{message}
diff --git a/src/components/MDX/ExpandableCallout.tsx b/src/components/MDX/ExpandableCallout.tsx
index 5f594063d..41d3d65d9 100644
--- a/src/components/MDX/ExpandableCallout.tsx
+++ b/src/components/MDX/ExpandableCallout.tsx
@@ -16,6 +16,7 @@ type CalloutVariants =
| 'note'
| 'wip'
| 'canary'
+ | 'experimental'
| 'major'
| 'rsc';
@@ -51,6 +52,15 @@ const variantMap = {
overlayGradient:
'linear-gradient(rgba(245, 249, 248, 0), rgba(245, 249, 248, 1)',
},
+ experimental: {
+ title: 'Experimental Feature',
+ Icon: IconCanary,
+ containerClasses:
+ 'bg-green-5 dark:bg-green-60 dark:bg-opacity-20 text-primary dark:text-primary-dark text-lg',
+ textColor: 'text-green-60 dark:text-green-40',
+ overlayGradient:
+ 'linear-gradient(rgba(245, 249, 248, 0), rgba(245, 249, 248, 1)',
+ },
pitfall: {
title: 'Pitfall',
Icon: IconPitfall,
diff --git a/src/components/MDX/MDXComponents.tsx b/src/components/MDX/MDXComponents.tsx
index f24fac598..36774ad4b 100644
--- a/src/components/MDX/MDXComponents.tsx
+++ b/src/components/MDX/MDXComponents.tsx
@@ -98,6 +98,10 @@ const Canary = ({children}: {children: React.ReactNode}) => (
{children}
);
+const Experimental = ({children}: {children: React.ReactNode}) => (
+ {children}
+);
+
const NextMajor = ({children}: {children: React.ReactNode}) => (
{children}
);
@@ -120,6 +124,20 @@ const CanaryBadge = ({title}: {title: string}) => (
);
+const ExperimentalBadge = ({title}: {title: string}) => (
+
+
+ Experimental only
+
+);
+
const NextMajorBadge = ({title}: {title: string}) => (
));
return (
-
+
{sequential ? (
@@ -351,7 +369,7 @@ function IllustrationBlock({
)}
-
+
);
}
@@ -508,6 +526,8 @@ export const MDXComponents = {
MathI,
Note,
Canary,
+ Experimental,
+ ExperimentalBadge,
CanaryBadge,
NextMajor,
NextMajorBadge,
diff --git a/src/components/MDX/Sandpack/template.ts b/src/components/MDX/Sandpack/template.ts
index 42f02f6a6..dd6fd12bd 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: '19.0.0-rc-3edc000d-20240926',
- 'react-dom': '19.0.0-rc-3edc000d-20240926',
+ react: '^19.1.0',
+ 'react-dom': '^19.1.0',
'react-scripts': '^5.0.0',
},
},
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/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(
)}
+
-Some API pages also include [Troubleshooting](/reference/react/useEffect#troubleshooting) (for common problems) and [Alternatives](/reference/react-dom/findDOMNode#alternatives) (for deprecated APIs).
+Some API pages also include [Troubleshooting](/reference/react/useEffect#troubleshooting) (for common problems) and [Alternatives](https://18.react.dev/reference/react-dom/findDOMNode#alternatives) (for deprecated APIs).
We hope that this approach will make the API reference useful not only as a way to look up an argument, but as a way to see all the different things you can do with any given API—and how it connects to the other ones.
diff --git a/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md b/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md
index 1bc78149d..df1fd085d 100644
--- a/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md
+++ b/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md
@@ -31,7 +31,7 @@ The biggest change is that we introduced [`async` / `await`](https://github.com/
Now that we have data fetching pretty well sorted, we're exploring the other direction: sending data from the client to the server, so that you can execute database mutations and implement forms. We're doing this by letting you pass Server Action functions across the server/client boundary, which the client can then call, providing seamless RPC. Server Actions also give you progressively enhanced forms before JavaScript loads.
-React Server Components has shipped in [Next.js App Router](/learn/start-a-new-react-project#nextjs-app-router). This showcases a deep integration of a router that really buys into RSC as a primitive, but it's not the only way to build a RSC-compatible router and framework. There's a clear separation for features provided by the RSC spec and implementation. React Server Components is meant as a spec for components that work across compatible React frameworks.
+React Server Components has shipped in [Next.js App Router](/learn/creating-a-react-app#nextjs-app-router). This showcases a deep integration of a router that really buys into RSC as a primitive, but it's not the only way to build a RSC-compatible router and framework. There's a clear separation for features provided by the RSC spec and implementation. React Server Components is meant as a spec for components that work across compatible React frameworks.
We generally recommend using an existing framework, but if you need to build your own custom framework, it is possible. Building your own RSC-compatible framework is not as easy as we'd like it to be, mainly due to the deep bundler integration needed. The current generation of bundlers are great for use on the client, but they weren't designed with first-class support for splitting a single module graph between the server and the client. This is why we're now partnering directly with bundler developers to get the primitives for RSC built-in.
@@ -92,7 +92,7 @@ Since our last update, we've tested an experimental version of prerendering inte
## Transition Tracing {/*transition-tracing*/}
-The Transition Tracing API lets you detect when [React Transitions](/reference/react/useTransition) become slower and investigate why they may be slow. Following our last update, we have completed the initial design of the API and published an [RFC](https://github.com/reactjs/rfcs/pull/238). The basic capabilities have also been implemented. The project is currently on hold. We welcome feedback on the RFC and look forward to resuming its development to provide a better performance measurement tool for React. This will be particularly useful with routers built on top of React Transitions, like the [Next.js App Router](/learn/start-a-new-react-project#nextjs-app-router).
+The Transition Tracing API lets you detect when [React Transitions](/reference/react/useTransition) become slower and investigate why they may be slow. Following our last update, we have completed the initial design of the API and published an [RFC](https://github.com/reactjs/rfcs/pull/238). The basic capabilities have also been implemented. The project is currently on hold. We welcome feedback on the RFC and look forward to resuming its development to provide a better performance measurement tool for React. This will be particularly useful with routers built on top of React Transitions, like the [Next.js App Router](/learn/creating-a-react-app#nextjs-app-router).
* * *
In addition to this update, our team has made recent guest appearances on community podcasts and livestreams to speak more on our work and answer questions.
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 ffe761624..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
@@ -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 cb83a6176..2e9131eb3 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
@@ -129,7 +129,7 @@ For a list of all available codemods, see the [`react-codemod` repo](https://git
In previous versions of React, errors thrown during render were caught and rethrown. In DEV, we would also log to `console.error`, resulting in duplicate error logs.
-In React 19, we've [improved how errors are handled](/blog/2024/04/25/react-19#error-handling) to reduce duplication by not re-throwing:
+In React 19, we've [improved how errors are handled](/blog/2024/12/05/react-19#error-handling) to reduce duplication by not re-throwing:
- **Uncaught Errors**: Errors that are not caught by an Error Boundary are reported to `window.reportError`.
- **Caught Errors**: Errors that are caught by an Error Boundary are reported to `console.error`.
@@ -499,7 +499,7 @@ function AutoselectingInput() {
### Deprecated: `element.ref` {/*deprecated-element-ref*/}
-React 19 supports [`ref` as a prop](/blog/2024/04/25/react-19#ref-as-a-prop), so we're deprecating the `element.ref` in place of `element.props.ref`.
+React 19 supports [`ref` as a prop](/blog/2024/12/05/react-19#ref-as-a-prop), so we're deprecating the `element.ref` in place of `element.props.ref`.
Accessing `element.ref` will warn:
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 f5a870b22..58e6b24aa 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,14 @@ October 21, 2024 by [Lauren Tan](https://twitter.com/potetotes).
---
+
+
+### 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.
+
+
+
The React team is excited to share new updates:
diff --git a/src/content/blog/2024/12/05/react-19.md b/src/content/blog/2024/12/05/react-19.md
index aac80a44f..1bbf2389c 100644
--- a/src/content/blog/2024/12/05/react-19.md
+++ b/src/content/blog/2024/12/05/react-19.md
@@ -355,7 +355,7 @@ For more information, see [React DOM Static APIs](/reference/react-dom/static).
Server Components are a new option that allows rendering components ahead of time, before bundling, in an environment separate from your client application or SSR server. This separate environment is the "server" in React Server Components. Server Components can run once at build time on your CI server, or they can be run for each request using a web server.
-React 19 includes all of the React Server Components features included from the Canary channel. This means libraries that ship with Server Components can now target React 19 as a peer dependency with a `react-server` [export condition](https://github.com/reactjs/rfcs/blob/main/text/0227-server-module-conventions.md#react-server-conditional-exports) for use in frameworks that support the [Full-stack React Architecture](/learn/start-a-new-react-project#which-features-make-up-the-react-teams-full-stack-architecture-vision).
+React 19 includes all of the React Server Components features included from the Canary channel. This means libraries that ship with Server Components can now target React 19 as a peer dependency with a `react-server` [export condition](https://github.com/reactjs/rfcs/blob/main/text/0227-server-module-conventions.md#react-server-conditional-exports) for use in frameworks that support the [Full-stack React Architecture](/learn/creating-a-react-app#which-features-make-up-the-react-teams-full-stack-architecture-vision).
@@ -389,7 +389,7 @@ For more info, see the docs for [Directives](/reference/rsc/directives).
Server Actions can be created in Server Components and passed as props to Client Components, or they can be imported and used in Client Components.
-For more, see the docs for [React Server Actions](/reference/rsc/server-actions).
+For more, see the docs for [React Server Actions](/reference/rsc/server-functions).
## Improvements in React 19 {/*improvements-in-react-19*/}
@@ -410,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.
diff --git a/src/content/blog/2025/04/21/react-compiler-rc.md b/src/content/blog/2025/04/21/react-compiler-rc.md
new file mode 100644
index 000000000..ecbbb8747
--- /dev/null
+++ b/src/content/blog/2025/04/21/react-compiler-rc.md
@@ -0,0 +1,128 @@
+---
+title: "React Compiler RC"
+author: Lauren Tan and Mofei Zhang
+date: 2025/04/21
+description: We are releasing the compiler's first Release Candidate (RC) today.
+
+---
+
+April 21, 2025 by [Lauren Tan](https://x.com/potetotes) and [Mofei Zhang](https://x.com/zmofei).
+
+---
+
+
+
+The React team is excited to share new updates:
+
+
+
+1. We're publishing React Compiler RC today, in preparation of the compiler's stable release.
+2. We're merging `eslint-plugin-react-compiler` into `eslint-plugin-react-hooks`.
+3. We've added support for swc and are working with oxc to support Babel-free builds.
+
+---
+
+[React Compiler](https://react.dev/learn/react-compiler) is a build-time tool that optimizes your React app through automatic memoization. Last year, we published React Compiler’s [first beta](https://react.dev/blog/2024/10/21/react-compiler-beta-release) and received lots of great feedback and contributions. We’re excited about the wins we’ve seen from folks adopting the compiler (see case studies from [Sanity Studio](https://github.com/reactwg/react-compiler/discussions/33) and [Wakelet](https://github.com/reactwg/react-compiler/discussions/52)) and are working towards a stable release.
+
+We are releasing the compiler's first Release Candidate (RC) today. The RC is intended to be a stable and near-final version of the compiler, and safe to try out in production.
+
+## Use React Compiler RC today {/*use-react-compiler-rc-today*/}
+To install the RC:
+
+npm
+
+{`npm install --save-dev --save-exact babel-plugin-react-compiler@rc`}
+
+
+pnpm
+
+{`pnpm add --save-dev --save-exact babel-plugin-react-compiler@rc`}
+
+
+yarn
+
+{`yarn add --dev --exact babel-plugin-react-compiler@rc`}
+
+
+As part of the RC, we've been making React Compiler easier to add to your projects and added optimizations to how the compiler generates memoization. React Complier now supports optional chains and array indices as dependencies. We're exploring how to infer even more dependencies like equality checks and string interpolation. These improvements ultimately result in fewer re-renders and more responsive UIs.
+
+We have also heard from the community that the ref-in-render validation sometimes has false positives. Since as a general philosophy we want you to be able to fully trust in the compiler's error messages and hints, we are turning it off by default for now. We will keep working to improve this validation, and we will re-enable it in a follow up release.
+
+You can find more details on using the Compiler in [our docs](https://react.dev/learn/react-compiler).
+
+## Feedback {/*feedback*/}
+During the RC period, we encourage all React users to try the compiler and provide feedback in the React repo. Please [open an issue](https://github.com/facebook/react/issues) if you encounter any bugs or unexpected behavior. If you have a general question or suggestion, please post them in the [React Compiler Working Group](https://github.com/reactwg/react-compiler/discussions).
+
+## Backwards Compatibility {/*backwards-compatibility*/}
+As noted in the Beta announcement, React Compiler is compatible with React 17 and up. If you are not yet on React 19, you can use 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](https://react.dev/learn/react-compiler#using-react-compiler-with-react-17-or-18).
+
+## Migrating from eslint-plugin-react-compiler to eslint-plugin-react-hooks {/*migrating-from-eslint-plugin-react-compiler-to-eslint-plugin-react-hooks*/}
+If you have already installed eslint-plugin-react-compiler, you can now remove it and use `eslint-plugin-react-hooks@6.0.0-rc.1`. Many thanks to [@michaelfaith](https://bsky.app/profile/michael.faith) for contributing to this improvement!
+
+To install:
+
+npm
+
+{`npm install --save-dev eslint-plugin-react-hooks@6.0.0-rc.1`}
+
+
+pnpm
+
+{`pnpm add --save-dev eslint-plugin-react-hooks@6.0.0-rc.1`}
+
+
+yarn
+
+{`yarn add --dev eslint-plugin-react-hooks@6.0.0-rc.1`}
+
+
+```js
+// eslint.config.js
+import * as reactHooks from 'eslint-plugin-react-hooks';
+
+export default [
+ // Flat Config (eslint 9+)
+ reactHooks.configs.recommended,
+
+ // Legacy Config
+ reactHooks.configs['recommended-latest']
+];
+```
+
+To enable the React Compiler rule, add `'react-hooks/react-compiler': 'error'` to your ESLint configuration.
+
+The linter does not require the compiler to be installed, so there's no risk in upgrading eslint-plugin-react-hooks. We recommend everyone upgrade today.
+
+## swc support (experimental) {/*swc-support-experimental*/}
+React Compiler can be installed across [several build tools](/learn/react-compiler#installation) such as Babel, Vite, and Rsbuild.
+
+In addition to those tools, we have been collaborating with Kang Dongyoon ([@kdy1dev](https://x.com/kdy1dev)) from the [swc](https://swc.rs/) team on adding additional support for React Compiler as an swc plugin. While this work isn't done, Next.js build performance should now be considerably faster when the [React Compiler is enabled in your Next.js app](https://nextjs.org/docs/app/api-reference/config/next-config-js/reactCompiler).
+
+We recommend using Next.js [15.3.1](https://github.com/vercel/next.js/releases/tag/v15.3.1) or greater to get the best build performance.
+
+Vite users can continue to use [vite-plugin-react](https://github.com/vitejs/vite-plugin-react) to enable the compiler, by adding it as a [Babel plugin](https://react.dev/learn/react-compiler#usage-with-vite). We are also working with the [oxc](https://oxc.rs/) team to [add support for the compiler](https://github.com/oxc-project/oxc/issues/10048). Once [rolldown](https://github.com/rolldown/rolldown) is officially released and supported in Vite and oxc support is added for React Compiler, we'll update the docs with information on how to migrate.
+
+## Upgrading React Compiler {/*upgrading-react-compiler*/}
+React Compiler works best when the auto-memoization applied is strictly for performance. Future versions of the compiler may change how memoization is applied, for example it could become more granular and precise.
+
+However, because product code may sometimes break the [rules of React](https://react.dev/reference/rules) in ways that aren't always statically detectable in JavaScript, changing memoization can occasionally have unexpected results. For example, a previously memoized value might be used as a dependency for a useEffect somewhere in the component tree. Changing how or whether this value is memoized can cause over or under-firing of that useEffect. While we encourage [useEffect only for synchronization](https://react.dev/learn/synchronizing-with-effects), your codebase may have useEffects that cover other use-cases such as effects that needs to only run in response to specific values changing.
+
+In other words, changing memoization may under rare circumstances cause unexpected behavior. For this reason, we recommend following the Rules of React and employing continuous end-to-end testing of your app so you can upgrade the compiler with confidence and identify any rules of React violations that might cause issues.
+
+If you don't have good test coverage, we recommend pinning the compiler to an exact version (eg `19.1.0`) rather than a SemVer range (eg `^19.1.0`). You can do this by passing the `--save-exact` (npm/pnpm) or `--exact` flags (yarn) when upgrading the compiler. You should then do any upgrades of the compiler manually, taking care to check that your app still works as expected.
+
+## Roadmap to Stable {/*roadmap-to-stable*/}
+*This is not a final roadmap, and is subject to change.*
+
+After a period of final feedback from the community on the RC, we plan on a Stable Release for the compiler.
+
+* ✅ Experimental: Released at React Conf 2024, primarily for feedback from application developers.
+* ✅ Public Beta: Available today, for feedback from library authors.
+* ✅ Release Candidate (RC): React Compiler works for the majority of rule-following apps and libraries without issue.
+* General Availability: After final feedback period from the community.
+
+Post-Stable, we plan to add more compiler optimizations and improvements. This includes both continual improvements to automatic memoization, and new optimizations altogether, with minimal to no change of product code. Each upgrade will continue to improve performance and add better handling of diverse JavaScript and React patterns.
+
+---
+
+Thanks to [Joe Savona](https://x.com/en_JS), [Jason Bonta](https://x.com/someextent), [Jimmy Lai](https://x.com/feedthejim), and [Kang Dongyoon](https://x.com/kdy1dev) (@kdy1dev) for reviewing and editing this post.
diff --git a/src/content/blog/2025/04/23/react-labs-view-transitions-activity-and-more.md b/src/content/blog/2025/04/23/react-labs-view-transitions-activity-and-more.md
new file mode 100644
index 000000000..0f54d02b4
--- /dev/null
+++ b/src/content/blog/2025/04/23/react-labs-view-transitions-activity-and-more.md
@@ -0,0 +1,14358 @@
+---
+title: "React Labs: View Transitions, Activity, and more"
+author: Ricky Hanlon
+date: 2025/04/23
+description: In React Labs posts, we write about projects in active research and development. In this post, we're sharing two new experimental features that are ready to try today, and updates on other areas we're working on now.
+---
+
+April 23, 2025 by [Ricky Hanlon](https://twitter.com/rickhanlonii)
+
+---
+
+
+
+In React Labs posts, we write about projects in active research and development. In this post, we're sharing two new experimental features that are ready to try today, and updates on other areas we're working on now.
+
+
+
+
+
+
+React Conf 2025 is scheduled for October 7–8 in Henderson, Nevada!
+
+We're looking for speakers to help us create talks about the features covered in this post. If you're interested in speaking at ReactConf, [please apply here](https://forms.reform.app/react-conf/call-for-speakers/) (no talk proposal required).
+
+For more info on tickets, free streaming, sponsoring, and more, see [the React Conf website](https://conf.react.dev).
+
+
+
+Today, we're excited to release documentation for two new experimental features that are ready for testing:
+
+- [View Transitions](#view-transitions)
+- [Activity](#activity)
+
+We're also sharing updates on new features currently in development:
+- [React Performance Tracks](#react-performance-tracks)
+- [Compiler IDE Extension](#compiler-ide-extension)
+- [Automatic Effect Dependencies](#automatic-effect-dependencies)
+- [Fragment Refs](#fragment-refs)
+- [Concurrent Stores](#concurrent-stores)
+
+---
+
+# New Experimental Features {/*new-experimental-features*/}
+
+View Transitions and Activity are now ready for testing in `react@experimental`. These features have been tested in production and are stable, but the final API may still change as we incorporate feedback.
+
+You can try them by upgrading React packages to the most recent experimental version:
+
+- `react@experimental`
+- `react-dom@experimental`
+
+Read on to learn how to use these features in your app, or check out the newly published docs:
+
+- [``](/reference/react/ViewTransition): A component that lets you activate an animation for a Transition.
+- [`addTransitionType`](/reference/react/addTransitionType): A function that allows you to specify the cause of a Transition.
+- [``](/reference/react/Activity): A component that lets you hide and show parts of the UI.
+
+## View Transitions {/*view-transitions*/}
+
+React View Transitions are a new experimental feature that makes it easier to add animations to UI transitions in your app. Under-the-hood, these animations use the new [`startViewTransition`](https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition) API available in most modern browsers.
+
+To opt-in to animating an element, wrap it in the new `` component:
+
+```js
+// "what" to animate.
+
+ 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
+
{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 ( +{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 ( +{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 ( +{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 ( +{details.title}
+{details.description}
+{details.title}
+{details.description}
+ > + ); +} +``` + +```js src/Home.js hidden +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 ( +{details.title}
+{details.description}
+ > + ); +} +``` + +```js src/Home.js +import { useId, useState, use, useDeferredValue, unstable_ViewTransition as ViewTransition } from "react";import { Video } from "./Videos";import Layout from "./Layout";import { fetchVideos } from "./data";import { IconSearch } from "./Icons"; + +function SearchList({searchText, videos}) { + // Activate with useDeferredValue ("when") + const deferredSearchText = useDeferredValue(searchText); + const filteredVideos = filterVideos(videos, deferredSearchText); + return ( +{details.title}
+{details.description}
+ > + ); +} +``` + +```js src/Home.js +import { useId, useState, use, useDeferredValue, unstable_ViewTransition as ViewTransition } from "react";import { Video } from "./Videos";import Layout from "./Layout";import { fetchVideos } from "./data";import { IconSearch } from "./Icons"; + +function SearchList({searchText, videos}) { + // Activate with useDeferredValue ("when") + const deferredSearchText = useDeferredValue(searchText); + const filteredVideos = filterVideos(videos, deferredSearchText); + return ( +{details.title}
+{details.description}
+ > + ); +} +``` + +```js src/Home.js hidden +import { useId, useState, use, useDeferredValue, unstable_ViewTransition as ViewTransition } from "react";import { Video } from "./Videos";import Layout from "./Layout";import { fetchVideos } from "./data";import { IconSearch } from "./Icons"; + +function SearchList({searchText, videos}) { + // Activate with useDeferredValue ("when") + const deferredSearchText = useDeferredValue(searchText); + const filteredVideos = filterVideos(videos, deferredSearchText); + return ( +{details.title}
+{details.description}
+ > + ); +} +``` + +```js src/Home.js hidden +import { useId, useState, use, useDeferredValue, unstable_ViewTransition as ViewTransition } from "react";import { Video } from "./Videos";import Layout from "./Layout";import { fetchVideos } from "./data";import { IconSearch } from "./Icons"; + +function SearchList({searchText, videos}) { + // Activate with useDeferredValue ("when") + const deferredSearchText = useDeferredValue(searchText); + const filteredVideos = filterVideos(videos, deferredSearchText); + return ( +