diff --git a/.env.production b/.env.production index d25eb7dd4..e403f96b6 100644 --- a/.env.production +++ b/.env.production @@ -1 +1 @@ -NEXT_PUBLIC_GA_TRACKING_ID = 'UA-41298772-4' \ No newline at end of file +NEXT_PUBLIC_GA_TRACKING_ID = 'G-B1E83PJ3RT' \ No newline at end of file diff --git a/package.json b/package.json index 5ff6adbab..b5e07d70a 100644 --- a/package.json +++ b/package.json @@ -30,13 +30,12 @@ "classnames": "^2.2.6", "date-fns": "^2.16.1", "debounce": "^1.2.1", - "ga-lite": "^2.1.4", "github-slugger": "^1.3.0", "next": "^13.4.1", "next-remote-watch": "^1.0.0", "parse-numeric-range": "^1.2.0", "react": "^0.0.0-experimental-16d053d59-20230506", - "react-collapsed": "npm:@gaearon/react-collapsed@3.1.0-forked.1", + "react-collapsed": "4.0.4", "react-dom": "^0.0.0-experimental-16d053d59-20230506", "remark-frontmatter": "^4.0.1", "remark-gfm": "^3.0.1" diff --git a/public/images/docs/diagrams/conditional_render_tree.dark.png b/public/images/docs/diagrams/conditional_render_tree.dark.png new file mode 100644 index 000000000..5189a44c8 Binary files /dev/null and b/public/images/docs/diagrams/conditional_render_tree.dark.png differ diff --git a/public/images/docs/diagrams/conditional_render_tree.png b/public/images/docs/diagrams/conditional_render_tree.png new file mode 100644 index 000000000..c76e8cb63 Binary files /dev/null and b/public/images/docs/diagrams/conditional_render_tree.png differ diff --git a/public/images/docs/diagrams/generic_dependency_tree.dark.png b/public/images/docs/diagrams/generic_dependency_tree.dark.png new file mode 100644 index 000000000..64694f585 Binary files /dev/null and b/public/images/docs/diagrams/generic_dependency_tree.dark.png differ diff --git a/public/images/docs/diagrams/generic_dependency_tree.png b/public/images/docs/diagrams/generic_dependency_tree.png new file mode 100644 index 000000000..8ab6f1a34 Binary files /dev/null and b/public/images/docs/diagrams/generic_dependency_tree.png differ diff --git a/public/images/docs/diagrams/generic_render_tree.dark.png b/public/images/docs/diagrams/generic_render_tree.dark.png new file mode 100644 index 000000000..859fdaa96 Binary files /dev/null and b/public/images/docs/diagrams/generic_render_tree.dark.png differ diff --git a/public/images/docs/diagrams/generic_render_tree.png b/public/images/docs/diagrams/generic_render_tree.png new file mode 100644 index 000000000..952cf5faa Binary files /dev/null and b/public/images/docs/diagrams/generic_render_tree.png differ diff --git a/public/images/docs/diagrams/module_dependency_tree.dark.png b/public/images/docs/diagrams/module_dependency_tree.dark.png new file mode 100644 index 000000000..e8a85f7c0 Binary files /dev/null and b/public/images/docs/diagrams/module_dependency_tree.dark.png differ diff --git a/public/images/docs/diagrams/module_dependency_tree.png b/public/images/docs/diagrams/module_dependency_tree.png new file mode 100644 index 000000000..0dcaaa7aa Binary files /dev/null and b/public/images/docs/diagrams/module_dependency_tree.png differ diff --git a/public/images/docs/diagrams/render_tree.dark.png b/public/images/docs/diagrams/render_tree.dark.png new file mode 100644 index 000000000..117d7ff3e Binary files /dev/null and b/public/images/docs/diagrams/render_tree.dark.png differ diff --git a/public/images/docs/diagrams/render_tree.png b/public/images/docs/diagrams/render_tree.png new file mode 100644 index 000000000..1ea750bb0 Binary files /dev/null and b/public/images/docs/diagrams/render_tree.png differ diff --git a/public/images/docs/diagrams/use_client_module_dependency.dark.png b/public/images/docs/diagrams/use_client_module_dependency.dark.png new file mode 100644 index 000000000..c50e7308b Binary files /dev/null and b/public/images/docs/diagrams/use_client_module_dependency.dark.png differ diff --git a/public/images/docs/diagrams/use_client_module_dependency.png b/public/images/docs/diagrams/use_client_module_dependency.png new file mode 100644 index 000000000..d535246f7 Binary files /dev/null and b/public/images/docs/diagrams/use_client_module_dependency.png differ diff --git a/public/images/docs/diagrams/use_client_render_tree.dark.png b/public/images/docs/diagrams/use_client_render_tree.dark.png new file mode 100644 index 000000000..8d3e6a484 Binary files /dev/null and b/public/images/docs/diagrams/use_client_render_tree.dark.png differ diff --git a/public/images/docs/diagrams/use_client_render_tree.png b/public/images/docs/diagrams/use_client_render_tree.png new file mode 100644 index 000000000..ad3840681 Binary files /dev/null and b/public/images/docs/diagrams/use_client_render_tree.png differ diff --git a/src/components/Layout/Feedback.tsx b/src/components/Layout/Feedback.tsx index d984ef584..6da7b5dd1 100644 --- a/src/components/Layout/Feedback.tsx +++ b/src/components/Layout/Feedback.tsx @@ -4,7 +4,6 @@ import {useState} from 'react'; import {useRouter} from 'next/router'; -import {ga} from '../../utils/analytics'; export function Feedback({onSubmit = () => {}}: {onSubmit?: () => void}) { const {asPath} = useRouter(); @@ -46,16 +45,16 @@ const thumbsDownIcon = ( ); function sendGAEvent(isPositive: boolean) { + const category = isPositive ? 'like_button' : 'dislike_button'; + const value = isPositive ? 1 : 0; // Fragile. Don't change unless you've tested the network payload // and verified that the right events actually show up in GA. - ga( - 'send', - 'event', - 'button', - 'feedback', - window.location.pathname, - isPositive ? '1' : '0' - ); + // @ts-ignore + gtag('event', 'feedback', { + event_category: category, + event_label: window.location.pathname, + event_value: value, + }); } function SendFeedback({onSubmit}: {onSubmit: () => void}) { diff --git a/src/components/Layout/Page.tsx b/src/components/Layout/Page.tsx index 5c692a050..fa123d9f6 100644 --- a/src/components/Layout/Page.tsx +++ b/src/components/Layout/Page.tsx @@ -28,7 +28,12 @@ interface PageProps { children: React.ReactNode; toc: Array; routeTree: RouteItem; - meta: {title?: string; canary?: boolean; description?: string}; + meta: { + title?: string; + titleForTitleTag?: string; + canary?: boolean; + description?: string; + }; section: 'learn' | 'reference' | 'community' | 'blog' | 'home' | 'unknown'; } @@ -107,6 +112,7 @@ export function Page({children, toc, routeTree, meta, section}: PageProps) { <> )} diff --git a/src/components/Layout/Sidebar/SidebarRouteTree.tsx b/src/components/Layout/Sidebar/SidebarRouteTree.tsx index 9a0dd23f5..a9fa575b5 100644 --- a/src/components/Layout/Sidebar/SidebarRouteTree.tsx +++ b/src/components/Layout/Sidebar/SidebarRouteTree.tsx @@ -7,7 +7,7 @@ import {useRef, useLayoutEffect, Fragment} from 'react'; import cn from 'classnames'; import {useRouter} from 'next/router'; import {SidebarLink} from './SidebarLink'; -import useCollapse from 'react-collapsed'; +import {useCollapse} from 'react-collapsed'; import usePendingRoute from 'hooks/usePendingRoute'; import type {RouteItem} from 'components/Layout/getRouteMeta'; diff --git a/src/components/Layout/getRouteMeta.tsx b/src/components/Layout/getRouteMeta.tsx index d22947847..3564dd738 100644 --- a/src/components/Layout/getRouteMeta.tsx +++ b/src/components/Layout/getRouteMeta.tsx @@ -58,13 +58,13 @@ export interface RouteMeta { order?: number; } -type TravesalContext = RouteMeta & { +type TraversalContext = RouteMeta & { currentIndex: number; }; export function getRouteMeta(cleanedPath: string, routeTree: RouteItem) { const breadcrumbs = getBreadcrumbs(cleanedPath, routeTree); - const ctx: TravesalContext = { + const ctx: TraversalContext = { currentIndex: 0, }; buildRouteMeta(cleanedPath, routeTree, ctx); @@ -79,7 +79,7 @@ export function getRouteMeta(cleanedPath: string, routeTree: RouteItem) { function buildRouteMeta( searchPath: string, currentRoute: RouteItem, - ctx: TravesalContext + ctx: TraversalContext ) { ctx.currentIndex++; diff --git a/src/components/MDX/MDXComponents.tsx b/src/components/MDX/MDXComponents.tsx index 535edc17e..63bb80294 100644 --- a/src/components/MDX/MDXComponents.tsx +++ b/src/components/MDX/MDXComponents.tsx @@ -243,7 +243,7 @@ function Illustration({ src={src} alt={alt} style={{maxHeight: 300}} - className="bg-white rounded-lg" + className="rounded-lg" /> {caption ? (
@@ -275,7 +275,12 @@ function IllustrationBlock({ const images = imageInfos.map((info, index) => (
- {info.alt} + {info.alt}
{info.caption ? (
diff --git a/src/components/MDX/Sandpack/Preview.tsx b/src/components/MDX/Sandpack/Preview.tsx index 8d83d9867..059645550 100644 --- a/src/components/MDX/Sandpack/Preview.tsx +++ b/src/components/MDX/Sandpack/Preview.tsx @@ -52,6 +52,12 @@ export function Preview({ rawError = null; } + // When throwing a new Error in Sandpack - we want to disable the dev error dialog + // to show the Error Boundary fallback + if (rawError && rawError.message.includes(`throw Error('Example error')`)) { + rawError = null; + } + // Memoized because it's fed to debouncing. const firstLintError = useMemo(() => { if (lintErrors.length === 0) { diff --git a/src/components/PageHeading.tsx b/src/components/PageHeading.tsx index 076a38be9..659295d0a 100644 --- a/src/components/PageHeading.tsx +++ b/src/components/PageHeading.tsx @@ -34,7 +34,7 @@ function PageHeading({ {title} {canary && ( )} diff --git a/src/components/Seo.tsx b/src/components/Seo.tsx index d0dcaab75..5af169e13 100644 --- a/src/components/Seo.tsx +++ b/src/components/Seo.tsx @@ -9,6 +9,7 @@ import {siteConfig} from '../siteConfig'; export interface SeoProps { title: string; + titleForTitleTag: undefined | string; description?: string; image?: string; // jsonld?: JsonLDType | Array; @@ -22,6 +23,7 @@ const deployedTranslations = [ 'zh-hans', 'es', 'fr', + 'ja', // We'll add more languages when they have enough content. // Please DO NOT edit this list without a discussion in the reactjs/react.dev repo. // It must be the same between all translations. @@ -35,7 +37,7 @@ function getDomain(languageCode: string): string { export const Seo = withRouter( ({ title, - description = 'The library for web and native user interfaces', + titleForTitleTag, image = '/images/og-default.png', router, children, @@ -46,14 +48,20 @@ export const Seo = withRouter( const canonicalUrl = `https://${siteDomain}${ router.asPath.split(/[\?\#]/)[0] }`; - const pageTitle = isHomePage ? title : title + ' – React'; + // Allow setting a different title for Google results + const pageTitle = + (titleForTitleTag ?? title) + (isHomePage ? '' : ' – React'); // Twitter's meta parser is not very good. const twitterTitle = pageTitle.replace(/[<>]/g, ''); + let description = isHomePage + ? 'React is the library for web and native user interfaces. Build user interfaces out of individual pieces called components written in JavaScript. React is designed to let you seamlessly combine components written by independent people, teams, and organizations.' + : 'The library for web and native user interfaces'; return ( {title != null && {pageTitle}} - {description != null && ( + {isHomePage && ( + // Let Google figure out a good description for each page. )} diff --git a/src/content/blog/2022/03/08/react-18-upgrade-guide.md b/src/content/blog/2022/03/08/react-18-upgrade-guide.md index 29ba0b71d..66da896ec 100644 --- a/src/content/blog/2022/03/08/react-18-upgrade-guide.md +++ b/src/content/blog/2022/03/08/react-18-upgrade-guide.md @@ -224,8 +224,8 @@ For more information, see the [Automatic batching deep dive](https://github.com/ In the React 18 Working Group we worked with library maintainers to create new APIs needed to support concurrent rendering for use cases specific to their use case in areas like styles, and external stores. To support React 18, some libraries may need to switch to one of the following APIs: -* `useSyncExternalStore` is a new hook that allows external stores to support concurrent reads by forcing updates to the store to be synchronous. This new API is recommended for any library that integrates with state external to React. For more information, see the [useSyncExternalStore overview post](https://github.com/reactwg/react-18/discussions/70) and [useSyncExternalStore API details](https://github.com/reactwg/react-18/discussions/86). -* `useInsertionEffect` is a new hook that allows CSS-in-JS libraries to address performance issues of injecting styles in render. Unless you've already built a CSS-in-JS library we don't expect you to ever use this. This hook will run after the DOM is mutated, but before layout effects read the new layout. This solves an issue that already exists in React 17 and below, but is even more important in React 18 because React yields to the browser during concurrent rendering, giving it a chance to recalculate layout. For more information, see the [Library Upgrade Guide for `