+ );
+}
diff --git a/src/components/MDX/MDXComponents.tsx b/src/components/MDX/MDXComponents.tsx
index bdfd05a20c1..a89edf9c88a 100644
--- a/src/components/MDX/MDXComponents.tsx
+++ b/src/components/MDX/MDXComponents.tsx
@@ -8,7 +8,7 @@ import cn from 'classnames';
import CodeBlock from './CodeBlock';
import {CodeDiagram} from './CodeDiagram';
-import ConsoleBlock from './ConsoleBlock';
+import {ConsoleBlock, ConsoleLogLine, ConsoleBlockMulti} from './ConsoleBlock';
import ExpandableCallout from './ExpandableCallout';
import ExpandableExample from './ExpandableExample';
import {H1, H2, H3, H4, H5} from './Heading';
@@ -420,6 +420,8 @@ export const MDXComponents = {
pre: CodeBlock,
CodeDiagram,
ConsoleBlock,
+ ConsoleBlockMulti,
+ ConsoleLogLine,
DeepDive: (props: {
children: React.ReactNode;
title: string;
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
new file mode 100644
index 00000000000..5e1b410b121
--- /dev/null
+++ b/src/content/blog/2024/04/25/react-19-upgrade-guide.md
@@ -0,0 +1,655 @@
+---
+title: "React 19 Beta Upgrade Guide"
+---
+
+April 25, 2024 by [Ricky Hanlon](https://twitter.com/rickhanlonii)
+
+---
+
+
+
+This beta release is for libraries to prepare for React 19. App developers should upgrade to 18.3.0 and wait for React 19 stable as we work with libraries and make changes based on feedback.
+
+
+
+
+
+
+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.
+
+To help make the upgrade easier, today we are also publishing React 18.3.
+
+
+
+
+
+#### React 18.3 has also been published {/*react-18-3*/}
+
+To help make the upgrade to React 19 easier, we've published a `react@18.3` release that is identical to 18.2 but adds warnings for deprecated APIs and other changes that are needed for React 19.
+
+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).
+
+
+
+In this post, we will guide you through the steps for upgrading libraries to React 19 beta:
+
+- [Installing](#installing)
+- [Breaking Changes](#breaking-changes)
+- [New Deprecations](#new-deprecations)
+- [Notable Changes](#notable-changes)
+- [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 beta, see the [React 19 release post](/blog/2024/04/25/react-19).
+
+---
+## Installing {/*installing*/}
+
+
+
+#### New JSX Transform is now required {/*new-jsx-transform-is-now-required*/}
+
+We introduced a [new JSX transform](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) in 2020 to improve bundle size and use JSX without importing React. In React 19, we're adding additional improvements like using ref as a prop and JSX speed improvements that require the new transform.
+
+If the new transform is not enabled, you will see this warning:
+
+
+
+
+
+Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance: https://react.dev/link/new-jsx-transform
+
+
+
+
+
+
+We expect most apps will not be affected since the transform is enabled in most environments already. For manual instructions on how to upgrade, please see the [announcement post](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html).
+
+
+
+
+To install the latest version of React and React DOM:
+
+```bash
+npm install react@beta react-dom@beta
+```
+
+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`. During the beta period, the types are available in different packages which need to be enforced in your `package.json`:
+
+```json
+{
+ "dependencies": {
+ "@types/react": "npm:types-react@alpha",
+ "@types/react-dom": "npm:types-react-dom@alpha"
+ },
+ "overrides": {
+ "@types/react": "npm:types-react@alpha",
+ "@types/react-dom": "npm:types-react-dom@alpha"
+ }
+}
+```
+
+We're also including a codemod for the most common replacements. See [Removed TypeScript Types](#removed-deprecated-typescript-types) below.
+
+
+## Breaking Changes {/*breaking-changes*/}
+
+### Errors in render are not re-thrown {/*errors-in-render-are-not-re-thrown*/}
+
+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:
+
+- **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`.
+
+This change should not impact most apps, but if your production error reporting relies on errors being re-thrown, you may need to update your error handling. To support this, we've added new methods to `createRoot` and `hydrateRoot` for custom error handling:
+
+```js [[1, 2, "onUncaughtError"], [2, 5, "onCaughtError"]]
+const root = createRoot(container, {
+ onUncaughtError: (error, errorInfo) => {
+ // ... log error report
+ },
+ onCaughtError: (error, errorInfo) => {
+ // ... log error report
+ }
+});
+```
+
+For more info, see the docs for [`createRoot`](https://react.dev/reference/react-dom/client/createRoot) and [`hydrateRoot`](https://react.dev/reference/react-dom/client/hydrateRoot).
+
+
+### Removed deprecated React APIs {/*removed-deprecated-react-apis*/}
+
+#### Removed: `propTypes` and `defaultProps` for functions {/*removed-proptypes-and-defaultprops*/}
+`PropTypes` were deprecated in [April 2017 (v15.5.0)](https://legacy.reactjs.org/blog/2017/04/07/react-v15.5.0.html#new-deprecation-warnings).
+
+In React 19, we're removing the `propType` checks from the React package, and using them will be silently ignored. If you're using `propTypes`, we recommend migrating to TypeScript or another type-checking solution.
+
+We're also removing `defaultProps` from function components in place of ES6 default parameters. Class components will continue to support `defaultProps` since there is no ES6 alternative.
+
+```js
+// Before
+import PropTypes from 'prop-types';
+
+function Heading({text}) {
+ return
;
+}
+```
+
+#### Removed: Legacy Context using `contextTypes` and `getChildContext` {/*removed-removing-legacy-context*/}
+
+Legacy Context was deprecated in [October 2018 (v16.6.0)](https://legacy.reactjs.org/blog/2018/10/23/react-v-16-6.html).
+
+Legacy Context was only available in class components using the APIs `contextTypes` and `getChildContext`, and was replaced with `contextType` due to subtle bugs that were easy to miss. In React 19, we're removing Legacy Context to make React slightly smaller and faster.
+
+If you're still using Legacy Context in class components, you'll need to migrate to the new `contextType` API:
+
+```js
+// Before
+import PropTypes from 'prop-types';
+
+class Parent extends React.Component {
+ static childContextTypes = {
+ foo: PropTypes.string.isRequired,
+ };
+
+ getChildContext() {
+ return { foo: 'bar' };
+ }
+
+ render() {
+ return ;
+ }
+}
+
+class Child extends React.Component {
+ static contextTypes = {
+ foo: PropTypes.string.isRequired,
+ };
+
+ render() {
+ return
;
+ }
+}
+```
+
+#### Removed: string refs {/*removed-string-refs*/}
+String refs were deprecated in [March, 2018 (v16.3.0)](https://legacy.reactjs.org/blog/2018/03/27/update-on-async-rendering.html).
+
+Class components supported string refs before being replaced by ref callbacks due to [multiple downsides](https://github.com/facebook/react/issues/1373). In React 19, we're removing string refs to make React simpler and easier to understand.
+
+If you're still using string refs in class components, you'll need to migrate to ref callbacks:
+
+```js
+// Before
+class MyComponent extends React.Component {
+ componentDidMount() {
+ this.refs.input.focus();
+ }
+
+ render() {
+ return ;
+ }
+}
+```
+
+```js
+// After
+class MyComponent extends React.Component {
+ componentDidMount() {
+ this.input.focus();
+ }
+
+ render() {
+ return this.input = input} />;
+ }
+}
+```
+
+
+
+To help with the migration, we will be publishing a [react-codemod](https://github.com/reactjs/react-codemod/#string-refs) to automatically replace string refs with `ref` callbacks. Follow [this PR](https://github.com/reactjs/react-codemod/pull/309) for updates and to try it out.
+
+
+
+#### Removed: Module pattern factories {/*removed-module-pattern-factories*/}
+Module pattern factories were deprecated in [August 2019 (v16.9.0)](https://legacy.reactjs.org/blog/2019/08/08/react-v16.9.0.html#deprecating-module-pattern-factories).
+
+This pattern was rarely used and supporting it causes React to be slightly larger and slower than necessary. In React 19, we're removing support for module pattern factories, and you'll need to migrate to regular functions:
+
+```js
+// Before
+function FactoryComponent() {
+ return { render() { return ; } }
+}
+```
+
+```js
+// After
+function FactoryComponent() {
+ return ;
+}
+```
+
+#### Removed: `React.createFactory` {/*removed-createfactory*/}
+`createFactory` was deprecated in [February 2020 (v16.13.0)](https://legacy.reactjs.org/blog/2020/02/26/react-v16.13.0.html#deprecating-createfactory).
+
+Using `createFactory` was common before broad support for JSX, but it's rarely used today and can be replaced with JSX. In React 19, we're removing `createFactory` and you'll need to migrate to JSX:
+
+```js
+// Before
+import { createFactory } from 'react';
+
+const button = createFactory('button');
+```
+
+```js
+// After
+const button = ;
+```
+
+#### Removed: `react-test-renderer/shallow` {/*removed-react-test-renderer-shallow*/}
+
+In React 18, we updated `react-test-renderer/shallow` to re-export [react-shallow-renderer](https://github.com/enzymejs/react-shallow-renderer). In React 19, we're removing `react-test-render/shallow` to prefer installing the package directly:
+
+```bash
+npm install react-shallow-renderer --save-dev
+```
+```diff
+- import ShallowRenderer from 'react-test-renderer/shallow';
++ import ShallowRenderer from 'react-shallow-renderer';
+```
+
+
+
+##### Please reconsider shallow rendering {/*please-reconsider-shallow-rendering*/}
+
+Shallow rendering depends on React internals and can block you from future upgrades. We recommend migrating your tests to [@testing-library/react](https://testing-library.com/docs/react-testing-library/intro/) or [@testing-library/react-native](https://callstack.github.io/react-native-testing-library/docs/getting-started).
+
+
+
+### Removed deprecated React DOM APIs {/*removed-deprecated-react-dom-apis*/}
+
+#### Removed: `react-dom/test-utils` {/*removed-react-dom-test-utils*/}
+
+We've moved `act` from `react-dom/test-utils` to the `react` package:
+
+
+
+
+
+`ReactDOMTestUtils.act` is deprecated in favor of `React.act`. Import `act` from `react` instead of `react-dom/test-utils`. See https://react.dev/warnings/react-dom-test-utils for more info.
+
+
+
+
+
+To fix this warning, you can import `act` from `react`:
+
+```diff
+- import {act} from 'react-dom/test-utils'
++ import {act} from 'react';
+```
+
+All other `test-utils` functions have been removed. These utilities were uncommon, and made it too easy to depend on low level implementation details of your components and React. In React 19, these functions will error when called and their exports will be removed in a future version.
+
+See the [warning page](https://react.dev/warnings/react-dom-test-utils) to for alternatives.
+
+#### Removed: `ReactDOM.render` {/*removed-reactdom-render*/}
+
+`ReactDOM.render` was deprecated in [March 2022 (v18.0.0)](https://react.dev/blog/2022/03/08/react-18-upgrade-guide). In React 19, we're removing `ReactDOM.render` and you'll need to migrate to using [`ReactDOM.createRoot`](https://react.dev/reference/react-dom/client/createRoot):
+
+```js
+// Before
+import {render} from 'react-dom';
+render(, document.getElementById('root'));
+
+// After
+import {createRoot} from 'react-dom/client';
+const root = createRoot(document.getElementById('root'));
+root.render();
+```
+
+#### Removed: `ReactDOM.hydrate` {/*removed-reactdom-hydrate*/}
+
+`ReactDOM.hydrate` was deprecated in [March 2022 (v18.0.0)](https://react.dev/blog/2022/03/08/react-18-upgrade-guide). In React 19, we're removing `ReactDOM.hydrate` you'll need to migrate to using [`ReactDOM.hydrateRoot`](https://react.dev/reference/react-dom/client/hydrateRoot),
+
+```js
+// Before
+import {hydrate} from 'react-dom';
+hydrate(, document.getElementById('root'));
+
+// After
+import {hydrateRoot} from 'react-dom/client';
+hydrate(document.getElementById('root'), );
+```
+
+
+#### Removed: `unmountComponentAtNode` {/*removed-unmountcomponentatnode*/}
+
+`ReactDOM.unmountComponentAtNode` was deprecated in [March 2022 (v18.0.0)](https://react.dev/blog/2022/03/08/react-18-upgrade-guide). In React 19, you'll need to migrate to using `root.unmount()`.
+
+
+```js
+// Before
+unmountComponentAtNode(document.getElementById('root'));
+
+// After
+root.unmount();
+```
+
+For more see `root.unmount()` for [`createRoot`](https://react.dev/reference/react-dom/client/createRoot#root-unmount) and [`hydrateRoot`](https://react.dev/reference/react-dom/client/hydrateRoot#root-unmount).
+
+
+#### Removed: `ReactDOM.findDOMNode` {/*removed-reactdom-finddomnode*/}
+`ReactDOM.findDOMNode` was [deprecated in October 2018 (v16.6.0)](https://legacy.reactjs.org/blog/2018/10/23/react-v-16-6.html#deprecations-in-strictmode).
+
+We're removing `findDOMNode` because it was a legacy escape hatch that was slow to execute, fragile to refactoring, only returned the first child, and broke abstraction levels (see more [here](https://legacy.reactjs.org/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage)). You can replace `ReactDOM.findDOMNode` with [DOM refs](/learn/manipulating-the-dom-with-refs):
+
+```js
+// Before
+import {findDOMNode} from 'react-dom';
+
+function AutoselectingInput() {
+ useEffect(() => {
+ const input = findDOMNode(this);
+ input.select()
+ }, []);
+
+ return ;
+}
+```
+
+```js
+// After
+function AutoselectingInput() {
+ const ref = useRef(null);
+ useEffect(() => {
+ ref.current.select();
+ }, []);
+
+ return
+}
+```
+
+## New Deprecations {/*new-deprecations*/}
+
+### 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`.
+
+Accessing `element.ref` will warn:
+
+
+
+
+
+Accessing element.ref is no longer supported. ref is now a regular prop. It will be removed from the JSX Element type in a future release.
+
+
+
+
+
+### Deprecated: `react-test-renderer` {/*deprecated-react-test-renderer*/}
+
+We are deprecating `react-test-renderer` because it implements its own renderer environment that doesn't match the environment users use, promotes testing implementation details, and relies on introspection of React's internals.
+
+The test renderer was created before there were more viable testing strategies available like [React Testing Library](https://testing-library.com), and we now recommend using a modern testing library instead.
+
+In React 19, `react-test-renderer` logs a deprecation warning, and has switched to concurrent rendering. We recommend migrating your tests to [@testing-library/react](https://testing-library.com/docs/react-testing-library/intro/) or [@testing-library/react-native](https://callstack.github.io/react-native-testing-library/docs/getting-started) for a modern and well supported testing experience.
+
+## Notable Changes {/*notable-changes*/}
+
+### StrictMode changes {/*strict-mode-improvements*/}
+
+React 19 includes several fixes and improvements to Strict Mode.
+
+When double rendering in Strict Mode in development, `useMemo` and `useCallback` will reuse the memoized results from the first render during the second render. Components that are already Strict Mode compatible should not notice a difference in behavior.
+
+As with all Strict Mode behaviors, these features are designed to proactively surface bugs in your components during development so you can fix them before they are shipped to production. For example, during development, Strict Mode will double-invoke ref callback functions on initial mount, to simulate what happens when a mounted component is replaced by a Suspense fallback.
+
+### UMD builds removed {/*umd-builds-removed*/}
+
+UMD was widely used in the past as a convenient way to load React without a build step. Now, there are modern alternatives for loading modules as scripts in HTML documents. Starting with React 19, React will no longer produce UMD builds to reduce the complexity of its testing and release process.
+
+To load React 19 with a script tag, we recommend using an ESM-based CDN such as [esm.sh](https://esm.sh/).
+
+```html
+
+```
+
+### Libraries depending on React internals may block upgrades {/*libraries-depending-on-react-internals-may-block-upgrades*/}
+
+This release includes changes to React internals that may impact libraries that ignore our pleas to not use internals like `SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED`. These changes are necessary to land improvements in React 19, and will not break libraries that follow our guidelines.
+
+Based on our [Versioning Policy](https://react.dev/community/versioning-policy#what-counts-as-a-breaking-change), these updates are not listed as breaking changes, and we are not including docs for how to upgrade them. The recommendation is to remove any code that depends on internals.
+
+To reflect the impact of using internals, we have renamed the `SECRET_INTERNALS` suffix to:
+
+`_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE`
+
+In the future we will more aggressively block accessing internals from React to discourage usage and ensure users are not blocked from upgrading.
+
+## TypeScript Changes {/*typescript-changes*/}
+
+### Removed deprecated TypeScript types {/*removed-deprecated-typescript-types*/}
+
+We've cleaned up the TypeScript types based on the removed APIs in React 19. Some of the removed have types been moved to more relevant packages, and others are no longer needed to describe React's behavior.
+
+
+We've published [`types-react-codemod`](https://github.com/eps1lon/types-react-codemod/) to migrate most type related breaking changes:
+
+```bash
+npx types-react-codemod@latest preset-19 ./path-to-app
+```
+
+If you have a lot of unsound access to `element.props`, you can run this additional codemod:
+
+```bash
+npx types-react-codemod@latest react-element-default-any-props ./path-to-your-react-ts-files
+```
+
+
+
+Check out [`types-react-codemod`](https://github.com/eps1lon/types-react-codemod/) for a list of supported replacements. If you feel a codemod is missing, it can be tracked in the [list of missing React 19 codemods](https://github.com/eps1lon/types-react-codemod/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22React+19%22+label%3Aenhancement).
+
+
+### `ref` cleanups required {/*ref-cleanup-required*/}
+
+_This change is included in the `react-19` codemod preset as [`no-implicit-ref-callback-return
+`](https://github.com/eps1lon/types-react-codemod/#no-implicit-ref-callback-return)._
+
+Due to the introduction of ref cleanup functions, returning anything else from a ref callback will now be rejected by TypeScript. The fix is usually to stop using implicit returns:
+
+```diff [[1, 1, "("], [1, 1, ")"], [2, 2, "{", 15], [2, 2, "}", 1]]
+-
(instance = current)} />
++
{instance = current}} />
+```
+
+The original code returned the instance of the `HTMLDivElement` and TypeScript wouldn't know if this was supposed to be a cleanup function or not.
+
+### `useRef` requires an argument {/*useref-requires-argument*/}
+
+_This change is included in the `react-19` codemod preset as [`refobject-defaults`](https://github.com/eps1lon/types-react-codemod/#refobject-defaults)._
+
+A long-time complaint of how TypeScript and React work has been `useRef`. We've changed the types so that `useRef` now requires an argument. This significantly simplifies its type signature. It'll now behave more like `createContext`.
+
+```ts
+// @ts-expect-error: Expected 1 argument but saw none
+useRef();
+// Passes
+useRef(undefined);
+// @ts-expect-error: Expected 1 argument but saw none
+createContext();
+// Passes
+createContext(undefined);
+```
+
+This now also means that all refs are mutable. You'll no longer hit the issue where you can't mutate a ref because you initialised it with `null`:
+
+```ts
+const ref = useRef(null);
+
+// Cannot assign to 'current' because it is a read-only property
+ref.current = 1;
+```
+
+`MutableRef` is now deprecated in favor of a single `RefObject` type which `useRef` will always return:
+
+```ts
+interface RefObject {
+ current: T
+}
+
+declare function useRef: RefObject
+```
+
+`useRef` still has a convenience overload for `useRef(null)` that automatically returns `RefObject`. To ease migration due to the required argument for `useRef`, a convenience overload for `useRef(undefined)` was added that automatically returns `RefObject`.
+
+Check out [[RFC] Make all refs mutable](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/64772) for prior discussions about this change.
+
+### Changes to the `ReactElement` TypeScript type {/*changes-to-the-reactelement-typescript-type*/}
+
+_This change is included in the [`react-element-default-any-props`](https://github.com/eps1lon/types-react-codemod#react-element-default-any-props) codemod._
+
+The `props` of React elements now default to `unknown` instead of `any` if the element is typed as `ReactElement`. This does not affect you if you pass a type argument to `ReactElement`:
+
+```ts
+type Example2 = ReactElement<{ id: string }>["props"];
+// ^? { id: string }
+```
+
+But if you relied on the default, you now have to handle `unknown`:
+
+```ts
+type Example = ReactElement["props"];
+// ^? Before, was 'any', now 'unknown'
+```
+
+You should only need it if you have a lot of legacy code relying on unsound access of element props. Element introspection only exists as an escape hatch, and you should make it explicit that your props access is unsound via an explicit `any`.
+
+### The JSX Namespace in TypeScript {/*the-jsx-namespace-in-typescript*/}
+This change is included in the `react-19` codemod preset as [`scoped-jsx`](https://github.com/eps1lon/types-react-codemod#scoped-jsx)
+
+A long-time request is to remove the global `JSX` namespace from our types in favor of `React.JSX`. This helps prevent pollution of global types which prevents conflicts between different UI libraries that leverage JSX.
+
+You'll now need to wrap module augmentation of the JSX namespace in `declare module "....":
+
+```diff
+// global.d.ts
++ declare module "react" {
+ namespace JSX {
+ interface IntrinsicElements {
+ "my-element": {
+ myElementProps: string;
+ };
+ }
+ }
++ }
+```
+
+The exact module specifier depends on the JSX runtime you specified in the `compilerOptions` of your `tsconfig.json`:
+
+- For `"jsx": "react-jsx"` it would be `react/jsx-runtime`.
+- For `"jsx": "react-jsxdev"` it would be `react/jsx-dev-runtime`.
+- For `"jsx": "react"` and `"jsx": "preserve"` it would be `react`.
+
+### Better `useReducer` typings {/*better-usereducer-typings*/}
+
+`useReducer` now has improved type inference thanks to [@mfp22](https://github.com/mfp22).
+
+However, this required a breaking change where `useReducer` doesn't accept the full reducer type as a type parameter but instead either needs none (and rely on contextual typing) or needs both the state and action type.
+
+The new best practice is _not_ to pass type arguments to `useReducer`.
+```diff
+- useReducer>(reducer)
++ useReducer(reducer)
+```
+This may not work in edge cases where you can explicitly type the state and action, by passing in the `Action` in a tuple:
+```diff
+- useReducer>(reducer)
++ useReducer(reducer)
+```
+If you define the reducer inline, we encourage to annotate the function parameters instead:
+```diff
+- useReducer>((state, action) => state)
++ useReducer((state: State, action: Action) => state)
+```
+This is also what you'd also have to do if you move the reducer outside of the `useReducer` call:
+
+```ts
+const reducer = (state: State, action: Action) => state;
+```
+
+## Changlog {/*changelog*/}
+
+### 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**: 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-is**: Remove deprecated methods from `react-is` [28224](https://github.com/facebook/react/pull/28224)
+
+### Other Notable Changes {/*other-notable-changes*/}
+
+- **react**: Batch sync, default and continuous lanes [#25700](https://github.com/facebook/react/pull/25700)
+- **react**: Don't prerender siblings of suspended component [#26380](https://github.com/facebook/react/pull/26380)
+- **react**: Detect infinite update loops caused by render phase updates [#26625](https://github.com/facebook/react/pull/26625)
+- **react-dom**: Transitions in popstate are now synchronous [#26025](https://github.com/facebook/react/pull/26025)
+- **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.
+
+---
+
+Thanks to [Andrew Clark](https://twitter.com/acdlite), [Eli White](https://twitter.com/Eli_White), [Jack Pope](https://github.com/jackpope), [Jan Kassens](https://github.com/kassens), [Josh Story](https://twitter.com/joshcstory), [Matt Carroll](https://twitter.com/mattcarrollcode), [Noah Lemen](https://twitter.com/noahlemen), [Sophie Alpert](https://twitter.com/sophiebits), and [Sebastian Silbermann](https://twitter.com/sebsilbermann) for reviewing and editing this post.
diff --git a/src/content/blog/2024/04/25/react-19.md b/src/content/blog/2024/04/25/react-19.md
new file mode 100644
index 00000000000..4431b5bf6e3
--- /dev/null
+++ b/src/content/blog/2024/04/25/react-19.md
@@ -0,0 +1,768 @@
+---
+title: "React 19 Beta"
+---
+
+April 25, 2024 by [The React Team](/community/team)
+
+---
+
+
+
+This beta release is for libraries to prepare for React 19. App developers should upgrade to 18.3.0 and wait for React 19 stable as we work with libraries and make changes based on feedback.
+
+
+
+
+
+React 19 Beta is now available on npm!
+
+
+
+In our [React 19 Beta Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide), we shared step-by-step instructions for upgrading your app to React 19 Beta. 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)
+- [How to Upgrade](#how-to-upgrade)
+
+For a list of breaking changes, see the [Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide).
+
+---
+
+## What's new in React 19 {/*whats-new-in-react-19*/}
+
+### Actions {/*actions*/}
+
+A common use case in React apps is to perform a data mutation and then update state in response. For example, when a user submits a form to change their name, you will make an API request, and then handle the response. In the past, you would need to handle pending states, errors, optimistic updates, and sequential requests manually.
+
+For example, you could handle the pending and error state in `useState`:
+
+```js
+// Before Actions
+function UpdateName({}) {
+ const [name, setName] = useState("");
+ const [error, setError] = useState(null);
+ const [isPending, setIsPending] = useState(false);
+
+ const handleSubmit = async () => {
+ setIsPending(true);
+ const error = await updateName(name);
+ setIsPending(false);
+ if (error) {
+ setError(error);
+ return;
+ }
+ redirect("/path");
+ };
+
+ return (
+
+ setName(event.target.value)} />
+
+ {error &&
{error}
}
+
+ );
+}
+```
+
+In React 19, we're adding support for using async functions in transitions to handle pending states, errors, forms, and optimistic updates automatically.
+
+For example, you can use `useTransition` to handle the pending state for you:
+
+```js
+// Using pending state from Actions
+function UpdateName({}) {
+ const [name, setName] = useState("");
+ const [error, setError] = useState(null);
+ const [isPending, startTransition] = useTransition();
+
+ const handleSubmit = async () => {
+ startTransition(async () => {
+ const error = await updateName(name);
+ if (error) {
+ setError(error);
+ return;
+ }
+ redirect("/path");
+ })
+ };
+
+ return (
+
+ setName(event.target.value)} />
+
+ {error &&
{error}
}
+
+ );
+}
+```
+
+The async transition will immediately set the `isPending` state to true, make the async request(s), and switch `isPending` to false after any transitions. This allows you to keep the current UI responsive and interactive while the data is changing.
+
+
+
+#### By convention, functions that use async transitions are called "Actions". {/*by-convention-functions-that-use-async-transitions-are-called-actions*/}
+
+Actions automatically manage submitting data for you:
+
+- **Pending state**: Actions provide a pending state that starts at the beginning of a request and automatically resets when the final state update is committed.
+- **Optimistic updates**: Actions support the new [`useOptimistic`](#new-feature-optimistic-updates) hook so you can show users instant feedback while the requests are submitting.
+- **Error handling**: Actions provide error handling so you can and display Error Boundaries when a request fails, and revert optimistic updates to their original value automatically.
+- **Forms**: `
+
+Building on top of Actions, we're also introducing [`
+ );
+}
+```
+
+In the next section, we'll break down each of the new Action features in React 19.
+
+### New Hook: `useActionState` {/*new-hook-useactionstate*/}
+
+To make the common cases easier for Actions, we've added a new hook called `useActionState`:
+
+```js
+const [error, submitAction, isPending] = useActionState(async (previousState, newName) => {
+ const {error} = await updateName(newName);
+ if (!error) {
+ // You can return any result of the action.
+ // Here, we return only the error.
+ return error;
+ }
+
+ // handle success
+});
+```
+
+`useActionState` accepts a function (the "Action"), and returns a wrapped Action to call. This works because Actions compose. When the wrapped Action is called, `useActionState` will return the last result of the Action as `data`, and the pending state of the Action as `pending`.
+
+
+
+`React.useActionState` was previously called `ReactDOM.useFormState` in the Canary releases, but we've renamed it and deprecated `useFormState`.
+
+See [#28491](https://github.com/facebook/react/pull/28491) for more info.
+
+
+
+For more information, see the docs for [`useActionState`](/reference/react/useActionState).
+
+### `