+        {/* @ts-ignore: the OpenInCodeSandboxButton type from '@codesandbox/sandpack-react/unstyled' is incompatible with JSX in React 19 */}
         
         
           
diff --git a/src/components/MDX/Sandpack/NavigationBar.tsx b/src/components/MDX/Sandpack/NavigationBar.tsx
index 26ed5783d..bf2c3186c 100644
--- a/src/components/MDX/Sandpack/NavigationBar.tsx
+++ b/src/components/MDX/Sandpack/NavigationBar.tsx
@@ -115,7 +115,10 @@ export function NavigationBar({providedFiles}: {providedFiles: Array
}) {
 
   return (
     
+      {/* If Prettier reformats this block, the two @ts-ignore directives will no longer be adjacent to the problematic lines, causing TypeScript errors */}
+      {/* prettier-ignore */}
       
+        {/* @ts-ignore: the Listbox type from '@headlessui/react' is incompatible with JSX in React 19 */}
         
           
             
@@ -129,8 +132,10 @@ export function NavigationBar({providedFiles}: {providedFiles: Array}) {
                   'w-[fit-content]',
                   showDropdown ? 'invisible' : ''
                 )}>
+                {/* @ts-ignore: the FileTabs type from '@codesandbox/sandpack-react/unstyled' is incompatible with JSX in React 19 */}
                 
               
+              {/* @ts-ignore: the Listbox type from '@headlessui/react' is incompatible with JSX in React 19 */}
               
                 {({open}) => (
                   // If tabs don't fit, display the dropdown instead.
@@ -160,10 +165,10 @@ export function NavigationBar({providedFiles}: {providedFiles: Array}) {
               
              
           
-          {isMultiFile && showDropdown && (
-            
-              {visibleFiles.map((filePath: string) => (
-                
+          {/* @ts-ignore: the Listbox type from '@headlessui/react' is incompatible with JSX in React 19 */}
+          {isMultiFile && showDropdown && (
+              {/* @ts-ignore: the Listbox type from '@headlessui/react' is incompatible with JSX in React 19 */}
+              {visibleFiles.map((filePath: string) => (
                   {({active}) => (
                      {
       ) {
         return result;
       }
-      const {props} = codeSnippet.props.children;
+      const {props} = (
+        codeSnippet.props as PropsWithChildren<{
+          children: ReactElement<
+            HTMLAttributes & {meta?: string}
+          >;
+        }>
+      ).children;
       let filePath; // path in the folder structure
       let fileHidden = false; // if the file is available as a tab
       let fileActive = false; // if the file tab is shown by default
diff --git a/src/components/MDX/Sandpack/template.ts b/src/components/MDX/Sandpack/template.ts
index d05a1ff4c..2702cddfc 100644
--- a/src/components/MDX/Sandpack/template.ts
+++ b/src/components/MDX/Sandpack/template.ts
@@ -1,7 +1,7 @@
 export const template = {
   '/src/index.js': {
     hidden: true,
-    code: `import React, { StrictMode } from "react";
+    code: `import { StrictMode } from "react";
 import { createRoot } from "react-dom/client";
 import "./styles.css";
 
@@ -28,8 +28,8 @@ root.render(
           eject: 'react-scripts eject',
         },
         dependencies: {
-          react: '^18.0.0',
-          'react-dom': '^18.0.0',
+          react: '^19.1.0',
+          'react-dom': '^19.1.0',
           'react-scripts': '^5.0.0',
         },
       },
diff --git a/src/components/MDX/TeamMember.tsx b/src/components/MDX/TeamMember.tsx
index e1b9198d8..2c2fffa73 100644
--- a/src/components/MDX/TeamMember.tsx
+++ b/src/components/MDX/TeamMember.tsx
@@ -3,7 +3,7 @@
  */
 
 import * as React from 'react';
-import Image from 'next/image';
+import Image from 'next/legacy/image';
 import {IconTwitter} from '../Icon/IconTwitter';
 import {IconThreads} from '../Icon/IconThreads';
 import {IconBsky} from '../Icon/IconBsky';
@@ -39,11 +39,9 @@ export function TeamMember({
   personal,
 }: TeamMemberProps) {
   if (name == null || title == null || permalink == null || children == null) {
+    const identifier = name ?? title ?? permalink ?? 'unknown';
     throw new Error(
-      'Expected name, title, permalink, and children for ' + name ??
-        title ??
-        permalink ??
-        'unknown'
+      `Expected name, title, permalink, and children for ${identifier}`
     );
   }
   return (
diff --git a/src/components/MDX/TerminalBlock.tsx b/src/components/MDX/TerminalBlock.tsx
index fc13af338..475292716 100644
--- a/src/components/MDX/TerminalBlock.tsx
+++ b/src/components/MDX/TerminalBlock.tsx
@@ -31,9 +31,11 @@ function TerminalBlock({level = 'info', children}: TerminalBlockProps) {
     message = children;
   } else if (
     isValidElement(children) &&
-    typeof children.props.children === 'string'
+    typeof (children as React.ReactElement<{children: string}>).props
+      .children === 'string'
   ) {
-    message = children.props.children;
+    message = (children as React.ReactElement<{children: string}>).props
+      .children;
   } else {
     throw Error('Expected TerminalBlock children to be a plain string.');
   }
@@ -71,7 +73,7 @@ function TerminalBlock({level = 'info', children}: TerminalBlockProps) {
         
         
diff --git a/src/components/PageHeading.tsx b/src/components/PageHeading.tsx
index 6000c8e51..3f15afe95 100644
--- a/src/components/PageHeading.tsx
+++ b/src/components/PageHeading.tsx
@@ -8,10 +8,12 @@ import {H1} from './MDX/Heading';
 import type {RouteTag, RouteItem} from './Layout/getRouteMeta';
 import * as React from 'react';
 import {IconCanary} from './Icon/IconCanary';
+import {IconExperimental} from './Icon/IconExperimental';
 
 interface PageHeadingProps {
   title: string;
-  canary?: boolean;
+  version?: 'experimental' | 'canary';
+  experimental?: boolean;
   status?: string;
   description?: string;
   tags?: RouteTag[];
@@ -21,7 +23,7 @@ interface PageHeadingProps {
 function PageHeading({
   title,
   status,
-  canary,
+  version,
   tags = [],
   breadcrumbs,
 }: PageHeadingProps) {
@@ -31,9 +33,15 @@ function PageHeading({
         {breadcrumbs ? 
 : null}
         
           {title}
-          {canary && (
+          {version === 'canary' && (
             
+          )}
+          {version === 'experimental' && (
+            
           )}
diff --git a/src/components/Search.tsx b/src/components/Search.tsx
index f5c963f67..c7401487b 100644
--- a/src/components/Search.tsx
+++ b/src/components/Search.tsx
@@ -9,6 +9,8 @@ import {lazy, useEffect} from 'react';
 import * as React from 'react';
 import {createPortal} from 'react-dom';
 import {siteConfig} from 'siteConfig';
+import type {ComponentType, PropsWithChildren} from 'react';
+import type {DocSearchModalProps} from '@docsearch/react/modal';
 
 export interface SearchProps {
   appId?: string;
@@ -83,9 +85,10 @@ const options = {
 };
 
 const DocSearchModal: any = lazy(() =>
-  // @ts-ignore
   import('@docsearch/react/modal').then((mod) => ({
-    default: mod.DocSearchModal,
+    default: mod.DocSearchModal as ComponentType<
+      PropsWithChildren
+    >,
   }))
 );
 
diff --git a/src/components/Seo.tsx b/src/components/Seo.tsx
index 628085744..b8a8394b6 100644
--- a/src/components/Seo.tsx
+++ b/src/components/Seo.tsx
@@ -124,7 +124,14 @@ export const Seo = withRouter(
         )}
         
+        >>>>>> e07ac94bc2c1ffd817b13930977be93325e5bea9
 
 ---
 
diff --git a/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md b/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md
index fee21f4ec..9ec330e6b 100644
--- a/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md
+++ b/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md
@@ -5,7 +5,7 @@ date: 2024/02/15
 description: In React Labs posts, we write about projects in active research and development. Weāve made significant progress since our last update, and weād like to share our progress.
 ---
 
-February 15, 2024 by [Joseph Savona](https://twitter.com/en_JS), [Ricky Hanlon](https://twitter.com/rickhanlonii), [Andrew Clark](https://twitter.com/acdlite), [Matt Carroll](https://twitter.com/mattcarrollcode), and [Dan Abramov](https://twitter.com/dan_abramov).
+February 15, 2024 by [Joseph Savona](https://twitter.com/en_JS), [Ricky Hanlon](https://twitter.com/rickhanlonii), [Andrew Clark](https://twitter.com/acdlite), [Matt Carroll](https://twitter.com/mattcarrollcode), and [Dan Abramov](https://bsky.app/profile/danabra.mov).
 
 ---
 
@@ -107,7 +107,7 @@ Activity is still under research and our remaining work is to finalize the primi
 
 In addition to this update, our team has presented at conferences and made appearances on podcasts to speak more on our work and answer questions.
 
-- [Sathya Gunasekaran](/community/team#sathya-gunasekaran) spoke about the React Compiler at the [React India](https://www.youtube.com/watch?v=kjOacmVsLSE) conference
+- [Sathya Gunasekaran](https://github.com/gsathya) spoke about the React Compiler at the [React India](https://www.youtube.com/watch?v=kjOacmVsLSE) conference
 
 - [Dan Abramov](/community/team#dan-abramov) gave a talk at [RemixConf](https://www.youtube.com/watch?v=zMf_xeGPn6s) titled āReact from Another Dimensionā which explores an alternative history of how React Server Components and Actions could have been created
 
diff --git a/src/content/blog/2024/04/25/react-19-upgrade-guide.md b/src/content/blog/2024/04/25/react-19-upgrade-guide.md
index e6d76ec7b..cb83a6176 100644
--- a/src/content/blog/2024/04/25/react-19-upgrade-guide.md
+++ b/src/content/blog/2024/04/25/react-19-upgrade-guide.md
@@ -1,5 +1,5 @@
 ---
-title: "React 19 RC Upgrade Guide"
+title: "React 19 Upgrade Guide"
 author: Ricky Hanlon
 date: 2024/04/25
 description: The improvements added to React 19 require some breaking changes, but we've worked to make the upgrade as smooth as possible and we don't expect the changes to impact most apps. In this post, we will guide you through the steps for upgrading apps and libraries to React 19.
@@ -12,7 +12,7 @@ April 25, 2024 by [Ricky Hanlon](https://twitter.com/rickhanlonii)
 
 
 
-The improvements added to React 19 RC require some breaking changes, but we've worked to make the upgrade as smooth as possible, and we don't expect the changes to impact most apps.
+The improvements added to React 19 require some breaking changes, but we've worked to make the upgrade as smooth as possible, and we don't expect the changes to impact most apps.
 
 
 
@@ -24,7 +24,7 @@ To help make the upgrade to React 19 easier, we've published a `react@18.3` rele
 
 We recommend upgrading to React 18.3 first to help identify any issues before upgrading to React 19.
 
-For a list of changes in 18.3 see the [Release Notes](https://github.com/facebook/react/blob/main/CHANGELOG.md).
+For a list of changes in 18.3 see the [Release Notes](https://github.com/facebook/react/blob/main/CHANGELOG.md#1830-april-25-2024).
 
 
 
@@ -38,7 +38,7 @@ In this post, we will guide you through the steps for upgrading to React 19:
 - [TypeScript changes](#typescript-changes)
 - [Changelog](#changelog)
 
-If you'd like to help us test React 19, follow the steps in this upgrade guide and [report any issues](https://github.com/facebook/react/issues/new?assignees=&labels=React+19&projects=&template=19.md&title=%5BReact+19%5D) you encounter. For a list of new features added to React 19, see the [React 19 release post](/blog/2024/04/25/react-19).
+If you'd like to help us test React 19, follow the steps in this upgrade guide and [report any issues](https://github.com/facebook/react/issues/new?assignees=&labels=React+19&projects=&template=19.md&title=%5BReact+19%5D) you encounter. For a list of new features added to React 19, see the [React 19 release post](/blog/2024/12/05/react-19).
 
 ---
 ## Installing {/*installing*/}
@@ -70,28 +70,23 @@ We expect most apps will not be affected since the transform is enabled in most
 To install the latest version of React and React DOM:
 
 ```bash
-npm install --save-exact react@rc react-dom@rc
+npm install --save-exact react@^19.0.0 react-dom@^19.0.0
 ```
 
 Or, if you're using Yarn:
 
 ```bash
-yarn add --exact react@rc react-dom@rc
+yarn add --exact react@^19.0.0 react-dom@^19.0.0
 ```
 
-If you're using TypeScript, you also need to update the types. Once React 19 is released as stable, you can install the types as usual from `@types/react` and `@types/react-dom`.  Until the stable release, the types are available in different packages which need to be enforced in your `package.json`:
+If you're using TypeScript, you also need to update the types.
+```bash
+npm install --save-exact @types/react@^19.0.0 @types/react-dom@^19.0.0
+```
 
-```json
-{
-  "dependencies": {
-    "@types/react": "npm:types-react@rc",
-    "@types/react-dom": "npm:types-react-dom@rc"
-  },
-  "overrides": {
-    "@types/react": "npm:types-react@rc",
-    "@types/react-dom": "npm:types-react-dom@rc"
-  }
-}
+Or, if you're using Yarn:
+```bash
+yarn add --exact @types/react@^19.0.0 @types/react-dom@^19.0.0
 ```
 
 We're also including a codemod for the most common replacements. See [TypeScript changes](#typescript-changes) below.
@@ -118,7 +113,7 @@ This will run the following codemods from `react-codemod`:
 - [`replace-string-ref`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-string-ref)
 - [`replace-act-import`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-act-import)
 - [`replace-use-form-state`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-use-form-state) 
-- [`prop-types-typescript`](TODO)
+- [`prop-types-typescript`](https://github.com/reactjs/react-codemod#react-proptypes-to-prop-types)
 
 This does not include the TypeScript changes. See [TypeScript changes](#typescript-changes) below.
 
@@ -735,12 +730,12 @@ const reducer = (state: State, action: Action) => state;
 
 ### Other breaking changes {/*other-breaking-changes*/}
 
-- **react-dom**: Error for javascript URLs in src/href [#26507](https://github.com/facebook/react/pull/26507)
+- **react-dom**: Error for javascript URLs in `src` and `href` [#26507](https://github.com/facebook/react/pull/26507)
 - **react-dom**: Remove `errorInfo.digest` from `onRecoverableError` [#28222](https://github.com/facebook/react/pull/28222)
 - **react-dom**: Remove `unstable_flushControlled` [#26397](https://github.com/facebook/react/pull/26397)
 - **react-dom**: Remove `unstable_createEventHandle` [#28271](https://github.com/facebook/react/pull/28271)
 - **react-dom**: Remove `unstable_renderSubtreeIntoContainer` [#28271](https://github.com/facebook/react/pull/28271)
-- **react-dom**: Remove `unstable_runWithPrioirty` [#28271](https://github.com/facebook/react/pull/28271)
+- **react-dom**: Remove `unstable_runWithPriority` [#28271](https://github.com/facebook/react/pull/28271)
 - **react-is**: Remove deprecated methods from `react-is` [28224](https://github.com/facebook/react/pull/28224)
 
 ### Other notable changes {/*other-notable-changes*/}
@@ -752,7 +747,7 @@ const reducer = (state: State, action: Action) => state;
 - **react-dom**: Remove layout effect warning during SSR [#26395](https://github.com/facebook/react/pull/26395)
 - **react-dom**: Warn and donāt set empty string for src/href (except anchor tags) [#28124](https://github.com/facebook/react/pull/28124)
 
-We'll publish the full changelog with the stable release of React 19.
+For a full list of changes, please see the [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md#1900-december-5-2024).
 
 ---
 
diff --git a/src/content/blog/2024/05/22/react-conf-2024-recap.md b/src/content/blog/2024/05/22/react-conf-2024-recap.md
index 96417fd8b..7cb7d42ee 100644
--- a/src/content/blog/2024/05/22/react-conf-2024-recap.md
+++ b/src/content/blog/2024/05/22/react-conf-2024-recap.md
@@ -17,7 +17,7 @@ Last week we hosted React Conf 2024, a two-day conference in Henderson, Nevada w
 
 ---
 
-At React Conf 2024, we announced the [React 19 RC](/blog/2024/04/25/react-19), the [React Native New Architecture Beta](https://github.com/reactwg/react-native-new-architecture/discussions/189), and an experimental release of the [React Compiler](/learn/react-compiler). The community also took the stage to announce [React Router v7](https://remix.run/blog/merging-remix-and-react-router), [Universal Server Components](https://www.youtube.com/watch?v=T8TZQ6k4SLE&t=20765s) in Expo Router, React Server Components in [RedwoodJS](https://redwoodjs.com/blog/rsc-now-in-redwoodjs), and much more.
+At React Conf 2024, we announced the [React 19 RC](/blog/2024/12/05/react-19), the [React Native New Architecture Beta](https://github.com/reactwg/react-native-new-architecture/discussions/189), and an experimental release of the [React Compiler](/learn/react-compiler). The community also took the stage to announce [React Router v7](https://remix.run/blog/merging-remix-and-react-router), [Universal Server Components](https://www.youtube.com/watch?v=T8TZQ6k4SLE&t=20765s) in Expo Router, React Server Components in [RedwoodJS](https://redwoodjs.com/blog/rsc-now-in-redwoodjs), and much more.
 
 The entire [day 1](https://www.youtube.com/watch?v=T8TZQ6k4SLE) and [day 2](https://www.youtube.com/watch?v=0ckOUBiuxVY) streams are available online. In this post, we'll summarize the talks and announcements from the event.
 
@@ -36,13 +36,13 @@ For more, check out these talks from the community later in the conference:
 - [RedwoodJS, now with React Server Components](https://www.youtube.com/watch?v=T8TZQ6k4SLE&t=26815s) by [Amy Dutton](https://twitter.com/selfteachme)
 - [Introducing Universal React Server Components in Expo Router](https://www.youtube.com/watch?v=T8TZQ6k4SLE&t=20765s) by [Evan Bacon](https://twitter.com/Baconbrix)
 
-Next in the keynote, [Josh Story](https://twitter.com/joshcstory) and [Andrew Clark](https://twitter.com/acdlite) shared new features coming in React 19, and announced the React 19 RC which is ready for testing in production. Check out all the features in the [React 19 release post](/blog/2024/04/25/react-19), and see these talks for deep dives on the new features:
+Next in the keynote, [Josh Story](https://twitter.com/joshcstory) and [Andrew Clark](https://twitter.com/acdlite) shared new features coming in React 19, and announced the React 19 RC which is ready for testing in production. Check out all the features in the [React 19 release post](/blog/2024/12/05/react-19), and see these talks for deep dives on the new features:
 
 - [What's new in React 19](https://www.youtube.com/watch?v=T8TZQ6k4SLE&t=8880s) by [Lydia Hallie](https://twitter.com/lydiahallie)
 - [React Unpacked: A Roadmap to React 19](https://www.youtube.com/watch?v=T8TZQ6k4SLE&t=10112s) by [Sam Selikoff](https://twitter.com/samselikoff)
 - [React 19 Deep Dive: Coordinating HTML](https://www.youtube.com/watch?v=T8TZQ6k4SLE&t=24916s) by [Josh Story](https://twitter.com/joshcstory)
 - [Enhancing Forms with React Server Components](https://www.youtube.com/watch?v=0ckOUBiuxVY&t=25280s) by [Aurora Walberg Scharff](https://twitter.com/aurorascharff)
-- [React for Two Computers](https://www.youtube.com/watch?v=T8TZQ6k4SLE&t=18825s) by [Dan Abramov](https://twitter.com/dan_abramov2)
+- [React for Two Computers](https://www.youtube.com/watch?v=T8TZQ6k4SLE&t=18825s) by [Dan Abramov](https://bsky.app/profile/danabra.mov)
 - [And Now You Understand React Server Components](https://www.youtube.com/watch?v=0ckOUBiuxVY&t=11256s) by [Kent C. Dodds](https://twitter.com/kentcdodds)
 
 Finally, we ended the keynote with [Joe Savona](https://twitter.com/en_JS), [Sathya Gunasekaran](https://twitter.com/_gsathya), and [Mofei Zhang](https://twitter.com/zmofei) announcing that the React Compiler is now [Open Source](https://github.com/facebook/react/pull/29061), and sharing an experimental version of the React Compiler to try out.
diff --git a/src/content/blog/2024/10/21/react-compiler-beta-release.md b/src/content/blog/2024/10/21/react-compiler-beta-release.md
index ff45fa54d..b0a12b2cd 100644
--- a/src/content/blog/2024/10/21/react-compiler-beta-release.md
+++ b/src/content/blog/2024/10/21/react-compiler-beta-release.md
@@ -10,6 +10,17 @@ October 21, 2024 by [Lauren Tan](https://twitter.com/potetotes).
 
 ---
 
+<<<<<<< HEAD
+=======
+
+
+### React Compiler is now in RC! {/*react-compiler-is-now-in-rc*/}
+
+Please see the [RC blog post](/blog/2025/04/21/react-compiler-rc) for details.
+
+
+
+>>>>>>> e07ac94bc2c1ffd817b13930977be93325e5bea9
 
 
 The React team is excited to share new updates:
@@ -64,11 +75,19 @@ Or, if you're using Yarn:
 yarn add -D eslint-plugin-react-compiler@beta
 
 
+<<<<<<< HEAD
 After installation you can enable the linter by [adding it to your ESLint config](/learn/react-compiler#installing-eslint-plugin-react-compiler). Using the linter helps identify Rules of React breakages, making it easier to adopt the compiler when it's fully released.
 
 ## Backwards Compatibility {/*backwards-compatibility*/}
 
 React Compiler produces code that depends on runtime APIs added in React 19, but we've since added support for the compiler to also work with React 17 and 18. If you are not on React 19 yet, in the Beta release you can now try out React Compiler by specifying a minimum `target` in your compiler config, and adding `react-compiler-runtime` as a dependency. [You can find docs on this here](/learn/react-compiler#using-react-compiler-with-react-17-or-18).
+=======
+After installation you can enable the linter by [adding it to your ESLint config](/learn/react-compiler/installation#eslint-integration). Using the linter helps identify Rules of React breakages, making it easier to adopt the compiler when it's fully released.
+
+## Backwards Compatibility {/*backwards-compatibility*/}
+
+React Compiler produces code that depends on runtime APIs added in React 19, but we've since added support for the compiler to also work with React 17 and 18. If you are not on React 19 yet, in the Beta release you can now try out React Compiler by specifying a minimum `target` in your compiler config, and adding `react-compiler-runtime` as a dependency. [You can find docs on this here](/reference/react-compiler/configuration#react-17-18).
+>>>>>>> e07ac94bc2c1ffd817b13930977be93325e5bea9
 
 ## Using React Compiler in libraries {/*using-react-compiler-in-libraries*/}
 
@@ -78,7 +97,11 @@ React Compiler can also be used to compile libraries. Because React Compiler nee
 
 Because your code is pre-compiled, users of your library will not need to have the compiler enabled in order to benefit from the automatic memoization applied to your library. If your library targets apps not yet on React 19, specify a minimum `target` and add `react-compiler-runtime` as a direct dependency. The runtime package will use the correct implementation of APIs depending on the application's version, and polyfill the missing APIs if necessary.
 
+<<<<<<< HEAD
 [You can find more docs on this here.](/learn/react-compiler#using-the-compiler-on-libraries)
+=======
+[You can find more docs on this here.](/reference/react-compiler/compiling-libraries)
+>>>>>>> e07ac94bc2c1ffd817b13930977be93325e5bea9
 
 ## Opening up React Compiler Working Group to everyone {/*opening-up-react-compiler-working-group-to-everyone*/}
 
@@ -123,4 +146,8 @@ Thanks to [Sathya Gunasekaran](https://twitter.com/_gsathya), [Joe Savona](https
 
 [^2]: Thanks [Vaishali Garg](https://www.linkedin.com/in/vaishaligarg09) for leading this study on React Compiler at Meta, and for reviewing this post.
 
+<<<<<<< HEAD
+[^3]: After controlling on author tenure, diff length/complexity, and other potential confounding factors.
+=======
 [^3]: After controlling on author tenure, diff length/complexity, and other potential confounding factors.
+>>>>>>> e07ac94bc2c1ffd817b13930977be93325e5bea9
diff --git a/src/content/blog/2024/04/25/react-19.md b/src/content/blog/2024/12/05/react-19.md
similarity index 92%
rename from src/content/blog/2024/04/25/react-19.md
rename to src/content/blog/2024/12/05/react-19.md
index 1b19c3546..65bf42757 100644
--- a/src/content/blog/2024/04/25/react-19.md
+++ b/src/content/blog/2024/12/05/react-19.md
@@ -1,21 +1,33 @@
 ---
-title: "React 19 RC"
+title: "React v19"
 author: The React Team
-date: 2024/04/25
-description: React 19 RC is now available on npm! In this post, we'll give an overview of the new features in React 19, and how you can adopt them.
+date: 2024/12/05
+description: React 19 is now available on npm! In this post, we'll give an overview of the new features in React 19, and how you can adopt them.
 ---
 
-April 25, 2024 by [The React Team](/community/team)
+December 05, 2024 by [The React Team](/community/team)
 
 ---
+
+
+### React 19 is now stable! {/*react-19-is-now-stable*/}
+
+Additions since this post was originally shared with the React 19 RC in April:
+
+- **Pre-warming for suspended trees**: see [Improvements to Suspense](/blog/2024/04/25/react-19-upgrade-guide#improvements-to-suspense).
+- **React DOM static APIs**: see [New React DOM Static APIs](#new-react-dom-static-apis).
+
+_The date for this post has been updated to reflect the stable release date._
+
+
 
 
 
-React 19 RC is now available on npm!
+React v19 is now available on npm!
 
 
 
-In our [React 19 RC Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide), we shared step-by-step instructions for upgrading your app to React 19. In this post, we'll give an overview of the new features in React 19, and how you can adopt them.
+In our [React 19 Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide), we shared step-by-step instructions for upgrading your app to React 19. In this post, we'll give an overview of the new features in React 19, and how you can adopt them.
 
 - [What's new in React 19](#whats-new-in-react-19)
 - [Improvements in React 19](#improvements-in-react-19)
@@ -282,7 +294,7 @@ A component was suspended by an uncached promise. Creating promises inside a Cli
 
 
 
-To fix, you need to pass a promise from a suspense powered library or framework that supports caching for promises. In the future we plan to ship features to make it easier to cache promises in render.
+To fix, you need to pass a promise from a Suspense powered library or framework that supports caching for promises. In the future we plan to ship features to make it easier to cache promises in render.
 
 
 
@@ -312,6 +324,30 @@ The `use` API can only be called in render, similar to hooks. Unlike hooks, `use
 
 For more information, see the docs for [`use`](/reference/react/use).
 
+## New React DOM Static APIs {/*new-react-dom-static-apis*/}
+
+We've added two new APIs to `react-dom/static` for static site generation:
+- [`prerender`](/reference/react-dom/static/prerender)
+- [`prerenderToNodeStream`](/reference/react-dom/static/prerenderToNodeStream)
+
+These new APIs improve on `renderToString` by waiting for data to load for static HTML generation. They are designed to work with streaming environments like Node.js Streams and Web Streams. For example, in a Web Stream environment, you can prerender a React tree to static HTML with `prerender`: 
+
+```js
+import { prerender } from 'react-dom/static';
+
+async function handler(request) {
+  const {prelude} = await prerender(, {
+    bootstrapScripts: ['/main.js']
+  });
+  return new Response(prelude, {
+    headers: { 'content-type': 'text/html' },
+  });
+}
+```
+
+Prerender APIs will wait for all data to load before returning the static HTML stream. Streams can be converted to strings, or sent with a streaming response. They do not support streaming content as it loads, which is supported by the existing [React DOM server rendering APIs](/reference/react-dom/server).
+
+For more information, see [React DOM Static APIs](/reference/react-dom/static).
 
 ## React Server Components {/*react-server-components*/}
 
@@ -326,7 +362,7 @@ React 19 includes all of the React Server Components features included from the
 
 #### How do I build support for Server Components? {/*how-do-i-build-support-for-server-components*/}
 
-While React Server Components in React 19 are stable and will not break between major versions, the underlying APIs used to implement a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x. 
+While React Server Components in React 19 are stable and will not break between minor versions, the underlying APIs used to implement a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x. 
 
 To support React Server Components as a bundler or framework, we recommend pinning to a specific React version, or using the Canary release. We will continue working with bundlers and frameworks to stabilize the APIs used to implement React Server Components in the future.
 
@@ -374,7 +410,7 @@ New function components will no longer need `forwardRef`, and we will be publish
 
 
 
-`refs` passed to classes are not passed as props since they reference the component instance.
+`ref`s passed to classes are not passed as props since they reference the component instance.
 
 
 
@@ -771,5 +807,4 @@ Thanks to [Joey Arhar](https://github.com/josepharhar) for driving the design an
 #### How to upgrade {/*how-to-upgrade*/}
 See the [React 19 Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide) for step-by-step instructions and a full list of breaking and notable changes.
 
-
-
+_Note: this post was originally published 04/25/2024 and has been updated to 12/05/2024 with the stable release._
diff --git a/src/content/blog/2025/02/14/sunsetting-create-react-app.md b/src/content/blog/2025/02/14/sunsetting-create-react-app.md
new file mode 100644
index 000000000..9ced6231c
--- /dev/null
+++ b/src/content/blog/2025/02/14/sunsetting-create-react-app.md
@@ -0,0 +1,320 @@
+---
+title: "Sunsetting Create React App"
+author: Matt Carroll and Ricky Hanlon
+date: 2025/02/14
+description: Today, weāre deprecating Create React App for new apps, and encouraging existing apps to migrate to a framework, or to migrate to a build tool like Vite, Parcel, or RSBuild. Weāre also providing docs for when a framework isnāt a good fit for your project, you want to build your own framework, or you just want to learn how React works by building a React app from scratch.
+---
+
+February 14, 2025 by [Matt Carroll](https://twitter.com/mattcarrollcode) and [Ricky Hanlon](https://bsky.app/profile/ricky.fm)
+
+---
+
+
+
+Today, weāre deprecating [Create React App](https://create-react-app.dev/) for new apps, and encouraging existing apps to migrate to a [framework](#how-to-migrate-to-a-framework), or to [migrate to a build tool](#how-to-migrate-to-a-build-tool) like Vite, Parcel, or RSBuild. 
+
+Weāre also providing docs for when a framework isnāt a good fit for your project, you want to build your own framework, or you just want to learn how React works by [building a React app from scratch](/learn/build-a-react-app-from-scratch).
+
+
+
+-----
+
+When we released Create React App in 2016, there was no clear way to build a new React app.
+
+To create a React app, you had to install a bunch of tools and wire them up together yourself to support basic features like JSX, linting, and hot reloading. This was very tricky to do correctly, so the [community](https://github.com/react-boilerplate/react-boilerplate) [created](https://github.com/kriasoft/react-starter-kit) [boilerplates](https://github.com/petehunt/react-boilerplate) for [common](https://github.com/gaearon/react-hot-boilerplate) [setups](https://github.com/erikras/react-redux-universal-hot-example). However, boilerplates were difficult to update and fragmentation made it difficult for React to release new features.
+
+Create React App solved these problems by combining several tools into a single recommended configuration. This allowed apps a simple way to upgrade to new tooling features, and allowed the React team to deploy non-trivial tooling changes (Fast Refresh support, React Hooks lint rules) to the broadest possible audience.
+
+This model became so popular that there's an entire category of tools working this way today.
+
+## Deprecating Create React App {/*deprecating-create-react-app*/}
+
+Although Create React App makes it easy to get started, [there are several limitations](#limitations-of-build-tools) that make it difficult to build high performant production apps. In principle, we could solve these problems by essentially evolving it into a [framework](#why-we-recommend-frameworks).
+
+However, since Create React App currently has no active maintainers, and there are many existing frameworks that solve these problems already, weāve decided to deprecate Create React App.
+
+Starting today, if you install a new app, you will see a deprecation warning:
+
+
+
+
+create-react-app is deprecated.
+{'\n\n'}
+You can find a list of up-to-date React frameworks on react.dev
+For more info see: react.dev/link/cra
+{'\n\n'}
+This error message will only be shown once per install.
+
+
+
+
+We've also added a deprecation notice to the Create React App [website](https://create-react-app.dev/) and GitHub [repo](https://github.com/facebook/create-react-app). Create React App will continue working in maintenance mode, and we've published a new version of Create React App to work with React 19.
+
+## How to Migrate to a Framework {/*how-to-migrate-to-a-framework*/}
+We recommend [creating new React apps](/learn/creating-a-react-app) with a framework. All the frameworks we recommend support client-side rendering ([CSR](https://developer.mozilla.org/en-US/docs/Glossary/CSR)) and single-page apps ([SPA](https://developer.mozilla.org/en-US/docs/Glossary/SPA)), and can be deployed to a CDN or static hosting service without a server.
+
+For existing apps, these guides will help you migrate to a client-only SPA:
+
+* [Next.jsā Create React App migration guide](https://nextjs.org/docs/app/building-your-application/upgrading/from-create-react-app)
+* [React Routerās framework adoption guide](https://reactrouter.com/upgrading/component-routes).
+* [Expo webpack to Expo Router migration guide](https://docs.expo.dev/router/migrate/from-expo-webpack/)
+
+## How to Migrate to a Build Tool {/*how-to-migrate-to-a-build-tool*/}
+
+If your app has unusual constraints, or you prefer to solve these problems by building your own framework, or you just want to learn how react works from scratch, you can roll your own custom setup with React using Vite, Parcel or Rsbuild.
+
+For existing apps, these guides will help you migrate to a build tool:
+
+* [Vite Create React App migration guide](https://www.robinwieruch.de/vite-create-react-app/)
+* [Parcel Create React App migration guide](https://parceljs.org/migration/cra/)
+* [Rsbuild Create React App migration guide](https://rsbuild.dev/guide/migration/cra)
+
+To help get started with Vite, Parcel or Rsbuild, we've added new docs for [Building a React App from Scratch](/learn/build-a-react-app-from-scratch).
+
+
+
+#### Do I need a framework? {/*do-i-need-a-framework*/}
+
+Most apps would benefit from a framework, but there are valid cases to build a React app from scratch. A good rule of thumb is if your app needs routing, you would probably benefit from a framework. 
+
+Just like Svelte has Sveltekit, Vue has Nuxt, and Solid has SolidStart, [React recommends using a framework](#why-we-recommend-frameworks) that fully integrates routing into features like data-fetching and code-splitting out of the box. This avoids the pain of needing to write your own complex configurations and essentially build a framework yourself.
+
+However, you can always [build a React app from scratch](/learn/build-a-react-app-from-scratch) using a build tool like Vite, Parcel, or Rsbuild.
+
+
+
+Continue reading to learn more about the [limitations of build tools](#limitations-of-build-tools) and [why we recommend frameworks](#why-we-recommend-frameworks).
+
+## Limitations of Build Tools {/*limitations-of-build-tools*/}
+
+Create React App and build tools like it make it easy to get started building a React app. After running `npx create-react-app my-app`, you get a fully configured React app with a development server, linting, and a production build.
+
+For example, if you're building an internal admin tool, you can start with a landing page:
+
+```js
+export default function App() {
+  return (
+    
+      
Welcome to the Admin Tool!
+    
+  )
+}
+```
+
+This allows you to immediately start coding in React with features like JSX, default linting rules, and a bundler to run in both development and production. However, this setup is missing the tools you need to build a real production app.
+
+Most production apps need solutions to problems like routing, data fetching, and code splitting.
+
+### Routing {/*routing*/}
+
+Create React App does not include a specific routing solution. If you're just getting started, one option is to use `useState` to switch between routes. But doing this means that you can't share links to your app - every link would go to the same page - and structuring your app becomes difficult over time:
+
+```js
+import {useState} from 'react';
+
+import Home from './Home';
+import Dashboard from './Dashboard';
+
+export default function App() {
+  // ā Routing in state does not create URLs
+  const [route, setRoute] = useState('home');
+  return (
+    
+      {route === 'home' && }
+      {route === 'dashboard' && }
+    
+  )
+}
+```
+
+This is why most apps that use Create React App solve add routing with a routing library like [React Router](https://reactrouter.com/) or [Tanstack Router](https://tanstack.com/router/latest). With a routing library, you can add additional routes to the app, which provides opinions on the structure of your app, and allows you to start sharing links to routes. For example, with React Router you can define routes:
+
+```js
+import {RouterProvider, createBrowserRouter} from 'react-router';
+
+import Home from './Home';
+import Dashboard from './Dashboard';
+
+// ā
 Each route has it's own URL
+const router = createBrowserRouter([
+  {path: '/', element: },
+  {path: '/dashboard', element: }
+]);
+
+export default function App() {
+  return (
+    
+  )
+}
+```
+
+With this change, you can share a link to `/dashboard` and the app will navigate to the dashboard page . Once you have a routing library, you can add additional features like nested routes, route guards, and route transitions, which are difficult to implement without a routing library.
+
+There's a tradeoff being made here: the routing library adds complexity to the app, but it also adds features that are difficult to implement without it.
+
+### Data Fetching {/*data-fetching*/}
+
+Another common problem in Create React App is data fetching. Create React App does not include a specific data fetching solution. If you're just getting started, a common option is to use `fetch` in an effect to load data.
+
+But doing this means that the data is fetched after the component renders, which can cause network waterfalls. Network waterfalls are caused by fetching data when your app renders instead of in parallel while the code is downloading:
+
+```js
+export default function Dashboard() {
+  const [data, setData] = useState(null);
+
+  // ā Fetching data in a component causes network waterfalls
+  useEffect(() => {
+    fetch('/api/data')
+      .then(response => response.json())
+      .then(data => setData(data));
+  }, []);
+
+  return (
+    
+      {data.map(item => 
{item.name}
)}
+    
+      {loaderData.map(item => 
{item.name}
)}
+    
+  
+    - Accessibility+
- Asset loading+
- Authentication+
- Caching+
+  
+    - Error handling+
- Mutating data+
- Navigations+
- Optimistic updates+
+  
+    - Progressive enhancement+
- Server-side rendering+
- Static site generation+
- Streaming+
+
animate me
+
+```
+
+This new component lets you declaratively define "what" to animate when an animation is activated. 
+
+You can define "when" to animate by using one of these three triggers for a View Transition:
+
+```js
+// "when" to animate.
+
+// Transitions
+startTransition(() => setState(...));
+
+// Deferred Values
+const deferred = useDeferredValue(value);
+
+// Suspense
+}>
+  Loading...
+
+```
+
+By default, these animations use the [default CSS animations for View Transitions](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API/Using#customizing_your_animations) applied (typically a smooth cross-fade). You can use [view transition pseudo-selectors](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API/Using#the_view_transition_pseudo-element_tree) to define "how" the animation runs. For example, you can use `*` to change the default animation for all transitions:
+
+```
+// "how" to animate.
+::view-transition-old(*) {
+  animation: 300ms ease-out fade-out;
+}
+::view-transition-new(*) {
+  animation: 300ms ease-in fade-in;
+}
+```
+
+When the DOM updates due to an animation trigger—like `startTransition`, `useDeferredValue`, or a `Suspense` fallback switching to content—React will use [declarative heuristics](/reference/react/ViewTransition#viewtransition) to automatically determine which `` components to activate for the animation. The browser will then run the animation that's defined in CSS.
+
+If you're familiar with the browser's View Transition API and want to know how React supports it, check out [How does `` Work](/reference/react/ViewTransition#how-does-viewtransition-work) in the docs. 
+
+In this post, let's take a look at a few examples of how to use View Transitions. 
+
+We'll start with this app, which doesn't animate any of the following interactions:
+- Click a video to view the details.
+- Click "back" to go back to the feed.
+- Type in the list to filter the videos.
+
+
+
+```js src/App.js active
+import TalkDetails from './Details'; import Home from './Home'; import {useRouter} from './router';
+
+export default function App() {
+  const {url} = useRouter();
+
+  // š©This version doesn't include any animations yet
+  return url === '/' ?  : ;
+}
+```
+
+```js src/Details.js
+import { fetchVideo, fetchVideoDetails } from "./data";
+import { Thumbnail, VideoControls } from "./Videos";
+import { useRouter } from "./router";
+import Layout from "./Layout";
+import { use, Suspense } from "react";
+import { ChevronLeft } from "./Icons";
+
+function VideoInfo({ id }) {
+  const details = use(fetchVideoDetails(id));
+  return (
+    <>
+      {details.title}
+      {details.description}
+    >
+  );
+}
+
+function VideoInfoFallback() {
+  return (
+    <>
+      
+      
+    >
+  );
+}
+
+export default function Details() {
+  const { url, navigateBack } = useRouter();
+  const videoId = url.split("/").pop();
+  const video = use(fetchVideo(videoId));
+
+  return (
+     {
+            navigateBack("/");
+          }}
+        >
+           Back
+        
 
+      }
+    >
+      
+        
+          
+        
+        }>
+          
+        
+      
+    
+  );
+}
+
+```
+
+```js src/Home.js
+import { Video } from "./Videos";
+import Layout from "./Layout";
+import { fetchVideos } from "./data";
+import { useId, useState, use } from "react";
+import { IconSearch } from "./Icons";
+
+function SearchInput({ value, onChange }) {
+  const id = useId();
+  return (
+    
+  );
+}
+
+function filterVideos(videos, query) {
+  const keywords = query
+    .toLowerCase()
+    .split(" ")
+    .filter((s) => s !== "");
+  if (keywords.length === 0) {
+    return videos;
+  }
+  return videos.filter((video) => {
+    const words = (video.title + " " + video.description)
+      .toLowerCase()
+      .split(" ");
+    return keywords.every((kw) => words.some((w) => w.includes(kw)));
+  });
+}
+
+export default function Home() {
+  const videos = use(fetchVideos());
+  const count = videos.length;
+  const [searchText, setSearchText] = useState("");
+  const foundVideos = filterVideos(videos, searchText);
+  return (
+    
{count} Videos }>
+      
+      
+        {foundVideos.length === 0 && (
+          
No results
+        )}
+        
+          {foundVideos.map((video) => (
+            
+          ))}
+        
+      
+    
+  );
+}
+
+```
+
+```js src/Icons.js
+export function ChevronLeft() {
+  return (
+    
+  );
+}
+
+export function PauseIcon() {
+  return (
+    
+  );
+}
+
+export function PlayIcon() {
+  return (
+    
+  );
+}
+export function Heart({liked, animate}) {
+  return (
+    <>
+      
+
+      
+    >
+  );
+}
+
+export function IconSearch(props) {
+  return (
+    
+  );
+}
+```
+
+```js src/Layout.js
+import { useIsNavPending } from "./router";
+
+export default function Page({ heading, children }) {
+  const isPending = useIsNavPending();
+  return (
+    
+      
+        
+          {heading}
+          {isPending && }
+        
+      
+
+      
+    
+  );
+}
+```
+
+```js src/LikeButton.js
+import {useState} from 'react';
+import {Heart} from './Icons';
+
+// A hack since we don't actually have a backend.
+// Unlike local state, this survives videos being filtered.
+const likedVideos = new Set();
+
+export default function LikeButton({video}) {
+  const [isLiked, setIsLiked] = useState(() => likedVideos.has(video.id));
+  const [animate, setAnimate] = useState(false);
+  return (
+    
+  );
+}
+```
+
+```js src/Videos.js
+import { useState } from "react";
+import LikeButton from "./LikeButton";
+import { useRouter } from "./router";
+import { PauseIcon, PlayIcon } from "./Icons";
+import { startTransition } from "react";
+
+export function VideoControls() {
+  const [isPlaying, setIsPlaying] = useState(false);
+
+  return (
+    
+        startTransition(() => {
+          setIsPlaying((p) => !p);
+        })
+      }
+    >
+      {isPlaying ?  : }
+    
+  );
+}
+
+export function Thumbnail({ video, children }) {
+  return (
+    
+      {children}
+    
+  );
+}
+
+export function Video({ video }) {
+  const { navigate } = useRouter();
+
+  return (
+    
+      
 {
+          e.preventDefault();
+          navigate(`/video/${video.id}`);
+        }}
+      >
+        
+
+        
+          
{video.title}
+          
{video.description}
+        
+      
+      
+    
+  );
+}
+```
+
+
+```js src/data.js hidden
+const videos = [
+  {
+    id: '1',
+    title: 'First video',
+    description: 'Video description',
+    image: 'blue',
+  },
+  {
+    id: '2',
+    title: 'Second video',
+    description: 'Video description',
+    image: 'red',
+  },
+  {
+    id: '3',
+    title: 'Third video',
+    description: 'Video description',
+    image: 'green',
+  },
+  {
+    id: '4',
+    title: 'Fourth video',
+    description: 'Video description',
+    image: 'purple',
+  },
+  {
+    id: '5',
+    title: 'Fifth video',
+    description: 'Video description',
+    image: 'yellow',
+  },
+  {
+    id: '6',
+    title: 'Sixth video',
+    description: 'Video description',
+    image: 'gray',
+  },
+];
+
+let videosCache = new Map();
+let videoCache = new Map();
+let videoDetailsCache = new Map();
+const VIDEO_DELAY = 1;
+const VIDEO_DETAILS_DELAY = 1000;
+export function fetchVideos() {
+  if (videosCache.has(0)) {
+    return videosCache.get(0);
+  }
+  const promise = new Promise((resolve) => {
+    setTimeout(() => {
+      resolve(videos);
+    }, VIDEO_DELAY);
+  });
+  videosCache.set(0, promise);
+  return promise;
+}
+
+export function fetchVideo(id) {
+  if (videoCache.has(id)) {
+    return videoCache.get(id);
+  }
+  const promise = new Promise((resolve) => {
+    setTimeout(() => {
+      resolve(videos.find((video) => video.id === id));
+    }, VIDEO_DELAY);
+  });
+  videoCache.set(id, promise);
+  return promise;
+}
+
+export function fetchVideoDetails(id) {
+  if (videoDetailsCache.has(id)) {
+    return videoDetailsCache.get(id);
+  }
+  const promise = new Promise((resolve) => {
+    setTimeout(() => {
+      resolve(videos.find((video) => video.id === id));
+    }, VIDEO_DETAILS_DELAY);
+  });
+  videoDetailsCache.set(id, promise);
+  return promise;
+}
+```
+
+```js src/router.js
+import {
+  useState,
+  createContext,
+  use,
+  useTransition,
+  useLayoutEffect,
+  useEffect,
+} from "react";
+
+const RouterContext = createContext({ url: "/", params: {} });
+
+export function useRouter() {
+  return use(RouterContext);
+}
+
+export function useIsNavPending() {
+  return use(RouterContext).isPending;
+}
+
+export function Router({ children }) {
+  const [routerState, setRouterState] = useState({
+    pendingNav: () => {},
+    url: document.location.pathname,
+  });
+  const [isPending, startTransition] = useTransition();
+
+  function go(url) {
+    setRouterState({
+      url,
+      pendingNav() {
+        window.history.pushState({}, "", url);
+      },
+    });
+  }
+  function navigate(url) {
+    // Update router state in transition.
+    startTransition(() => {
+      go(url);
+    });
+  }
+
+  function navigateBack(url) {
+    // Update router state in transition.
+    startTransition(() => {
+      go(url);
+    });
+  }
+
+  useEffect(() => {
+    function handlePopState() {
+      // This should not animate because restoration has to be synchronous.
+      // Even though it's a transition.
+      startTransition(() => {
+        setRouterState({
+          url: document.location.pathname + document.location.search,
+          pendingNav() {
+            // Noop. URL has already updated.
+          },
+        });
+      });
+    }
+    window.addEventListener("popstate", handlePopState);
+    return () => {
+      window.removeEventListener("popstate", handlePopState);
+    };
+  }, []);
+  const pendingNav = routerState.pendingNav;
+  useLayoutEffect(() => {
+    pendingNav();
+  }, [pendingNav]);
+
+  return (
+    
+      {children}
+    
+  );
+}
+```
+
+```css src/styles.css
+@font-face {
+  font-family: Optimistic Text;
+  src: url(https://react.dev/fonts/Optimistic_Text_W_Rg.woff2) format("woff2");
+  font-weight: 400;
+  font-style: normal;
+  font-display: swap;
+}
+
+@font-face {
+  font-family: Optimistic Text;
+  src: url(https://react.dev/fonts/Optimistic_Text_W_Md.woff2) format("woff2");
+  font-weight: 500;
+  font-style: normal;
+  font-display: swap;
+}
+
+@font-face {
+  font-family: Optimistic Text;
+  src: url(https://react.dev/fonts/Optimistic_Text_W_Bd.woff2) format("woff2");
+  font-weight: 600;
+  font-style: normal;
+  font-display: swap;
+}
+
+@font-face {
+  font-family: Optimistic Text;
+  src: url(https://react.dev/fonts/Optimistic_Text_W_Bd.woff2) format("woff2");
+  font-weight: 700;
+  font-style: normal;
+  font-display: swap;
+}
+
+* {
+  box-sizing: border-box;
+}
+
+html {
+  background-image: url(https://react.dev/images/meta-gradient-dark.png);
+  background-size: 100%;
+  background-position: -100%;
+  background-color: rgb(64 71 86);
+  background-repeat: no-repeat;
+  height: 100%;
+  width: 100%;
+}
+
+body {
+  font-family: Optimistic Text, -apple-system, ui-sans-serif, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
+  padding: 10px 0 10px 0;
+  margin: 0;
+  display: flex;
+  justify-content: center;
+}
+
+#root {
+  flex: 1 1;
+  height: auto;
+  background-color: #fff;
+  border-radius: 10px;
+  max-width: 450px;
+  min-height: 600px;
+  padding-bottom: 10px;
+}
+
+h1 {
+  margin-top: 0;
+  font-size: 22px;
+}
+
+h2 {
+  margin-top: 0;
+  font-size: 20px;
+}
+
+h3 {
+  margin-top: 0;
+  font-size: 18px;
+}
+
+h4 {
+  margin-top: 0;
+  font-size: 16px;
+}
+
+h5 {
+  margin-top: 0;
+  font-size: 14px;
+}
+
+h6 {
+  margin-top: 0;
+  font-size: 12px;
+}
+
+code {
+  font-size: 1.2em;
+}
+
+ul {
+  padding-inline-start: 20px;
+}
+
+.sr-only {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip: rect(0, 0, 0, 0);
+  white-space: nowrap;
+  border-width: 0;
+}
+
+.absolute {
+  position: absolute;
+}
+
+.overflow-visible {
+  overflow: visible;
+}
+
+.visible {
+  overflow: visible;
+}
+
+.fit {
+  width: fit-content;
+}
+
+
+/* Layout */
+.page {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+}
+
+.top-hero {
+  height: 200px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background-image: conic-gradient(
+      from 90deg at -10% 100%,
+      #2b303b 0deg,
+      #2b303b 90deg,
+      #16181d 1turn
+  );
+}
+
+.bottom {
+  flex: 1;
+  overflow: auto;
+}
+
+.top-nav {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-bottom: 0;
+  padding: 0 12px;
+  top: 0;
+  width: 100%;
+  height: 44px;
+  color: #23272f;
+  font-weight: 700;
+  font-size: 20px;
+  z-index: 100;
+  cursor: default;
+}
+
+.content {
+  padding: 0 12px;
+  margin-top: 4px;
+}
+
+
+.loader {
+  color: #23272f;
+  font-size: 3px;
+  width: 1em;
+  margin-right: 18px;
+  height: 1em;
+  border-radius: 50%;
+  position: relative;
+  text-indent: -9999em;
+  animation: loading-spinner 1.3s infinite linear;
+  animation-delay: 200ms;
+  transform: translateZ(0);
+}
+
+@keyframes loading-spinner {
+  0%,
+  100% {
+    box-shadow: 0 -3em 0 0.2em,
+    2em -2em 0 0em, 3em 0 0 -1em,
+    2em 2em 0 -1em, 0 3em 0 -1em,
+    -2em 2em 0 -1em, -3em 0 0 -1em,
+    -2em -2em 0 0;
+  }
+  12.5% {
+    box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em,
+    3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em,
+    -2em 2em 0 -1em, -3em 0 0 -1em,
+    -2em -2em 0 -1em;
+  }
+  25% {
+    box-shadow: 0 -3em 0 -0.5em,
+    2em -2em 0 0, 3em 0 0 0.2em,
+    2em 2em 0 0, 0 3em 0 -1em,
+    -2em 2em 0 -1em, -3em 0 0 -1em,
+    -2em -2em 0 -1em;
+  }
+  37.5% {
+    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em,
+    3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em,
+    -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
+  }
+  50% {
+    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em,
+    3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em,
+    -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
+  }
+  62.5% {
+    box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em,
+    3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0,
+    -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
+  }
+  75% {
+    box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em,
+    3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em,
+    -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
+  }
+  87.5% {
+    box-shadow: 0em -3em 0 0, 2em -2em 0 -1em,
+    3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em,
+    -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
+  }
+}
+
+/* LikeButton */
+.like-button {
+  outline-offset: 2px;
+  position: relative;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 2.5rem;
+  height: 2.5rem;
+  cursor: pointer;
+  border-radius: 9999px;
+  border: none;
+  outline: none 2px;
+  color: #5e687e;
+  background: none;
+}
+
+.like-button:focus {
+  color: #a6423a;
+  background-color: rgba(166, 66, 58, .05);
+}
+
+.like-button:active {
+  color: #a6423a;
+  background-color: rgba(166, 66, 58, .05);
+  transform: scaleX(0.95) scaleY(0.95);
+}
+
+.like-button:hover {
+  background-color: #f6f7f9;
+}
+
+.like-button.liked {
+  color: #a6423a;
+}
+
+/* Icons */
+@keyframes circle {
+  0% {
+    transform: scale(0);
+    stroke-width: 16px;
+  }
+
+  50% {
+    transform: scale(.5);
+    stroke-width: 16px;
+  }
+
+  to {
+    transform: scale(1);
+    stroke-width: 0;
+  }
+}
+
+.circle {
+  color: rgba(166, 66, 58, .5);
+  transform-origin: center;
+  transition-property: all;
+  transition-duration: .15s;
+  transition-timing-function: cubic-bezier(.4,0,.2,1);
+}
+
+.circle.liked.animate {
+  animation: circle .3s forwards;
+}
+
+.heart {
+  width: 1.5rem;
+  height: 1.5rem;
+}
+
+.heart.liked {
+  transform-origin: center;
+  transition-property: all;
+  transition-duration: .15s;
+  transition-timing-function: cubic-bezier(.4, 0, .2, 1);
+}
+
+.heart.liked.animate {
+  animation: scale .35s ease-in-out forwards;
+}
+
+.control-icon {
+  color: hsla(0, 0%, 100%, .5);
+  filter:  drop-shadow(0 20px 13px rgba(0, 0, 0, .03)) drop-shadow(0 8px 5px rgba(0, 0, 0, .08));
+}
+
+.chevron-left {
+  margin-top: 2px;
+  rotate: 90deg;
+}
+
+
+/* Video */
+.thumbnail {
+  position: relative;
+  aspect-ratio: 16 / 9;
+  display: flex;
+  overflow: hidden;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  border-radius: 0.5rem;
+  outline-offset: 2px;
+  width: 8rem;
+  vertical-align: middle;
+  background-color: #ffffff;
+  background-size: cover;
+  user-select: none;
+}
+
+.thumbnail.blue {
+  background-image: conic-gradient(at top right, #c76a15, #087ea4, #2b3491);
+}
+
+.thumbnail.red {
+  background-image: conic-gradient(at top right, #c76a15, #a6423a, #2b3491);
+}
+
+.thumbnail.green {
+  background-image: conic-gradient(at top right, #c76a15, #388f7f, #2b3491);
+}
+
+.thumbnail.purple {
+  background-image: conic-gradient(at top right, #c76a15, #575fb7, #2b3491);
+}
+
+.thumbnail.yellow {
+  background-image: conic-gradient(at top right, #c76a15, #FABD62, #2b3491);
+}
+
+.thumbnail.gray {
+  background-image: conic-gradient(at top right, #c76a15, #4E5769, #2b3491);
+}
+
+.video {
+  display: flex;
+  flex-direction: row;
+  gap: 0.75rem;
+  align-items: center;
+}
+
+.video .link {
+  display: flex;
+  flex-direction: row;
+  flex: 1 1 0;
+  gap: 0.125rem;
+  outline-offset: 4px;
+  cursor: pointer;
+}
+
+.video .info {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  margin-left: 8px;
+  gap: 0.125rem;
+}
+
+.video .info:hover {
+  text-decoration: underline;
+}
+
+.video-title {
+  font-size: 15px;
+  line-height: 1.25;
+  font-weight: 700;
+  color: #23272f;
+}
+
+.video-description {
+  color: #5e687e;
+  font-size: 13px;
+}
+
+/* Details */
+.details .thumbnail {
+  position: relative;
+  aspect-ratio: 16 / 9;
+  display: flex;
+  overflow: hidden;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  border-radius: 0.5rem;
+  outline-offset: 2px;
+  width: 100%;
+  vertical-align: middle;
+  background-color: #ffffff;
+  background-size: cover;
+  user-select: none;
+}
+
+.video-details-title {
+  margin-top: 8px;
+}
+
+.video-details-speaker {
+  display: flex;
+  gap: 8px;
+  margin-top: 10px
+}
+
+.back {
+  display: flex;
+  align-items: center;
+  margin-left: -5px;
+  cursor: pointer;
+}
+
+.back:hover {
+  text-decoration: underline;
+}
+
+.info-title {
+  font-size: 1.5rem;
+  font-weight: 700;
+  line-height: 1.25;
+  margin: 8px 0 0 0 ;
+}
+
+.info-description {
+  margin: 8px 0 0 0;
+}
+
+.controls {
+  cursor: pointer;
+}
+
+.fallback {
+  background: #f6f7f8 linear-gradient(to right, #e6e6e6 5%, #cccccc 25%, #e6e6e6 35%) no-repeat;
+  background-size: 800px 104px;
+  display: block;
+  line-height: 1.25;
+  margin: 8px 0 0 0;
+  border-radius: 5px;
+  overflow: hidden;
+
+  animation: 1s linear 1s infinite shimmer;
+  animation-delay: 300ms;
+  animation-duration: 1s;
+  animation-fill-mode: forwards;
+  animation-iteration-count: infinite;
+  animation-name: shimmer;
+  animation-timing-function: linear;
+}
+
+
+.fallback.title {
+  width: 130px;
+  height: 30px;
+
+}
+
+.fallback.description {
+  width: 150px;
+  height: 21px;
+}
+
+@keyframes shimmer {
+  0% {
+    background-position: -468px 0;
+  }
+
+  100% {
+    background-position: 468px 0;
+  }
+}
+
+.search {
+  margin-bottom: 10px;
+}
+.search-input {
+  width: 100%;
+  position: relative;
+}
+
+.search-icon {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  inset-inline-start: 0;
+  display: flex;
+  align-items: center;
+  padding-inline-start: 1rem;
+  pointer-events: none;
+  color: #99a1b3;
+}
+
+.search-input input {
+  display: flex;
+  padding-inline-start: 2.75rem;
+  padding-top: 10px;
+  padding-bottom: 10px;
+  width: 100%;
+  text-align: start;
+  background-color: rgb(235 236 240);
+  outline: 2px solid transparent;
+  cursor: pointer;
+  border: none;
+  align-items: center;
+  color: rgb(35 39 47);
+  border-radius: 9999px;
+  vertical-align: middle;
+  font-size: 15px;
+}
+
+.search-input input:hover, .search-input input:active {
+  background-color: rgb(235 236 240/ 0.8);
+  color: rgb(35 39 47/ 0.8);
+}
+
+/* Home */
+.video-list {
+  position: relative;
+}
+
+.video-list .videos {
+  display: flex;
+  flex-direction: column;
+  gap: 1rem;
+  overflow-y: auto;
+  height: 100%;
+}
+```
+
+```js src/index.js hidden
+import React, {StrictMode} from 'react';
+import {createRoot} from 'react-dom/client';
+import './styles.css';
+
+import App from './App';
+import {Router} from './router';
+
+const root = createRoot(document.getElementById('root'));
+root.render(
+  
+    
+      
+    
+  
+);
+```
+
+```json package.json hidden
+{
+  "dependencies": {
+    "react": "experimental",
+    "react-dom": "experimental",
+    "react-scripts": "latest"
+  },
+  "scripts": {
+    "start": "react-scripts start",
+    "build": "react-scripts build",
+    "test": "react-scripts test --env=jsdom",
+    "eject": "react-scripts eject"
+  }
+}
+```
+
+
+
+
+
+#### View Transitions do not replace CSS and JS driven animations {/*view-transitions-do-not-replace-css-and-js-driven-animations*/}
+
+View Transitions are meant to be used for UI transitions such as navigation, expanding, opening, or re-ordering. They are not meant to replace all the animations in your app.
+
+In our example app above, notice that there are already animations when you click the "like" button and in the Suspense fallback glimmer. These are good use cases for CSS animations because they are animating a specific element.
+
+
+
+### Animating navigations {/*animating-navigations*/}
+
+Our app includes a Suspense-enabled router, with [page transitions already marked as Transitions](/reference/react/useTransition#building-a-suspense-enabled-router), which means navigations are performed with `startTransition`:
+
+```js
+function navigate(url) {
+  startTransition(() => {
+    go(url);
+  });
+}
+```
+
+`startTransition` is a View Transition trigger, so we can add `
` to animate between pages:
+
+```js
+// "what" to animate
+
+  {url === '/' ?  : }
+
+```
+
+When the `url` changes, the `` and new route are rendered. Since the `` was updated inside of `startTransition`, the `` is activated for an animation.
+
+
+By default, View Transitions include the browser default cross-fade animation. Adding this to our example, we now have a cross-fade whenever we navigate between pages: 
+
+
+
+```js src/App.js active
+import {unstable_ViewTransition as ViewTransition} from 'react'; import Details from './Details'; import Home from './Home'; import {useRouter} from './router';
+
+export default function App() {
+  const {url} = useRouter();
+  
+  // Use ViewTransition to animate between pages.
+  // No additional CSS needed by default.
+  return (
+    
+      {url === '/' ?  : {details.title}
+      {details.description}
+    >
+  );
+}
+
+function VideoInfoFallback() {
+  return (
+    <>
+      
+      
+    >
+  );
+}
+
+export default function Details() {
+  const { url, navigateBack } = useRouter();
+  const videoId = url.split("/").pop();
+  const video = use(fetchVideo(videoId));
+
+  return (
+     {
+            navigateBack("/");
+          }}
+        >
+           Back
+