Skip to content

Sync with react.dev @ 91614a51 #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 72 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
6a35e13
Update react-19-upgrade-guide.md
sophiebits Dec 2, 2024
4bae717
Fix typo in react-19-upgrade-guide.md
sophiebits Dec 2, 2024
fd8b1e0
Update React v19 blog post for stable release (#7321)
rickhanlonii Dec 5, 2024
4673a05
Merge v19 docs to main (#7322)
rickhanlonii Dec 5, 2024
d6f3659
update version label
rickhanlonii Dec 5, 2024
d2536c0
fix vv19
rickhanlonii Dec 5, 2024
8235ae9
Fix types install instructions in 19 upgrade guide
eps1lon Dec 5, 2024
4d7cc91
Update Versions page (#7324)
rickhanlonii Dec 5, 2024
ebedc89
fix links to prerender docs (#7323)
mayank99 Dec 5, 2024
acda167
Add compiler beta release to Version changelog
rickhanlonii Dec 5, 2024
69edd84
fixed typo in yarn add command (#7326)
JakeSaterlay Dec 5, 2024
3b02f82
Update React DevTools docs to reference RN DevTools (#7355)
huntie Dec 11, 2024
9fb491d
Fix troubleshooting links in startTransition reference (#7367)
jimmycallin Dec 16, 2024
51864f6
(fix): mismatch href bug (#7368)
ahm3tozenir Dec 16, 2024
bc93f05
Fix stylesheet precedence example (#7235)
EricCote Dec 16, 2024
07eca83
Fix intro of prerenderToNodeStream (#7356)
smikitky Dec 16, 2024
c92bad2
chore: several major typo fixes (#7362)
coalio Dec 16, 2024
d3bd0f9
Update act.md (#7363)
huiliangShen Dec 16, 2024
31456db
chore: correct typo in useTransition docs (#7366)
AminDannak Dec 16, 2024
d4d1683
chore: fix a typo in startTransition docs (#7361)
AminDannak Dec 16, 2024
04ba43c
fix: add link to prop-type codemod (#7344)
renbaoshuo Dec 16, 2024
4349dd5
fix: anchor (#7343)
Jealh-h Dec 16, 2024
d3cde8f
Fix "won't break between majors" (#7357)
smikitky Dec 16, 2024
37e1ce9
Add React Summit 2025 to conferences.md; move past conferences to the…
McFrid Dec 16, 2024
4b5ce91
Add missing react-error-boundary dependency (#7353)
acusti Dec 16, 2024
0805613
fix broken link in use server (#7351)
simon300000 Dec 16, 2024
a4b6074
fix: page does not exist (#7348)
nusr Dec 16, 2024
807e7fa
Mention that uncontrolled form elements are reset by form actions (#7…
jeremy-deutsch Dec 16, 2024
0f8bd80
Code example mistake in useMemo page (#7335)
JZZICK Dec 16, 2024
3558095
docs: include React 19 blog post in sidebarBlog.json (#7331)
slorber Dec 16, 2024
93a03f1
docs: Fix broken link to next.js Suspense docs (#7318)
ethshea Dec 16, 2024
204b3f1
Remove canary flag from useFormStatus (#7349)
smikitky Dec 16, 2024
8ac5531
Rename remaining "Server Actions" (#7352)
smikitky Dec 16, 2024
9985199
docs[compiler]: clarify React DevTools support for Compiler Badges in…
piotrski Dec 16, 2024
c37fdd3
Remove forwardref from useImperativeHandle docs (#7360)
SebassNoob Dec 16, 2024
e2bba41
docs: fix readme node version (#7316)
devwqc Dec 16, 2024
8a5526e
Update lauren (#7373)
poteto Dec 17, 2024
03e74dd
Add info about App.js 2025 conference (#7154)
piaskowyk Dec 18, 2024
8e41e32
Inline stylesheets are not Suspensey yet (#7378)
eps1lon Dec 19, 2024
1517494
refactor: remove unused useTransition import in App.js and update doc…
Rekl0w Dec 19, 2024
6ae99dd
Remove forwardRef references from useRef and Manipulating the DOM wit…
mattcarrollcode Dec 20, 2024
b1a249d
Fix React Native DevTools link (#7386)
rammba Dec 24, 2024
5e3e400
bot to notify for PRs (#7408)
rickhanlonii Jan 7, 2025
c0b6baf
Fix broken Next.js base path configuration link (#7419)
amarachiugwu Jan 9, 2025
7b4f948
fix: change overflow-x-scroll to overflow-x-auto in TerminalBlock com…
hichemfantar Jan 9, 2025
9c4bc28
Update server-functions.md (#7396)
Azzyxec Jan 9, 2025
9000e6e
Add React Universe Conf 2025 to list of conferences (#7421)
barbaramarkiewicz Jan 9, 2025
517c0fa
/errors: Empty args are not missing arguments (#6767)
eps1lon Jan 13, 2025
855ce23
Upgrade to React 19, Next 15.1 and enable React Compiler (#6996)
mattcarrollcode Jan 13, 2025
316230a
Update React compiler and install eslint plugin (#7428)
poteto Jan 13, 2025
ee8a829
Disallow `/index.html` in sandboxes (#7430)
eps1lon Jan 14, 2025
a2d4932
Update Conferences Lists for 2025 (#7406)
apherio Jan 15, 2025
b22cbc3
Update Dan Abramov's broken Twitter link to bsky.app across multiple …
hichemfantar Jan 15, 2025
ee361b5
Update React Paris conference year to 2025 (#7439)
mikedidomizio Jan 21, 2025
e88e3d0
React Native Connection is back in 2025 (#7311)
viteinfinite Jan 21, 2025
b03017a
fix typo (#7440)
slavgetov Jan 21, 2025
c140d2c
Update conferences.md for CityJS Athens and London Events (#7425)
arismarko Jan 22, 2025
7cdbed0
Mention startTransition in useActionState docs (#7448)
sophiebits Jan 24, 2025
07f13ab
[ci] Add workflow to label PRs from core team (#7451)
poteto Jan 24, 2025
2f24839
[ci] Specify is_remote input to maintainer check workflow (#7453)
poteto Jan 24, 2025
a5aad0d
[ci] Update discord notification bot to use remote workflow (#7455)
poteto Jan 24, 2025
4d44167
import missing useState in the useEffect markdown file (#7457)
SruthiKrish19 Jan 27, 2025
066b6c1
bumped up the versions of docsearch packages (#7458)
phanendraguptha Jan 27, 2025
9001bc6
docs: Correct var reference in prerender example (#7434)
rschristian Jan 27, 2025
305db5f
Capitalized Suspense in a few files (#7449)
renatodellosso Jan 27, 2025
ef705c7
Update Eli's github username on the team page (#7460)
elicwhite Jan 27, 2025
3bb7a4e
Team page updates (#7438)
rickhanlonii Jan 27, 2025
0eb0f88
feat: migrate React.dev to the App Router (#7437)
feedthejim Feb 1, 2025
af0358f
Revert "feat: migrate React.dev to the App Router (#7437)" (#7466)
gaearon Feb 1, 2025
6fc98ff
Fix Vite URLs (#7462)
karlhorky Feb 2, 2025
91614a5
Clarify security updates in versioning-policy.md (#7485)
sophiebits Feb 9, 2025
a26aa41
Merge branch 'main' of https://github.com/reactjs/react.dev into sync…
react-translations-bot Feb 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -2,11 +2,13 @@
"root": true,
"extends": "next/core-web-vitals",
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"plugins": ["@typescript-eslint", "eslint-plugin-react-compiler"],
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["error", { "varsIgnorePattern": "^_" }],
"react-hooks/exhaustive-deps": "error"
"@typescript-eslint/no-unused-vars": ["error", {"varsIgnorePattern": "^_"}],
"react-hooks/exhaustive-deps": "error",
"react/no-unknown-property": ["error", {"ignore": ["meta"]}],
"react-compiler/react-compiler": "error"
},
"env": {
"node": true,
28 changes: 28 additions & 0 deletions .github/workflows/discord_notify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Discord Notify

on:
pull_request_target:
types: [labeled]

jobs:
check_maintainer:
uses: facebook/react/.github/workflows/shared_check_maintainer.yml@main
with:
actor: ${{ github.event.pull_request.user.login }}
is_remote: true

notify:
if: ${{ needs.check_maintainer.outputs.is_core_team == 'true' }}
needs: check_maintainer
runs-on: ubuntu-latest
steps:
- name: Discord Webhook Action
uses: tsickert/[email protected]
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
embed-author-name: ${{ github.event.pull_request.user.login }}
embed-author-url: ${{ github.event.pull_request.user.html_url }}
embed-author-icon-url: ${{ github.event.pull_request.user.avatar_url }}
embed-title: '#${{ github.event.number }} (+${{github.event.pull_request.additions}} -${{github.event.pull_request.deletions}}): ${{ github.event.pull_request.title }}'
embed-description: ${{ github.event.pull_request.body }}
embed-url: ${{ github.event.pull_request.html_url }}
32 changes: 32 additions & 0 deletions .github/workflows/label_core_team_prs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Label Core Team PRs

on:
pull_request_target:

env:
TZ: /usr/share/zoneinfo/America/Los_Angeles
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1

jobs:
check_maintainer:
uses: facebook/react/.github/workflows/shared_check_maintainer.yml@main
with:
actor: ${{ github.event.pull_request.user.login }}
is_remote: true

label:
if: ${{ needs.check_maintainer.outputs.is_core_team == 'true' }}
runs-on: ubuntu-latest
needs: check_maintainer
steps:
- name: Label PR as React Core Team
uses: actions/github-script@v7
with:
script: |
github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: ${{ github.event.number }},
labels: ['React Core Team']
});
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ This repo contains the source code and documentation powering [mk.react.dev](htt
### Prerequisites

1. Git
1. Node: any 12.x version starting with v12.0.0 or greater
1. Node: any version starting with v16.8.0 or greater
1. Yarn: See [Yarn website for installation instructions](https://yarnpkg.com/lang/en/docs/install/)
1. A fork of the repo (for any contributions)
1. A clone of the [mk.react.dev repo](https://github.com/reactjs/mk.react.dev) on your local machine
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
@@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
4 changes: 1 addition & 3 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -9,10 +9,8 @@ const nextConfig = {
pageExtensions: ['jsx', 'js', 'ts', 'tsx', 'mdx', 'md'],
reactStrictMode: true,
experimental: {
// TODO: Remove after https://github.com/vercel/next.js/issues/49355 is fixed
appDir: false,
scrollRestoration: true,
legacyBrowsers: false,
reactCompiler: true,
},
env: {},
webpack: (config, {dev, isServer, ...options}) => {
24 changes: 13 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -18,27 +18,27 @@
"ci-check": "npm-run-all prettier:diff --parallel lint tsc lint-heading-ids rss",
"tsc": "tsc --noEmit",
"start": "next start",
"postinstall": "patch-package && (is-ci || husky install .husky)",
"postinstall": "is-ci || husky install .husky",
"check-all": "npm-run-all prettier lint:fix tsc rss",
"rss": "node scripts/generateRss.js"
},
"dependencies": {
"@codesandbox/sandpack-react": "2.13.5",
"@docsearch/css": "^3.6.1",
"@docsearch/react": "^3.6.1",
"@docsearch/css": "^3.8.3",
"@docsearch/react": "^3.8.3",
"@headlessui/react": "^1.7.0",
"@radix-ui/react-context-menu": "^2.1.5",
"body-scroll-lock": "^3.1.3",
"classnames": "^2.2.6",
"date-fns": "^2.16.1",
"debounce": "^1.2.1",
"github-slugger": "^1.3.0",
"next": "^13.4.1",
"next": "15.1.0",
"next-remote-watch": "^1.0.0",
"parse-numeric-range": "^1.2.0",
"react": "^0.0.0-experimental-16d053d59-20230506",
"react": "^19.0.0",
"react-collapsed": "4.0.4",
"react-dom": "^0.0.0-experimental-16d053d59-20230506",
"react-dom": "^19.0.0",
"remark-frontmatter": "^4.0.1",
"remark-gfm": "^3.0.1"
},
@@ -54,20 +54,22 @@
"@types/mdx-js__react": "^1.5.2",
"@types/node": "^14.6.4",
"@types/parse-numeric-range": "^0.0.1",
"@types/react": "^18.0.9",
"@types/react-dom": "^18.0.5",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2",
"asyncro": "^3.0.0",
"autoprefixer": "^10.4.2",
"babel-eslint": "10.x",
"babel-plugin-react-compiler": "19.0.0-beta-e552027-20250112",
"eslint": "7.x",
"eslint-config-next": "12.0.3",
"eslint-config-react-app": "^5.2.1",
"eslint-plugin-flowtype": "4.x",
"eslint-plugin-import": "2.x",
"eslint-plugin-jsx-a11y": "6.x",
"eslint-plugin-react": "7.x",
"eslint-plugin-react-compiler": "^19.0.0-beta-e552027-20250112",
"eslint-plugin-react-hooks": "^0.0.0-experimental-fabef7a6b-20221215",
"fs-extra": "^9.0.1",
"globby": "^11.0.1",
@@ -78,7 +80,6 @@
"mdast-util-to-string": "^1.1.0",
"metro-cache": "0.72.2",
"npm-run-all": "^4.1.5",
"patch-package": "^6.2.2",
"postcss": "^8.4.5",
"postcss-flexbugs-fixes": "4.2.1",
"postcss-preset-env": "^6.7.0",
@@ -94,7 +95,7 @@
"retext-smartypants": "^4.0.0",
"rss": "^1.2.2",
"tailwindcss": "^3.4.1",
"typescript": "^4.0.2",
"typescript": "^5.7.2",
"unist-util-visit": "^2.0.3",
"webpack-bundle-analyzer": "^4.5.0"
},
@@ -109,5 +110,6 @@
"lint-staged": {
"*.{js,ts,jsx,tsx,css}": "yarn prettier",
"src/**/*.md": "yarn fix-headings"
}
},
"packageManager": "[email protected]"
}
22 changes: 0 additions & 22 deletions patches/next+13.4.1.patch

This file was deleted.

16 changes: 0 additions & 16 deletions patches/next-remote-watch+1.0.0.patch

This file was deleted.

Binary file removed public/images/team/andrey-lunyov.jpg
Binary file not shown.
Binary file added public/images/team/hendrik.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/team/jordan.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/images/team/kathryn-middleton.jpg
Binary file not shown.
Binary file modified public/images/team/lauren.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/images/team/luna-wei.jpg
Binary file not shown.
Binary file added public/images/team/mike.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/images/team/noahlemen.jpg
Binary file not shown.
Binary file added public/images/team/pieter.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/images/team/sam.jpg
Binary file not shown.
Binary file removed public/images/team/sathya.jpg
Binary file not shown.
Binary file removed public/images/team/tianyu.jpg
Binary file not shown.
6 changes: 5 additions & 1 deletion src/components/ExternalLink.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import type {DetailedHTMLProps, AnchorHTMLAttributes} from 'react';

export function ExternalLink({
href,
target,
children,
...props
}: JSX.IntrinsicElements['a']) {
}: DetailedHTMLProps<
AnchorHTMLAttributes<HTMLAnchorElement>,
HTMLAnchorElement
>) {
return (
<a href={href} target={target ?? '_blank'} rel="noopener" {...props}>
{children}
3 changes: 2 additions & 1 deletion src/components/Icon/IconArrow.tsx
Original file line number Diff line number Diff line change
@@ -4,9 +4,10 @@

import {memo} from 'react';
import cn from 'classnames';
import type {SVGProps} from 'react';

export const IconArrow = memo<
JSX.IntrinsicElements['svg'] & {
SVGProps<SVGSVGElement> & {
/**
* The direction the arrow should point.
* `start` and `end` are relative to the current locale.
3 changes: 2 additions & 1 deletion src/components/Icon/IconArrowSmall.tsx
Original file line number Diff line number Diff line change
@@ -4,9 +4,10 @@

import {memo} from 'react';
import cn from 'classnames';
import type {SVGProps} from 'react';

export const IconArrowSmall = memo<
JSX.IntrinsicElements['svg'] & {
SVGProps<SVGSVGElement> & {
/**
* The direction the arrow should point.
* `start` and `end` are relative to the current locale.
5 changes: 2 additions & 3 deletions src/components/Icon/IconBsky.tsx
Original file line number Diff line number Diff line change
@@ -3,10 +3,9 @@
*/

import {memo} from 'react';
import type {SVGProps} from 'react';

export const IconBsky = memo<JSX.IntrinsicElements['svg']>(function IconBsky(
props
) {
export const IconBsky = memo<SVGProps<SVGSVGElement>>(function IconBsky(props) {
return (
<svg
aria-label="Bluesky"
3 changes: 2 additions & 1 deletion src/components/Icon/IconClose.tsx
Original file line number Diff line number Diff line change
@@ -3,8 +3,9 @@
*/

import {memo} from 'react';
import type {SVGProps} from 'react';

export const IconClose = memo<JSX.IntrinsicElements['svg']>(function IconClose(
export const IconClose = memo<SVGProps<SVGSVGElement>>(function IconClose(
props
) {
return (
3 changes: 2 additions & 1 deletion src/components/Icon/IconFacebookCircle.tsx
Original file line number Diff line number Diff line change
@@ -3,8 +3,9 @@
*/

import {memo} from 'react';
import type {SVGProps} from 'react';

export const IconFacebookCircle = memo<JSX.IntrinsicElements['svg']>(
export const IconFacebookCircle = memo<SVGProps<SVGSVGElement>>(
function IconFacebookCircle(props) {
return (
<svg
31 changes: 16 additions & 15 deletions src/components/Icon/IconGitHub.tsx
Original file line number Diff line number Diff line change
@@ -3,19 +3,20 @@
*/

import {memo} from 'react';
import type {SVGProps} from 'react';

export const IconGitHub = memo<JSX.IntrinsicElements['svg']>(
function IconGitHub(props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1.5em"
height="1.5em"
viewBox="0 -2 24 24"
fill="currentColor"
{...props}>
<path d="M10 0a10 10 0 0 0-3.16 19.49c.5.1.68-.22.68-.48l-.01-1.7c-2.78.6-3.37-1.34-3.37-1.34-.46-1.16-1.11-1.47-1.11-1.47-.9-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.9 1.52 2.34 1.08 2.91.83.1-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.94 0-1.1.39-1.99 1.03-2.69a3.6 3.6 0 0 1 .1-2.64s.84-.27 2.75 1.02a9.58 9.58 0 0 1 5 0c1.91-1.3 2.75-1.02 2.75-1.02.55 1.37.2 2.4.1 2.64.64.7 1.03 1.6 1.03 2.69 0 3.84-2.34 4.68-4.57 4.93.36.31.68.92.68 1.85l-.01 2.75c0 .26.18.58.69.48A10 10 0 0 0 10 0"></path>
</svg>
);
}
);
export const IconGitHub = memo<SVGProps<SVGSVGElement>>(function IconGitHub(
props
) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1.5em"
height="1.5em"
viewBox="0 -2 24 24"
fill="currentColor"
{...props}>
<path d="M10 0a10 10 0 0 0-3.16 19.49c.5.1.68-.22.68-.48l-.01-1.7c-2.78.6-3.37-1.34-3.37-1.34-.46-1.16-1.11-1.47-1.11-1.47-.9-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.9 1.52 2.34 1.08 2.91.83.1-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.94 0-1.1.39-1.99 1.03-2.69a3.6 3.6 0 0 1 .1-2.64s.84-.27 2.75 1.02a9.58 9.58 0 0 1 5 0c1.91-1.3 2.75-1.02 2.75-1.02.55 1.37.2 2.4.1 2.64.64.7 1.03 1.6 1.03 2.69 0 3.84-2.34 4.68-4.57 4.93.36.31.68.92.68 1.85l-.01 2.75c0 .26.18.58.69.48A10 10 0 0 0 10 0"></path>
</svg>
);
});
3 changes: 2 additions & 1 deletion src/components/Icon/IconHamburger.tsx
Original file line number Diff line number Diff line change
@@ -3,8 +3,9 @@
*/

import {memo} from 'react';
import type {SVGProps} from 'react';

export const IconHamburger = memo<JSX.IntrinsicElements['svg']>(
export const IconHamburger = memo<SVGProps<SVGSVGElement>>(
function IconHamburger(props) {
return (
<svg
3 changes: 2 additions & 1 deletion src/components/Icon/IconInstagram.tsx
Original file line number Diff line number Diff line change
@@ -3,8 +3,9 @@
*/

import {memo} from 'react';
import type {SVGProps} from 'react';

export const IconInstagram = memo<JSX.IntrinsicElements['svg']>(
export const IconInstagram = memo<SVGProps<SVGSVGElement>>(
function IconInstagram(props) {
return (
<svg
5 changes: 2 additions & 3 deletions src/components/Icon/IconLink.tsx
Original file line number Diff line number Diff line change
@@ -3,10 +3,9 @@
*/

import {memo} from 'react';
import type {SVGProps} from 'react';

export const IconLink = memo<JSX.IntrinsicElements['svg']>(function IconLink(
props
) {
export const IconLink = memo<SVGProps<SVGSVGElement>>(function IconLink(props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
45 changes: 23 additions & 22 deletions src/components/Icon/IconNewPage.tsx
Original file line number Diff line number Diff line change
@@ -3,26 +3,27 @@
*/

import {memo} from 'react';
import type {SVGProps} from 'react';

export const IconNewPage = memo<JSX.IntrinsicElements['svg']>(
function IconNewPage(props) {
return (
<svg
width="1em"
height="1em"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}>
<path
d="M20.5001 2H15.5001C15.3675 2 15.2403 2.05268 15.1465 2.14645C15.0528 2.24021 15.0001 2.36739 15.0001 2.5V3.5C15.0001 3.63261 15.0528 3.75979 15.1465 3.85355C15.2403 3.94732 15.3675 4 15.5001 4H18.5901L7.6501 14.94C7.60323 14.9865 7.56604 15.0418 7.54065 15.1027C7.51527 15.1636 7.5022 15.229 7.5022 15.295C7.5022 15.361 7.51527 15.4264 7.54065 15.4873C7.56604 15.5482 7.60323 15.6035 7.6501 15.65L8.3501 16.35C8.39658 16.3969 8.45188 16.4341 8.51281 16.4594C8.57374 16.4848 8.63909 16.4979 8.7051 16.4979C8.7711 16.4979 8.83646 16.4848 8.89738 16.4594C8.95831 16.4341 9.01362 16.3969 9.0601 16.35L20.0001 5.41V8.5C20.0001 8.63261 20.0528 8.75979 20.1465 8.85355C20.2403 8.94732 20.3675 9 20.5001 9H21.5001C21.6327 9 21.7599 8.94732 21.8537 8.85355C21.9474 8.75979 22.0001 8.63261 22.0001 8.5V3.5C22.0001 3.10218 21.8421 2.72064 21.5608 2.43934C21.2795 2.15804 20.8979 2 20.5001 2V2Z"
fill="currentColor"
/>
<path
d="M21.5 13H20.5C20.3674 13 20.2402 13.0527 20.1464 13.1464C20.0527 13.2402 20 13.3674 20 13.5V20H4V4H10.5C10.6326 4 10.7598 3.94732 10.8536 3.85355C10.9473 3.75979 11 3.63261 11 3.5V2.5C11 2.36739 10.9473 2.24021 10.8536 2.14645C10.7598 2.05268 10.6326 2 10.5 2H3.5C3.10218 2 2.72064 2.15804 2.43934 2.43934C2.15804 2.72064 2 3.10218 2 3.5V20.5C2 20.8978 2.15804 21.2794 2.43934 21.5607C2.72064 21.842 3.10218 22 3.5 22H20.5C20.8978 22 21.2794 21.842 21.5607 21.5607C21.842 21.2794 22 20.8978 22 20.5V13.5C22 13.3674 21.9473 13.2402 21.8536 13.1464C21.7598 13.0527 21.6326 13 21.5 13Z"
fill="currentColor"
/>
</svg>
);
}
);
export const IconNewPage = memo<SVGProps<SVGSVGElement>>(function IconNewPage(
props
) {
return (
<svg
width="1em"
height="1em"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}>
<path
d="M20.5001 2H15.5001C15.3675 2 15.2403 2.05268 15.1465 2.14645C15.0528 2.24021 15.0001 2.36739 15.0001 2.5V3.5C15.0001 3.63261 15.0528 3.75979 15.1465 3.85355C15.2403 3.94732 15.3675 4 15.5001 4H18.5901L7.6501 14.94C7.60323 14.9865 7.56604 15.0418 7.54065 15.1027C7.51527 15.1636 7.5022 15.229 7.5022 15.295C7.5022 15.361 7.51527 15.4264 7.54065 15.4873C7.56604 15.5482 7.60323 15.6035 7.6501 15.65L8.3501 16.35C8.39658 16.3969 8.45188 16.4341 8.51281 16.4594C8.57374 16.4848 8.63909 16.4979 8.7051 16.4979C8.7711 16.4979 8.83646 16.4848 8.89738 16.4594C8.95831 16.4341 9.01362 16.3969 9.0601 16.35L20.0001 5.41V8.5C20.0001 8.63261 20.0528 8.75979 20.1465 8.85355C20.2403 8.94732 20.3675 9 20.5001 9H21.5001C21.6327 9 21.7599 8.94732 21.8537 8.85355C21.9474 8.75979 22.0001 8.63261 22.0001 8.5V3.5C22.0001 3.10218 21.8421 2.72064 21.5608 2.43934C21.2795 2.15804 20.8979 2 20.5001 2V2Z"
fill="currentColor"
/>
<path
d="M21.5 13H20.5C20.3674 13 20.2402 13.0527 20.1464 13.1464C20.0527 13.2402 20 13.3674 20 13.5V20H4V4H10.5C10.6326 4 10.7598 3.94732 10.8536 3.85355C10.9473 3.75979 11 3.63261 11 3.5V2.5C11 2.36739 10.9473 2.24021 10.8536 2.14645C10.7598 2.05268 10.6326 2 10.5 2H3.5C3.10218 2 2.72064 2.15804 2.43934 2.43934C2.15804 2.72064 2 3.10218 2 3.5V20.5C2 20.8978 2.15804 21.2794 2.43934 21.5607C2.72064 21.842 3.10218 22 3.5 22H20.5C20.8978 22 21.2794 21.842 21.5607 21.5607C21.842 21.2794 22 20.8978 22 20.5V13.5C22 13.3674 21.9473 13.2402 21.8536 13.1464C21.7598 13.0527 21.6326 13 21.5 13Z"
fill="currentColor"
/>
</svg>
);
});
32 changes: 32 additions & 0 deletions src/components/Icon/IconRocket.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*/

import {memo} from 'react';

export const IconRocket = memo<
JSX.IntrinsicElements['svg'] & {title?: string; size?: 's' | 'md'}
>(function IconRocket({className, size = 'md'}) {
return (
<svg
className={className}
aria-hidden="true"
width={size === 's' ? '1.2em' : '1.5em'}
height={size === 's' ? '1.2em' : '1.5em'}
fill="currentColor"
version="1.1"
viewBox="0 0 1200 1200"
xmlns="http://www.w3.org/2000/svg">
<g fillRule="evenodd">
<path d="m911.8 288.2c65.051 65.051 65.051 170.6 0 235.65-65.051 65.051-170.6 65.051-235.65 0-65.051-65.051-65.051-170.6 0-235.65 65.051-65.051 170.6-65.051 235.65 0zm-53.051 53.051c-35.75-35.801-93.801-35.801-129.55 0-35.801 35.75-35.801 93.801 0 129.55 35.75 35.801 93.801 35.801 129.55 0 35.801-35.75 35.801-93.801 0-129.55z" />
<path d="m1122.2 103.4s96.648 328.1-194.4 619.1c-130.75 130.75-303.25 226.75-440.75 250.5-12.102 2.0508-24.449-1.8984-33.102-10.648l-231.55-234.8c-8.6484-8.8008-12.449-21.301-10.102-33.398 26.102-135.4 135.45-292.2 265.2-421.95 291-291.05 619.1-194.4 619.1-194.4 12.352 3.6016 22 13.25 25.602 25.602zm-67.5 41.898c-70.898-12.898-308.6-35.602-524.15 179.9-112.35 112.35-210.4 245.4-240.4 364.25 0 0 203.05 205.9 203.1 205.9 121.75-26.852 268.4-112.75 381.55-225.9 215.5-215.55 192.8-453.25 179.9-524.15z" />
<path d="m151.55 543.85 124 20.648c20.398 3.3984 34.25 22.75 30.801 43.148-3.3984 20.449-22.699 34.25-43.148 30.852l-144.35-24.051c-22.148-3.6992-40.699-18.949-48.602-40-7.9492-21.051-4.0508-44.699 10.199-62.148l122.85-150.15c15.051-18.398 36.898-30 60.551-32.148l179.55-16.301c20.602-1.8984 38.852 13.352 40.75 33.949 1.8516 20.602-13.352 38.852-33.949 40.75l-179.55 16.301c-3.6484 0.35156-7 2.1016-9.3008 4.9492z" />
<path d="m656.15 1048.4 134.2-109.8c2.8516-2.3008 4.6016-5.6484 4.9492-9.3008l16.301-179.55c1.8984-20.602 20.148-35.801 40.75-33.949 20.602 1.8984 35.852 20.148 33.949 40.75l-16.301 179.55c-2.1484 23.648-13.75 45.5-32.148 60.551l-150.15 122.85c-17.449 14.25-41.102 18.148-62.148 10.199-21.051-7.8984-36.301-26.449-40-48.602l-29.25-175.7c-3.3984-20.398 10.398-39.75 30.801-43.148 20.449-3.3984 39.75 10.449 43.148 30.852l25.898 155.3z" />
<path d="m310.9 560.4c-14.648-14.648-14.648-38.398 0-53.051 14.648-14.648 38.398-14.648 53.051 0l328.7 328.7c14.648 14.648 14.648 38.398 0 53.051-14.648 14.648-38.398 14.648-53.051 0z" />
<path d="m383.95 982.15c14.648-14.602 38.398-14.602 53.051 0 14.602 14.648 14.602 38.398 0 53.051l-91.352 91.301c-14.602 14.648-38.398 14.648-53 0-14.648-14.602-14.648-38.398 0-53z" />
<path d="m237.85 909.1c14.648-14.602 38.398-14.602 53.051 0 14.602 14.648 14.602 38.398 0 53.051l-127.85 127.85c-14.648 14.648-38.398 14.648-53.051 0-14.648-14.648-14.648-38.398 0-53.051z" />
<path d="m164.8 763c14.648-14.602 38.398-14.602 53.051 0 14.602 14.648 14.602 38.398 0 53.051l-91.352 91.301c-14.602 14.648-38.398 14.648-53 0-14.648-14.602-14.648-38.398 0-53z" />
</g>
</svg>
);
});
5 changes: 2 additions & 3 deletions src/components/Icon/IconRss.tsx
Original file line number Diff line number Diff line change
@@ -3,10 +3,9 @@
*/

import {memo} from 'react';
import type {SVGProps} from 'react';

export const IconRss = memo<JSX.IntrinsicElements['svg']>(function IconRss(
props
) {
export const IconRss = memo<SVGProps<SVGSVGElement>>(function IconRss(props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
33 changes: 17 additions & 16 deletions src/components/Icon/IconSearch.tsx
Original file line number Diff line number Diff line change
@@ -3,20 +3,21 @@
*/

import {memo} from 'react';
import type {SVGProps} from 'react';

export const IconSearch = memo<JSX.IntrinsicElements['svg']>(
function IconSearch(props) {
return (
<svg width="1em" height="1em" viewBox="0 0 20 20" {...props}>
<path
d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"
stroke="currentColor"
fill="none"
strokeWidth="2"
fillRule="evenodd"
strokeLinecap="round"
strokeLinejoin="round"></path>
</svg>
);
}
);
export const IconSearch = memo<SVGProps<SVGSVGElement>>(function IconSearch(
props
) {
return (
<svg width="1em" height="1em" viewBox="0 0 20 20" {...props}>
<path
d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"
stroke="currentColor"
fill="none"
strokeWidth="2"
fillRule="evenodd"
strokeLinecap="round"
strokeLinejoin="round"></path>
</svg>
);
});
37 changes: 19 additions & 18 deletions src/components/Icon/IconThreads.tsx
Original file line number Diff line number Diff line change
@@ -3,22 +3,23 @@
*/

import {memo} from 'react';
import type {SVGProps} from 'react';

export const IconThreads = memo<JSX.IntrinsicElements['svg']>(
function IconThreads(props) {
return (
<svg
aria-label="Threads"
viewBox="0 0 192 192"
height="1.40em"
width="1.40em"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
{...props}>
<path
className="x19hqcy"
d="M141.537 88.9883C140.71 88.5919 139.87 88.2104 139.019 87.8451C137.537 60.5382 122.616 44.905 97.5619 44.745C97.4484 44.7443 97.3355 44.7443 97.222 44.7443C82.2364 44.7443 69.7731 51.1409 62.102 62.7807L75.881 72.2328C81.6116 63.5383 90.6052 61.6848 97.2286 61.6848C97.3051 61.6848 97.3819 61.6848 97.4576 61.6855C105.707 61.7381 111.932 64.1366 115.961 68.814C118.893 72.2193 120.854 76.925 121.825 82.8638C114.511 81.6207 106.601 81.2385 98.145 81.7233C74.3247 83.0954 59.0111 96.9879 60.0396 116.292C60.5615 126.084 65.4397 134.508 73.775 140.011C80.8224 144.663 89.899 146.938 99.3323 146.423C111.79 145.74 121.563 140.987 128.381 132.296C133.559 125.696 136.834 117.143 138.28 106.366C144.217 109.949 148.617 114.664 151.047 120.332C155.179 129.967 155.42 145.8 142.501 158.708C131.182 170.016 117.576 174.908 97.0135 175.059C74.2042 174.89 56.9538 167.575 45.7381 153.317C35.2355 139.966 29.8077 120.682 29.6052 96C29.8077 71.3178 35.2355 52.0336 45.7381 38.6827C56.9538 24.4249 74.2039 17.11 97.0132 16.9405C119.988 17.1113 137.539 24.4614 149.184 38.788C154.894 45.8136 159.199 54.6488 162.037 64.9503L178.184 60.6422C174.744 47.9622 169.331 37.0357 161.965 27.974C147.036 9.60668 125.202 0.195148 97.0695 0H96.9569C68.8816 0.19447 47.2921 9.6418 32.7883 28.0793C19.8819 44.4864 13.2244 67.3157 13.0007 95.9325L13 96L13.0007 96.0675C13.2244 124.684 19.8819 147.514 32.7883 163.921C47.2921 182.358 68.8816 191.806 96.9569 192H97.0695C122.03 191.827 139.624 185.292 154.118 170.811C173.081 151.866 172.51 128.119 166.26 113.541C161.776 103.087 153.227 94.5962 141.537 88.9883ZM98.4405 129.507C88.0005 130.095 77.1544 125.409 76.6196 115.372C76.2232 107.93 81.9158 99.626 99.0812 98.6368C101.047 98.5234 102.976 98.468 104.871 98.468C111.106 98.468 116.939 99.0737 122.242 100.233C120.264 124.935 108.662 128.946 98.4405 129.507Z"></path>
</svg>
);
}
);
export const IconThreads = memo<SVGProps<SVGSVGElement>>(function IconThreads(
props
) {
return (
<svg
aria-label="Threads"
viewBox="0 0 192 192"
height="1.40em"
width="1.40em"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
{...props}>
<path
className="x19hqcy"
d="M141.537 88.9883C140.71 88.5919 139.87 88.2104 139.019 87.8451C137.537 60.5382 122.616 44.905 97.5619 44.745C97.4484 44.7443 97.3355 44.7443 97.222 44.7443C82.2364 44.7443 69.7731 51.1409 62.102 62.7807L75.881 72.2328C81.6116 63.5383 90.6052 61.6848 97.2286 61.6848C97.3051 61.6848 97.3819 61.6848 97.4576 61.6855C105.707 61.7381 111.932 64.1366 115.961 68.814C118.893 72.2193 120.854 76.925 121.825 82.8638C114.511 81.6207 106.601 81.2385 98.145 81.7233C74.3247 83.0954 59.0111 96.9879 60.0396 116.292C60.5615 126.084 65.4397 134.508 73.775 140.011C80.8224 144.663 89.899 146.938 99.3323 146.423C111.79 145.74 121.563 140.987 128.381 132.296C133.559 125.696 136.834 117.143 138.28 106.366C144.217 109.949 148.617 114.664 151.047 120.332C155.179 129.967 155.42 145.8 142.501 158.708C131.182 170.016 117.576 174.908 97.0135 175.059C74.2042 174.89 56.9538 167.575 45.7381 153.317C35.2355 139.966 29.8077 120.682 29.6052 96C29.8077 71.3178 35.2355 52.0336 45.7381 38.6827C56.9538 24.4249 74.2039 17.11 97.0132 16.9405C119.988 17.1113 137.539 24.4614 149.184 38.788C154.894 45.8136 159.199 54.6488 162.037 64.9503L178.184 60.6422C174.744 47.9622 169.331 37.0357 161.965 27.974C147.036 9.60668 125.202 0.195148 97.0695 0H96.9569C68.8816 0.19447 47.2921 9.6418 32.7883 28.0793C19.8819 44.4864 13.2244 67.3157 13.0007 95.9325L13 96L13.0007 96.0675C13.2244 124.684 19.8819 147.514 32.7883 163.921C47.2921 182.358 68.8816 191.806 96.9569 192H97.0695C122.03 191.827 139.624 185.292 154.118 170.811C173.081 151.866 172.51 128.119 166.26 113.541C161.776 103.087 153.227 94.5962 141.537 88.9883ZM98.4405 129.507C88.0005 130.095 77.1544 125.409 76.6196 115.372C76.2232 107.93 81.9158 99.626 99.0812 98.6368C101.047 98.5234 102.976 98.468 104.871 98.468C111.106 98.468 116.939 99.0737 122.242 100.233C120.264 124.935 108.662 128.946 98.4405 129.507Z"></path>
</svg>
);
});
33 changes: 17 additions & 16 deletions src/components/Icon/IconTwitter.tsx
Original file line number Diff line number Diff line change
@@ -3,20 +3,21 @@
*/

import {memo} from 'react';
import type {SVGProps} from 'react';

export const IconTwitter = memo<JSX.IntrinsicElements['svg']>(
function IconTwitter(props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
height="1.30em"
width="1.30em"
fill="currentColor"
{...props}>
<path fill="none" d="M0 0h24v24H0z" />
<path d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z" />
</svg>
);
}
);
export const IconTwitter = memo<SVGProps<SVGSVGElement>>(function IconTwitter(
props
) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
height="1.30em"
width="1.30em"
fill="currentColor"
{...props}>
<path fill="none" d="M0 0h24v24H0z" />
<path d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z" />
</svg>
);
});
15 changes: 11 additions & 4 deletions src/components/Layout/Sidebar/SidebarLink.tsx
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ interface SidebarLinkProps {
selected?: boolean;
title: string;
level: number;
canary?: boolean;
version?: 'canary' | 'major';
icon?: React.ReactNode;
isExpanded?: boolean;
hideArrow?: boolean;
@@ -27,7 +27,7 @@ export function SidebarLink({
href,
selected = false,
title,
canary,
version,
level,
isExpanded,
hideArrow,
@@ -75,10 +75,17 @@ export function SidebarLink({
{/* This here needs to be refactored ofc */}
<div>
{title}{' '}
{canary && (
{version === 'major' && (
<span
title="- This feature is available in React 19 beta and the React canary channel"
className={`text-xs px-1 ms-1 rounded bg-gray-10 dark:bg-gray-40 dark:bg-opacity-20 text-gray-40 dark:text-gray-40`}>
React 19
</span>
)}
{version === 'canary' && (
<IconCanary
title=" - This feature is available in the latest Canary"
className="ms-2 text-gray-30 dark:text-gray-60 inline-block w-4 h-4 align-[-3px]"
className="ms-1 text-gray-30 dark:text-gray-60 inline-block w-3.5 h-3.5 align-[-3px]"
/>
)}
</div>
7 changes: 4 additions & 3 deletions src/components/Layout/Sidebar/SidebarRouteTree.tsx
Original file line number Diff line number Diff line change
@@ -38,6 +38,7 @@ function CollapseWrapper({
// Disable pointer events while animating.
const isExpandedRef = useRef(isExpanded);
if (typeof window !== 'undefined') {
// eslint-disable-next-line react-compiler/react-compiler
// eslint-disable-next-line react-hooks/rules-of-hooks
useLayoutEffect(() => {
const wasExpanded = isExpandedRef.current;
@@ -87,7 +88,7 @@ export function SidebarRouteTree({
path,
title,
routes,
canary,
version,
heading,
hasSectionHeader,
sectionHeader,
@@ -121,7 +122,7 @@ export function SidebarRouteTree({
selected={selected}
level={level}
title={title}
canary={canary}
version={version}
isExpanded={isExpanded}
hideArrow={isForceExpanded}
/>
@@ -145,7 +146,7 @@ export function SidebarRouteTree({
selected={selected}
level={level}
title={title}
canary={canary}
version={version}
/>
</li>
);
4 changes: 2 additions & 2 deletions src/components/Layout/getRouteMeta.tsx
Original file line number Diff line number Diff line change
@@ -19,8 +19,8 @@ export type RouteTag =
export interface RouteItem {
/** Page title (for the sidebar) */
title: string;
/** Optional canary flag for heading */
canary?: boolean;
/** Optional version flag for heading */
version?: 'canary' | 'major';
/** Optional page description for heading */
description?: string;
/* Additional meta info for page tagging */
3 changes: 2 additions & 1 deletion src/components/Logo.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import type {SVGProps} from 'react';

export function Logo(props: JSX.IntrinsicElements['svg']) {
export function Logo(props: SVGProps<SVGSVGElement>) {
return (
<svg
width="100%"
5 changes: 4 additions & 1 deletion src/components/MDX/Challenges/Challenges.tsx
Original file line number Diff line number Diff line change
@@ -40,7 +40,10 @@ const parseChallengeContents = (
let challenge: Partial<ChallengeContents> = {};
let content: React.ReactElement[] = [];
Children.forEach(children, (child) => {
const {props, type} = child;
const {props, type} = child as React.ReactElement<{
children?: string;
id?: string;
}>;
switch ((type as any).mdxName) {
case 'Solution': {
challenge.solution = child;
4 changes: 2 additions & 2 deletions src/components/MDX/CodeBlock/CodeBlock.tsx
Original file line number Diff line number Diff line change
@@ -289,7 +289,7 @@ function getSyntaxHighlight(theme: any): HighlightStyle {

function getLineDecorators(
code: string,
meta: string
meta?: string
): Array<{
line: number;
className: string;
@@ -309,7 +309,7 @@ function getLineDecorators(

function getInlineDecorators(
code: string,
meta: string
meta?: string
): Array<{
step: number;
line: number;
9 changes: 8 additions & 1 deletion src/components/MDX/CodeDiagram.tsx
Original file line number Diff line number Diff line change
@@ -17,7 +17,14 @@ export function CodeDiagram({children, flip = false}: CodeDiagramProps) {
});
const content = Children.toArray(children).map((child: any) => {
if (child.type?.mdxName === 'pre') {
return <CodeBlock {...child.props} noMargin={true} noMarkers={true} />;
return (
<CodeBlock
key={child.key}
{...child.props}
noMargin={true}
noMarkers={true}
/>
);
} else if (child.type === 'img') {
return null;
} else {
6 changes: 4 additions & 2 deletions src/components/MDX/ConsoleBlock.tsx
Original file line number Diff line number Diff line change
@@ -38,7 +38,8 @@ export function ConsoleBlock({level = 'error', children}: ConsoleBlockProps) {
if (typeof children === 'string') {
message = children;
} else if (isValidElement(children)) {
message = children.props.children;
message = (children as React.ReactElement<{children?: React.ReactNode}>)
.props.children;
}

return (
@@ -113,7 +114,8 @@ export function ConsoleLogLine({children, level}: ConsoleBlockProps) {
if (typeof children === 'string') {
message = children;
} else if (isValidElement(children)) {
message = children.props.children;
message = (children as React.ReactElement<{children?: React.ReactNode}>)
.props.children;
} else if (Array.isArray(children)) {
message = children.reduce((result, child) => {
if (typeof child === 'string') {
2 changes: 1 addition & 1 deletion src/components/MDX/ErrorDecoder.tsx
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ function replaceArgs(
return msg.replace(/%s/g, function () {
const arg = argList[argIdx++];
// arg can be an empty string: ?args[0]=&args[1]=count
return arg === undefined || arg === '' ? replacer : arg;
return arg === undefined ? replacer : arg;
});
}

34 changes: 30 additions & 4 deletions src/components/MDX/ExpandableCallout.tsx
Original file line number Diff line number Diff line change
@@ -8,8 +8,16 @@ import {IconNote} from '../Icon/IconNote';
import {IconWarning} from '../Icon/IconWarning';
import {IconPitfall} from '../Icon/IconPitfall';
import {IconCanary} from '../Icon/IconCanary';
import {IconRocket} from '../Icon/IconRocket';

type CalloutVariants = 'deprecated' | 'pitfall' | 'note' | 'wip' | 'canary';
type CalloutVariants =
| 'deprecated'
| 'pitfall'
| 'note'
| 'wip'
| 'canary'
| 'major'
| 'rsc';

interface ExpandableCalloutProps {
children: React.ReactNode;
@@ -59,6 +67,22 @@ const variantMap = {
overlayGradient:
'linear-gradient(rgba(249, 247, 243, 0), rgba(249, 247, 243, 1)',
},
major: {
title: 'React 19',
Icon: IconRocket,
containerClasses: 'bg-blue-10 dark:bg-blue-60 dark:bg-opacity-20',
textColor: 'text-blue-50 dark:text-blue-40',
overlayGradient:
'linear-gradient(rgba(249, 247, 243, 0), rgba(249, 247, 243, 1)',
},
rsc: {
title: 'React Server Components',
Icon: null,
containerClasses: 'bg-blue-10 dark:bg-blue-60 dark:bg-opacity-20',
textColor: 'text-blue-50 dark:text-blue-40',
overlayGradient:
'linear-gradient(rgba(249, 247, 243, 0), rgba(249, 247, 243, 1)',
},
};

function ExpandableCallout({children, type = 'note'}: ExpandableCalloutProps) {
@@ -72,9 +96,11 @@ function ExpandableCallout({children, type = 'note'}: ExpandableCalloutProps) {
variant.containerClasses
)}>
<h3 className={cn('text-2xl font-display font-bold', variant.textColor)}>
<variant.Icon
className={cn('inline me-3 mb-1 text-lg', variant.textColor)}
/>
{variant.Icon && (
<variant.Icon
className={cn('inline me-2 mb-1 text-lg', variant.textColor)}
/>
)}
{variant.title}
</h3>
<div className="relative">
3 changes: 2 additions & 1 deletion src/components/MDX/InlineCode.tsx
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
*/

import cn from 'classnames';
import type {HTMLAttributes} from 'react';

interface InlineCodeProps {
isLink?: boolean;
@@ -11,7 +12,7 @@ interface InlineCodeProps {
function InlineCode({
isLink,
...props
}: JSX.IntrinsicElements['code'] & InlineCodeProps) {
}: HTMLAttributes<HTMLElement> & InlineCodeProps) {
return (
<code
dir="ltr" // This is needed to prevent the code from inheriting the RTL direction of <html> in case of RTL languages to avoid like `()console.log` to be rendered as `console.log()`
48 changes: 39 additions & 9 deletions src/components/MDX/MDXComponents.tsx
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
import {Children, useContext, useMemo} from 'react';
import * as React from 'react';
import cn from 'classnames';
import type {HTMLAttributes} from 'react';

import CodeBlock from './CodeBlock';
import {CodeDiagram} from './CodeDiagram';
@@ -59,21 +60,21 @@ function CodeStep({children, step}: {children: any; step: number}) {
);
}

const P = (p: JSX.IntrinsicElements['p']) => (
const P = (p: HTMLAttributes<HTMLParagraphElement>) => (
<p className="whitespace-pre-wrap my-4" {...p} />
);

const Strong = (strong: JSX.IntrinsicElements['strong']) => (
const Strong = (strong: HTMLAttributes<HTMLElement>) => (
<strong className="font-bold" {...strong} />
);

const OL = (p: JSX.IntrinsicElements['ol']) => (
const OL = (p: HTMLAttributes<HTMLOListElement>) => (
<ol className="ms-6 my-3 list-decimal" {...p} />
);
const LI = (p: JSX.IntrinsicElements['li']) => (
const LI = (p: HTMLAttributes<HTMLLIElement>) => (
<li className="leading-relaxed mb-1" {...p} />
);
const UL = (p: JSX.IntrinsicElements['ul']) => (
const UL = (p: HTMLAttributes<HTMLUListElement>) => (
<ul className="ms-6 my-3 list-disc" {...p} />
);

@@ -97,6 +98,14 @@ const Canary = ({children}: {children: React.ReactNode}) => (
<ExpandableCallout type="canary">{children}</ExpandableCallout>
);

const NextMajor = ({children}: {children: React.ReactNode}) => (
<ExpandableCallout type="major">{children}</ExpandableCallout>
);

const RSC = ({children}: {children: React.ReactNode}) => (
<ExpandableCallout type="rsc">{children}</ExpandableCallout>
);

const CanaryBadge = ({title}: {title: string}) => (
<span
title={title}
@@ -111,10 +120,27 @@ const CanaryBadge = ({title}: {title: string}) => (
</span>
);

const Blockquote = ({
children,
...props
}: JSX.IntrinsicElements['blockquote']) => {
const NextMajorBadge = ({title}: {title: string}) => (
<span
title={title}
className={
'text-base font-display px-2 py-0.5 font-bold bg-blue-10 dark:bg-blue-60 text-gray-60 dark:text-gray-10 rounded'
}>
React 19
</span>
);

const RSCBadge = ({title}: {title: string}) => (
<span
title={title}
className={
'text-base font-display px-2 py-0.5 font-bold bg-blue-10 dark:bg-blue-50 text-gray-60 dark:text-gray-10 rounded'
}>
RSC
</span>
);

const Blockquote = ({children, ...props}: HTMLAttributes<HTMLQuoteElement>) => {
return (
<blockquote
className="mdx-blockquote py-4 px-8 my-8 shadow-inner-border dark:shadow-inner-border-dark bg-highlight dark:bg-highlight-dark bg-opacity-50 rounded-2xl leading-6 flex relative"
@@ -483,6 +509,10 @@ export const MDXComponents = {
Note,
Canary,
CanaryBadge,
NextMajor,
NextMajorBadge,
RSC,
RSCBadge,
PackageImport,
ReadBlogPost,
Recap,
1 change: 1 addition & 0 deletions src/components/MDX/Sandpack/CustomPreset.tsx
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ export const CustomPreset = memo(function CustomPreset({
const {activeFile} = sandpack;
const lineCountRef = useRef<{[key: string]: number}>({});
if (!lineCountRef.current[activeFile]) {
// eslint-disable-next-line react-compiler/react-compiler
lineCountRef.current[activeFile] = code.split('\n').length;
}
const lineCount = lineCountRef.current[activeFile];
3 changes: 2 additions & 1 deletion src/components/MDX/Sandpack/LoadingOverlay.tsx
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ export const LoadingOverlay = ({
clientId: string;
dependenciesLoading: boolean;
forceLoading: boolean;
} & React.HTMLAttributes<HTMLDivElement>): JSX.Element | null => {
} & React.HTMLAttributes<HTMLDivElement>): React.ReactNode | null => {
const loadingOverlayState = useLoadingOverlayState(
clientId,
dependenciesLoading,
@@ -64,6 +64,7 @@ export const LoadingOverlay = ({
transition: `opacity ${FADE_ANIMATION_DURATION}ms ease-out`,
}}>
<div className="sp-cube-wrapper" title="Open in CodeSandbox">
{/* @ts-ignore: the OpenInCodeSandboxButton type from '@codesandbox/sandpack-react/unstyled' is incompatible with JSX in React 19 */}
<OpenInCodeSandboxButton />
<div className="sp-cube">
<div className="sp-sides">
13 changes: 9 additions & 4 deletions src/components/MDX/Sandpack/NavigationBar.tsx
Original file line number Diff line number Diff line change
@@ -115,7 +115,10 @@ export function NavigationBar({providedFiles}: {providedFiles: Array<string>}) {

return (
<div className="bg-wash dark:bg-card-dark flex justify-between items-center relative z-10 border-b border-border dark:border-border-dark rounded-t-lg text-lg">
{/* If Prettier reformats this block, the two @ts-ignore directives will no longer be adjacent to the problematic lines, causing TypeScript errors */}
{/* prettier-ignore */}
<div className="flex-1 grow min-w-0 px-4 lg:px-6">
{/* @ts-ignore: the Listbox type from '@headlessui/react' is incompatible with JSX in React 19 */}
<Listbox value={activeFile} onChange={setActiveFile}>
<div ref={containerRef}>
<div className="relative overflow-hidden">
@@ -129,8 +132,10 @@ export function NavigationBar({providedFiles}: {providedFiles: Array<string>}) {
'w-[fit-content]',
showDropdown ? 'invisible' : ''
)}>
{/* @ts-ignore: the FileTabs type from '@codesandbox/sandpack-react/unstyled' is incompatible with JSX in React 19 */}
<FileTabs />
</div>
{/* @ts-ignore: the Listbox type from '@headlessui/react' is incompatible with JSX in React 19 */}
<Listbox.Button as={Fragment}>
{({open}) => (
// If tabs don't fit, display the dropdown instead.
@@ -160,10 +165,10 @@ export function NavigationBar({providedFiles}: {providedFiles: Array<string>}) {
</Listbox.Button>
</div>
</div>
{isMultiFile && showDropdown && (
<Listbox.Options className="absolute mt-0.5 bg-card dark:bg-card-dark px-2 inset-x-0 mx-0 rounded-b-lg border-1 border-border dark:border-border-dark rounded-sm shadow-md">
{visibleFiles.map((filePath: string) => (
<Listbox.Option key={filePath} value={filePath} as={Fragment}>
{/* @ts-ignore: the Listbox type from '@headlessui/react' is incompatible with JSX in React 19 */}
{isMultiFile && showDropdown && (<Listbox.Options className="absolute mt-0.5 bg-card dark:bg-card-dark px-2 inset-x-0 mx-0 rounded-b-lg border-1 border-border dark:border-border-dark rounded-sm shadow-md">
{/* @ts-ignore: the Listbox type from '@headlessui/react' is incompatible with JSX in React 19 */}
{visibleFiles.map((filePath: string) => (<Listbox.Option key={filePath} value={filePath} as={Fragment}>
{({active}) => (
<li
className={cn(
1 change: 1 addition & 0 deletions src/components/MDX/Sandpack/Preview.tsx
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/

// eslint-disable-next-line react-compiler/react-compiler
/* eslint-disable react-hooks/exhaustive-deps */
import {useRef, useState, useEffect, useMemo, useId} from 'react';
import {useSandpack, SandpackStack} from '@codesandbox/sandpack-react/unstyled';
7 changes: 7 additions & 0 deletions src/components/MDX/Sandpack/SandpackRoot.tsx
Original file line number Diff line number Diff line change
@@ -71,6 +71,13 @@ function SandpackRoot(props: SandpackProps) {
const codeSnippets = Children.toArray(children) as React.ReactElement[];
const files = createFileMap(codeSnippets);

if ('/index.html' in files) {
throw new Error(
'You cannot use `index.html` file in sandboxes. ' +
'Only `public/index.html` is respected by Sandpack and CodeSandbox (where forks are created).'
);
}

files['/src/styles.css'] = {
code: [sandboxStyle, files['/src/styles.css']?.code ?? ''].join('\n\n'),
hidden: !files['/src/styles.css']?.visible,
9 changes: 8 additions & 1 deletion src/components/MDX/Sandpack/createFileMap.ts
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
*/

import type {SandpackFile} from '@codesandbox/sandpack-react/unstyled';
import type {PropsWithChildren, ReactElement, HTMLAttributes} from 'react';

export const AppJSPath = `/src/App.js`;
export const StylesCSSPath = `/src/styles.css`;
@@ -17,7 +18,13 @@ export const createFileMap = (codeSnippets: any) => {
) {
return result;
}
const {props} = codeSnippet.props.children;
const {props} = (
codeSnippet.props as PropsWithChildren<{
children: ReactElement<
HTMLAttributes<HTMLDivElement> & {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
4 changes: 2 additions & 2 deletions src/components/MDX/Sandpack/template.ts
Original file line number Diff line number Diff line change
@@ -28,8 +28,8 @@ root.render(
eject: 'react-scripts eject',
},
dependencies: {
react: '^18.0.0',
'react-dom': '^18.0.0',
react: '19.0.0-rc-3edc000d-20240926',
'react-dom': '19.0.0-rc-3edc000d-20240926',
'react-scripts': '^5.0.0',
},
},
8 changes: 3 additions & 5 deletions src/components/MDX/TeamMember.tsx
Original file line number Diff line number Diff line change
@@ -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 (
8 changes: 5 additions & 3 deletions src/components/MDX/TerminalBlock.tsx
Original file line number Diff line number Diff line change
@@ -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) {
</div>
</div>
<div
className="px-8 pt-4 pb-6 text-primary-dark dark:text-primary-dark font-mono text-code whitespace-pre overflow-x-scroll"
className="px-8 pt-4 pb-6 text-primary-dark dark:text-primary-dark font-mono text-code whitespace-pre overflow-x-auto"
translate="no"
dir="ltr">
<LevelText type={level} />
7 changes: 5 additions & 2 deletions src/components/Search.tsx
Original file line number Diff line number Diff line change
@@ -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<DocSearchModalProps>
>,
}))
);

Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ date: 2020/12/21
description: 2020 has been a long year. As it comes to an end we wanted to share a special Holiday Update on our research into zero-bundle-size React Server Components.
---

December 21, 2020 by [Dan Abramov](https://twitter.com/dan_abramov), [Lauren Tan](https://twitter.com/potetotes), [Joseph Savona](https://twitter.com/en_JS), and [Sebastian Markbåge](https://twitter.com/sebmarkbage)
December 21, 2020 by [Dan Abramov](https://bsky.app/profile/danabra.mov), [Lauren Tan](https://twitter.com/potetotes), [Joseph Savona](https://twitter.com/en_JS), and [Sebastian Markbåge](https://twitter.com/sebmarkbage)

---

2 changes: 1 addition & 1 deletion src/content/blog/2021/06/08/the-plan-for-react-18.md
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ date: 2021/06/08
description: The React team is excited to share a few updates. We’ve started work on the React 18 release, which will be our next major version. We’ve created a Working Group to prepare the community for gradual adoption of new features in React 18. We’ve published a React 18 Alpha so that library authors can try it and provide feedback...
---

June 8, 2021 by [Andrew Clark](https://twitter.com/acdlite), [Brian Vaughn](https://github.com/bvaughn), [Christine Abernathy](https://twitter.com/abernathyca), [Dan Abramov](https://twitter.com/dan_abramov), [Rachel Nabors](https://twitter.com/rachelnabors), [Rick Hanlon](https://twitter.com/rickhanlonii), [Sebastian Markbåge](https://twitter.com/sebmarkbage), and [Seth Webster](https://twitter.com/sethwebster)
June 8, 2021 by [Andrew Clark](https://twitter.com/acdlite), [Brian Vaughn](https://github.com/bvaughn), [Christine Abernathy](https://twitter.com/abernathyca), [Dan Abramov](https://bsky.app/profile/danabra.mov), [Rachel Nabors](https://twitter.com/rachelnabors), [Rick Hanlon](https://twitter.com/rickhanlonii), [Sebastian Markbåge](https://twitter.com/sebmarkbage), and [Seth Webster](https://twitter.com/sethwebster)

---

2 changes: 1 addition & 1 deletion src/content/blog/2021/12/17/react-conf-2021-recap.md
Original file line number Diff line number Diff line change
@@ -131,7 +131,7 @@ This was our first year planning a conference ourselves, and we have a lot of pe

First, thanks to all of our speakers [Aakansha Doshi](https://twitter.com/aakansha1216), [Andrew Clark](https://twitter.com/acdlite), [Brian Vaughn](https://twitter.com/brian_d_vaughn), [Daishi Kato](https://twitter.com/dai_shi), [Debbie O'Brien](https://twitter.com/debs_obrien), [Delba de Oliveira](https://twitter.com/delba_oliveira), [Diego Haz](https://twitter.com/diegohaz), [Eric Rozell](https://twitter.com/EricRozell), [Helen Lin](https://twitter.com/wizardlyhel), [Juan Tejada](https://twitter.com/_jstejada), [Lauren Tan](https://twitter.com/potetotes), [Linton Ye](https://twitter.com/lintonye), [Lyle Troxell](https://twitter.com/lyle), [Rachel Nabors](https://twitter.com/rachelnabors), [Rick Hanlon](https://twitter.com/rickhanlonii), [Robert Balicki](https://twitter.com/StatisticsFTW), [Roman Rädle](https://twitter.com/raedle), [Sarah Rainsberger](https://twitter.com/sarah11918), [Shaundai Person](https://twitter.com/shaundai), [Shruti Kapoor](https://twitter.com/shrutikapoor08), [Steven Moyes](https://twitter.com/moyessa), [Tafu Nakazaki](https://twitter.com/hawaiiman0), and [Xuan Huang (黄玄)](https://twitter.com/Huxpro).

Thanks to everyone who helped provide feedback on talks including [Andrew Clark](https://twitter.com/acdlite), [Dan Abramov](https://twitter.com/dan_abramov), [Dave McCabe](https://twitter.com/mcc_abe), [Eli White](https://twitter.com/Eli_White), [Joe Savona](https://twitter.com/en_JS), [Lauren Tan](https://twitter.com/potetotes), [Rachel Nabors](https://twitter.com/rachelnabors), and [Tim Yung](https://twitter.com/yungsters).
Thanks to everyone who helped provide feedback on talks including [Andrew Clark](https://twitter.com/acdlite), [Dan Abramov](https://bsky.app/profile/danabra.mov), [Dave McCabe](https://twitter.com/mcc_abe), [Eli White](https://twitter.com/Eli_White), [Joe Savona](https://twitter.com/en_JS), [Lauren Tan](https://twitter.com/potetotes), [Rachel Nabors](https://twitter.com/rachelnabors), and [Tim Yung](https://twitter.com/yungsters).

Thanks to [Lauren Tan](https://twitter.com/potetotes) for setting up the conference Discord and serving as our Discord admin.

Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ date: 2022/06/15
description: React 18 was years in the making, and with it brought valuable lessons for the React team. Its release was the result of many years of research and exploring many paths. Some of those paths were successful; many more were dead-ends that led to new insights. One lesson we’ve learned is that it’s frustrating for the community to wait for new features without having insight into these paths that we’re exploring.
---

June 15, 2022 by [Andrew Clark](https://twitter.com/acdlite), [Dan Abramov](https://twitter.com/dan_abramov), [Jan Kassens](https://twitter.com/kassens), [Joseph Savona](https://twitter.com/en_JS), [Josh Story](https://twitter.com/joshcstory), [Lauren Tan](https://twitter.com/potetotes), [Luna Ruan](https://twitter.com/lunaruan), [Mengdi Chen](https://twitter.com/mengdi_en), [Rick Hanlon](https://twitter.com/rickhanlonii), [Robert Zhang](https://twitter.com/jiaxuanzhang01), [Sathya Gunasekaran](https://twitter.com/_gsathya), [Sebastian Markbåge](https://twitter.com/sebmarkbage), and [Xuan Huang](https://twitter.com/Huxpro)
June 15, 2022 by [Andrew Clark](https://twitter.com/acdlite), [Dan Abramov](https://bsky.app/profile/danabra.mov), [Jan Kassens](https://twitter.com/kassens), [Joseph Savona](https://twitter.com/en_JS), [Josh Story](https://twitter.com/joshcstory), [Lauren Tan](https://twitter.com/potetotes), [Luna Ruan](https://twitter.com/lunaruan), [Mengdi Chen](https://twitter.com/mengdi_en), [Rick Hanlon](https://twitter.com/rickhanlonii), [Robert Zhang](https://twitter.com/jiaxuanzhang01), [Sathya Gunasekaran](https://twitter.com/_gsathya), [Sebastian Markbåge](https://twitter.com/sebmarkbage), and [Xuan Huang](https://twitter.com/Huxpro)

---

4 changes: 2 additions & 2 deletions src/content/blog/2023/03/16/introducing-react-dev.md
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ date: 2023/03/16
description: Today we are thrilled to launch react.dev, the new home for React and its documentation. In this post, we would like to give you a tour of the new site.
---

March 16, 2023 by [Dan Abramov](https://twitter.com/dan_abramov) and [Rachel Nabors](https://twitter.com/rachelnabors)
March 16, 2023 by [Dan Abramov](https://bsky.app/profile/danabra.mov) and [Rachel Nabors](https://twitter.com/rachelnabors)

---

@@ -631,7 +631,7 @@ We think there's never been a better time to learn React.

## Who worked on this? {/*who-worked-on-this*/}

On the React team, [Rachel Nabors](https://twitter.com/rachelnabors/) led the project (and provided the illustrations), and [Dan Abramov](https://twitter.com/dan_abramov) designed the curriculum. They co-authored most of the content together as well.
On the React team, [Rachel Nabors](https://twitter.com/rachelnabors/) led the project (and provided the illustrations), and [Dan Abramov](https://bsky.app/profile/danabra.mov) designed the curriculum. They co-authored most of the content together as well.

Of course, no project this large happens in isolation. We have a lot of people to thank!

Original file line number Diff line number Diff line change
@@ -97,9 +97,9 @@ The Transition Tracing API lets you detect when [React Transitions](/reference/r
* * *
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.

* [Dan Abramov](https://twitter.com/dan_abramov) and [Joe Savona](https://twitter.com/en_JS) were interviewed by [Kent C. Dodds on his YouTube channel](https://www.youtube.com/watch?v=h7tur48JSaw), where they discussed concerns around React Server Components.
* [Dan Abramov](https://twitter.com/dan_abramov) and [Joe Savona](https://twitter.com/en_JS) were guests on the [JSParty podcast](https://jsparty.fm/267) and shared their thoughts about the future of React.
* [Dan Abramov](https://bsky.app/profile/danabra.mov) and [Joe Savona](https://twitter.com/en_JS) were interviewed by [Kent C. Dodds on his YouTube channel](https://www.youtube.com/watch?v=h7tur48JSaw), where they discussed concerns around React Server Components.
* [Dan Abramov](https://bsky.app/profile/danabra.mov) and [Joe Savona](https://twitter.com/en_JS) were guests on the [JSParty podcast](https://jsparty.fm/267) and shared their thoughts about the future of React.

Thanks to [Andrew Clark](https://twitter.com/acdlite), [Dan Abramov](https://twitter.com/dan_abramov), [Dave McCabe](https://twitter.com/mcc_abe), [Luna Wei](https://twitter.com/lunaleaps), [Matt Carroll](https://twitter.com/mattcarrollcode), [Sean Keegan](https://twitter.com/DevRelSean), [Sebastian Silbermann](https://twitter.com/sebsilbermann), [Seth Webster](https://twitter.com/sethwebster), and [Sophie Alpert](https://twitter.com/sophiebits) for reviewing this post.
Thanks to [Andrew Clark](https://twitter.com/acdlite), [Dan Abramov](https://bsky.app/profile/danabra.mov), [Dave McCabe](https://twitter.com/mcc_abe), [Luna Wei](https://twitter.com/lunaleaps), [Matt Carroll](https://twitter.com/mattcarrollcode), [Sean Keegan](https://twitter.com/DevRelSean), [Sebastian Silbermann](https://twitter.com/sebsilbermann), [Seth Webster](https://twitter.com/sethwebster), and [Sophie Alpert](https://twitter.com/sophiebits) for reviewing this post.

Thanks for reading, and see you in the next update!
2 changes: 1 addition & 1 deletion src/content/blog/2023/05/03/react-canaries.md
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ date: 2023/05/03
description: We'd like to offer the React community an option to adopt individual new features as soon as their design is close to final, before they're released in a stable version--similar to how Meta has long used bleeding-edge versions of React internally. We are introducing a new officially supported [Canary release channel](/community/versioning-policy#canary-channel). It lets curated setups like frameworks decouple adoption of individual React features from the React release schedule.
---

May 3, 2023 by [Dan Abramov](https://twitter.com/dan_abramov), [Sophie Alpert](https://twitter.com/sophiebits), [Rick Hanlon](https://twitter.com/rickhanlonii), [Sebastian Markbåge](https://twitter.com/sebmarkbage), and [Andrew Clark](https://twitter.com/acdlite)
May 3, 2023 by [Dan Abramov](https://bsky.app/profile/danabra.mov), [Sophie Alpert](https://twitter.com/sophiebits), [Rick Hanlon](https://twitter.com/rickhanlonii), [Sebastian Markbåge](https://twitter.com/sebmarkbage), and [Andrew Clark](https://twitter.com/acdlite)

---

Original file line number Diff line number Diff line change
@@ -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).

---

37 changes: 16 additions & 21 deletions src/content/blog/2024/04/25/react-19-upgrade-guide.md
Original file line number Diff line number Diff line change
@@ -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)

<Intro>

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.

</Intro>

@@ -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://codemod.com/registry/react-prop-types-typescript)

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 dont 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).

---

6 changes: 3 additions & 3 deletions src/content/blog/2024/05/22/react-conf-2024-recap.md
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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)

---
<Note>

### 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._

</Note>

<Intro>

React 19 RC is now available on npm!
React v19 is now available on npm!

</Intro>

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

</ConsoleBlockMulti>

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.

</Note>

@@ -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(<App />, {
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.

@@ -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._
14 changes: 7 additions & 7 deletions src/content/blog/index.md
Original file line number Diff line number Diff line change
@@ -10,25 +10,25 @@ This blog is the official source for the updates from the React team. Anything i

<div className="sm:-mx-5 flex flex-col gap-5 mt-12">

<BlogCard title="React Compiler Beta Release" date="October 21, 2024" url="/blog/2024/10/21/react-compiler-beta-release">
<BlogCard title="React v19 " date="December 5, 2024" url="/blog/2024/12/05/react-19">

We announced an experimental release of React Compiler at React Conf 2024. We've made a lot of progress since then, and in this post we want to share what's next for React Compiler ...
In the 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 ...

</BlogCard>

<BlogCard title="React Conf 2024 Recap" date="May 22, 2024" url="/blog/2024/05/22/react-conf-2024-recap">
<BlogCard title="React Compiler Beta Release" date="October 21, 2024" url="/blog/2024/10/21/react-compiler-beta-release">

Last week we hosted React Conf 2024, a two-day conference in Henderson, Nevada where 700+ attendees gathered in-person to discuss the latest in UI engineering. This was our first in-person conference since 2019, and we were thrilled to be able to bring the community together again ...
We announced an experimental release of React Compiler at React Conf 2024. We've made a lot of progress since then, and in this post we want to share what's next for React Compiler ...

</BlogCard>

<BlogCard title="React 19 RC " date="April 25, 2024" url="/blog/2024/04/25/react-19">
<BlogCard title="React Conf 2024 Recap" date="May 22, 2024" url="/blog/2024/05/22/react-conf-2024-recap">

In the React 19 RC 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 ...
Last week we hosted React Conf 2024, a two-day conference in Henderson, Nevada where 700+ attendees gathered in-person to discuss the latest in UI engineering. This was our first in-person conference since 2019, and we were thrilled to be able to bring the community together again ...

</BlogCard>

<BlogCard title="React 19 RC Upgrade Guide" date="April 25, 2024" url="/blog/2024/04/25/react-19-upgrade-guide">
<BlogCard title="React 19 Upgrade Guide" date="April 25, 2024" url="/blog/2024/04/25/react-19-upgrade-guide">

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 libraries to React 19 ...

5 changes: 4 additions & 1 deletion src/content/community/acknowledgements.md
Original file line number Diff line number Diff line change
@@ -36,6 +36,8 @@ We'd like to recognize a few people who have made significant contributions to R
* [Joe Critchley](https://github.com/joecritch)
* [Jeff Morrison](https://github.com/jeffmo)
* [Luna Ruan](https://github.com/lunaruan)
* [Luna Wei](https://github.com/lunaleaps)
* [Noah Lemen](https://github.com/noahlemen)
* [Kathryn Middleton](https://github.com/kmiddleton14)
* [Keyan Zhang](https://github.com/keyz)
* [Marco Salazar](https://github.com/salazarm)
@@ -51,9 +53,10 @@ We'd like to recognize a few people who have made significant contributions to R
* [Samuel Susla](https://github.com/sammy-SC)
* [Sander Spies](https://github.com/sanderspies)
* [Sasha Aickin](https://github.com/aickin)
* [Sean Keegan](https://github.com/seanryankeegan)
* [Sathya Gunasekaran](https://github.com/gsathya)
* [Sophia Shoemaker](https://github.com/mrscobbler)
* [Sunil Pai](https://github.com/threepointone)
* [Tianyu Yao](https://github.com/)
* [Tim Yung](https://github.com/yungsters)
* [Xuan Huang](https://github.com/huxpro)

102 changes: 72 additions & 30 deletions src/content/community/conferences.md
Original file line number Diff line number Diff line change
@@ -10,62 +10,104 @@ Do you know of a local React.js conference? Add it here! (Please keep the list c

## Upcoming Conferences {/*upcoming-conferences*/}

### React Universe Conf 2024 {/*react-universe-conf-2024*/}
September 5-6, 2024. Wrocław, Poland.
### React Paris 2025 {/*react-paris-2025*/}
March 20 - 21, 2025. In-person in Paris, France (hybrid event)

[Website](https://www.reactuniverseconf.com/) - [Twitter](https://twitter.com/react_native_eu) - [LinkedIn](https://www.linkedin.com/events/reactuniverseconf7163919537074118657/)
[Website](https://react.paris/) - [Twitter](https://x.com/BeJS_)

### React Alicante 2024 {/*react-alicante-2024*/}
September 19-21, 2024. Alicante, Spain.
### React Native Connection 2025 {/*react-native-connection-2025*/}
April 3 (Reanimated Training) + April 4 (Conference), 2025. Paris, France.

[Website](https://reactalicante.es/) - [Twitter](https://twitter.com/ReactAlicante) - [YouTube](https://www.youtube.com/channel/UCaSdUaITU1Cz6PvC97A7e0w)
[Website](https://reactnativeconnection.io/) - [X](https://x.com/reactnativeconn) - [Bluesky](https://bsky.app/profile/reactnativeconnect.bsky.social)

### RenderCon Kenya 2024 {/*rendercon-kenya-2024*/}
October 04 - 05, 2024. Nairobi, Kenya
### CityJS London 2025 {/*cityjs-london*/}
April 23 - 25, 2025. In-person in London, UK

[Website](https://rendercon.org/) - [Twitter](https://twitter.com/renderconke) - [LinkedIn](https://www.linkedin.com/company/renderconke/) - [YouTube](https://www.youtube.com/channel/UC0bCcG8gHUL4njDOpQGcMIA)
[Website](https://london.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social)

### React India 2024 {/*react-india-2024*/}
October 17 - 19, 2024. In-person in Goa, India (hybrid event) + Oct 15 2024 - remote day
### App.js Conf 2025 {/*appjs-conf-2025*/}
May 28 - 30, 2025. In-person in Kraków, Poland + remote

[Website](https://appjs.co) - [Twitter](https://twitter.com/appjsconf)

### CityJS Athens 2025 {/*cityjs-athens*/}
May 27 - 31, 2025. In-person in Athens, Greece

[Website](https://athens.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social)

### React Summit 2025 {/*react-summit-2025*/}
June 13 - 17, 2025. In-person in Amsterdam, Netherlands + remote (hybrid event)

[Website](https://reactsummit.com/) - [Twitter](https://x.com/reactsummit)

### React Universe Conf 2025 {/*react-universe-conf-2025*/}
September 2-4, 2025. Wrocław, Poland.

[Website](https://www.reactuniverseconf.com/) - [Twitter](https://twitter.com/react_native_eu) - [LinkedIn](https://www.linkedin.com/events/reactuniverseconf7163919537074118657/)

### React India 2025 {/*react-india-2025*/}
October 31 - November 01, 2025. In-person in Goa, India (hybrid event) + Oct 15 2025 - remote day

[Website](https://www.reactindia.io) - [Twitter](https://twitter.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia) - [Youtube](https://www.youtube.com/channel/UCaFbHCBkPvVv1bWs_jwYt3w)

### React Brussels 2024 {/*react-brussels-2024*/}
October 18, 2024. In-person in Brussels, Belgium (hybrid event)

[Website](https://www.react.brussels/) - [Twitter](https://x.com/BrusselsReact)
## Past Conferences {/*past-conferences*/}

### reactjsday 2024 {/*reactjsday-2024*/}
October 25, 2024. In-person in Verona, Italy + online (hybrid event)
### React Day Berlin 2024 {/*react-day-berlin-2024*/}
December 13 & 16, 2024. In-person in Berlin, Germany + remote (hybrid event)

[Website](https://2024.reactjsday.it/) - [Twitter](https://x.com/reactjsday) - [Facebook](https://www.facebook.com/GrUSP/) - [YouTube](https://www.youtube.com/c/grusp)
[Website](https://reactday.berlin/) - [Twitter](https://x.com/reactdayberlin)

### React Advanced London 2024 {/*react-advanced-london-2024*/}
October 25 & 28, 2024. In-person in London, UK + online (hybrid event)
### React Africa 2024 {/*react-africa-2024*/}
November 29, 2024. In-person in Casablanca, Morocco (hybrid event)

[Website](https://reactadvanced.com/) - [Twitter](https://x.com/reactadvanced)
[Website](https://react-africa.com/) - [Twitter](https://x.com/BeJS_)

### React Summit US 2024 {/*react-summit-us-2024*/}
November 19 & 22, 2024. In-person in New York, USA + online (hybrid event)

[Website](https://reactsummit.us/) - [Twitter](https://twitter.com/reactsummit) - [Videos](https://portal.gitnation.org/)

### React Native London Conf 2024 {/*react-native-london-2024*/}
November 14 & 15, 2024. In-person in London, UK

[Website](https://reactnativelondon.co.uk/) - [Twitter](https://x.com/RNLConf)

### React Summit US 2024 {/*react-summit-us-2024*/}
November 19 & 22, 2024. In-person in New York, USA + online (hybrid event)
### React Advanced London 2024 {/*react-advanced-london-2024*/}
October 25 & 28, 2024. In-person in London, UK + online (hybrid event)

[Website](https://reactsummit.us/) - [Twitter](https://twitter.com/reactsummit) - [Videos](https://portal.gitnation.org/)
[Website](https://reactadvanced.com/) - [Twitter](https://x.com/reactadvanced)

### React Africa 2024 {/*react-africa-2024*/}
November 29, 2024. In-person in Casablanca, Morocco (hybrid event)
### reactjsday 2024 {/*reactjsday-2024*/}
October 25, 2024. In-person in Verona, Italy + online (hybrid event)

[Website](https://react-africa.com/) - [Twitter](https://x.com/BeJS_)
[Website](https://2024.reactjsday.it/) - [Twitter](https://x.com/reactjsday) - [Facebook](https://www.facebook.com/GrUSP/) - [YouTube](https://www.youtube.com/c/grusp)

### React Day Berlin 2024 {/*react-day-berlin-2024*/}
December 13 & 16, 2024. In-person in Berlin, Germany + remote (hybrid event)
### React Brussels 2024 {/*react-brussels-2024*/}
October 18, 2024. In-person in Brussels, Belgium (hybrid event)

[Website](https://reactday.berlin/) - [Twitter](https://x.com/reactdayberlin)
[Website](https://www.react.brussels/) - [Twitter](https://x.com/BrusselsReact) - [YouTube](https://www.youtube.com/playlist?list=PL53Z0yyYnpWimQ0U75woee2zNUIFsiDC3)

### React India 2024 {/*react-india-2024*/}
October 17 - 19, 2024. In-person in Goa, India (hybrid event) + Oct 15 2024 - remote day

[Website](https://www.reactindia.io) - [Twitter](https://twitter.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia) - [Youtube](https://www.youtube.com/channel/UCaFbHCBkPvVv1bWs_jwYt3w)

### RenderCon Kenya 2024 {/*rendercon-kenya-2024*/}
October 04 - 05, 2024. Nairobi, Kenya

[Website](https://rendercon.org/) - [Twitter](https://twitter.com/renderconke) - [LinkedIn](https://www.linkedin.com/company/renderconke/) - [YouTube](https://www.youtube.com/channel/UC0bCcG8gHUL4njDOpQGcMIA)

### React Alicante 2024 {/*react-alicante-2024*/}
September 19-21, 2024. Alicante, Spain.

[Website](https://reactalicante.es/) - [Twitter](https://twitter.com/ReactAlicante) - [YouTube](https://www.youtube.com/channel/UCaSdUaITU1Cz6PvC97A7e0w)

### React Universe Conf 2024 {/*react-universe-conf-2024*/}
September 5-6, 2024. Wrocław, Poland.

[Website](https://www.reactuniverseconf.com/) - [Twitter](https://twitter.com/react_native_eu) - [LinkedIn](https://www.linkedin.com/events/reactuniverseconf7163919537074118657/)

## Past Conferences {/*past-conferences*/}

### React Rally 2024 🐙 {/*react-rally-2024*/}
August 12-13, 2024. Park City, UT, USA
4 changes: 2 additions & 2 deletions src/content/community/docs-contributors.md
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ React documentation is written and maintained by the [React team](/community/tea
## Content {/*content*/}

* [Rachel Nabors](https://twitter.com/RachelNabors): editing, writing, illustrating
* [Dan Abramov](https://twitter.com/dan_abramov): writing, curriculum design
* [Dan Abramov](https://bsky.app/profile/danabra.mov): writing, curriculum design
* [Sylwia Vargas](https://twitter.com/SylwiaVargas): example code
* [Rick Hanlon](https://twitter.com/rickhanlonii): writing
* [David McCabe](https://twitter.com/mcc_abe): writing
@@ -34,7 +34,7 @@ React documentation is written and maintained by the [React team](/community/tea
* [Jared Palmer](https://twitter.com/jaredpalmer): site development
* [ThisDotLabs](https://www.thisdot.co/) ([Dane Grant](https://twitter.com/danecando), [Dustin Goodman](https://twitter.com/dustinsgoodman)): site development
* [CodeSandbox](https://codesandbox.io/) ([Ives van Hoorne](https://twitter.com/CompuIves), [Alex Moldovan](https://twitter.com/alexnmoldovan), [Jasper De Moor](https://twitter.com/JasperDeMoor), [Danilo Woznica](https://twitter.com/danilowoz)): sandbox integration
* [Dan Abramov](https://twitter.com/dan_abramov): site development
* [Dan Abramov](https://bsky.app/profile/danabra.mov): site development
* [Rick Hanlon](https://twitter.com/rickhanlonii): site development
* [Harish Kumar](https://www.strek.in/): development and maintenance
* [Luna Ruan](https://twitter.com/lunaruan): sandbox improvements
32 changes: 16 additions & 16 deletions src/content/community/team.md
Original file line number Diff line number Diff line change
@@ -22,10 +22,14 @@ Current members of the React team are listed in alphabetical order below.
Dan got into programming after he accidentally discovered Visual Basic inside Microsoft PowerPoint. He has found his true calling in turning [Sebastian](#sebastian-markbåge)'s tweets into long-form blog posts. Dan occasionally wins at Fortnite by hiding in a bush until the game ends.
</TeamMember>

<TeamMember name="Eli White" permalink="eli-white" photo="/images/team/eli-white.jpg" github="TheSavior" twitter="Eli_White" threads="elicwhite" title="Engineering Manager at Meta">
<TeamMember name="Eli White" permalink="eli-white" photo="/images/team/eli-white.jpg" github="elicwhite" twitter="Eli_White" threads="elicwhite" title="Engineering Manager at Meta">
Eli got into programming after he got suspended from middle school for hacking. He has been working on React and React Native since 2017. He enjoys eating treats, especially ice cream and apple pie. You can find Eli trying quirky activities like parkour, indoor skydiving, and aerial silks.
</TeamMember>

<TeamMember name="Hendrik Liebau" permalink="hendrik-liebau" photo="/images/team/hendrik.jpg" github="unstubbable" bsky="unstubbable.bsky.social" twitter="unstubbable" title="Engineer at Vercel">
Hendrik’s journey in tech started in the late 90s when he built his first websites with Netscape Communicator. After earning a diploma in computer science and working at digital agencies, he built a React Server Components bundler and library, paving the way to his role on the Next.js team. Outside of work, he enjoys cycling and tinkering in his workshop.
</TeamMember>

<TeamMember name="Jack Pope" permalink="jack-pope" photo="/images/team/jack-pope.jpg" github="jackpope" personal="jackpope.me" title="Engineer at Meta">
Shortly after being introduced to AutoHotkey, Jack had written scripts to automate everything he could think of. When reaching limitations there, he dove headfirst into web app development and hasn't looked back. Most recently, Jack worked on the web platform at Instagram before moving to React. His favorite programming language is JSX.
</TeamMember>
@@ -38,28 +42,32 @@ Current members of the React team are listed in alphabetical order below.
Joe was planning to major in math and philosophy but got into computer science after writing physics simulations in Matlab. Prior to React, he worked on Relay, RSocket.js, and the Skip programming language. While he’s not building some sort of reactive system he enjoys running, studying Japanese, and spending time with his family.
</TeamMember>

<TeamMember name="Jordan Brown" permalink="jordan-brown" photo="/images/team/jordan.jpg" github="jbrown215" title="Engineer at Meta">
Jordan started coding by building iPhone apps, where he was pushing and popping view controllers before he knew that for-loops were a thing. He enjoys working on technology that developers love, which naturally drew him to React. Outside of work he enjoys reading, kiteboarding, and playing guitar.
</TeamMember>

<TeamMember name="Josh Story" permalink="josh-story" photo="/images/team/josh.jpg" github="gnoff" bsky="storyhb.com" title="Engineer at Vercel">
Josh majored in Mathematics and discovered programming while in college. His first professional developer job was to program insurance rate calculations in Microsoft Excel, the paragon of Reactive Programming which must be why he now works on React. In between that time Josh has been an IC, Manager, and Executive at a few startups. outside of work he likes to push his limits with cooking.
</TeamMember>

<TeamMember name="Lauren Tan" permalink="lauren-tan" photo="/images/team/lauren.jpg" github="poteto" twitter="potetotes" threads="potetotes" bsky="no.lol" title="Engineer at Meta">
Lauren's programming career peaked when she first discovered the `<marquee>` tag. She’s been chasing that high ever since. She studied Finance instead of CS in college, so she learned to code using Excel instead of Java. Lauren enjoys dropping cheeky memes in chat, playing video games with her partner, and petting her dog Zelda.
</TeamMember>

<TeamMember name="Luna Wei" permalink="luna-wei" photo="/images/team/luna-wei.jpg" github="lunaleaps" twitter="lunaleaps" threads="lunaleaps" title="Engineer at Meta">
Luna first learnt the fundamentals of python at the age of 6 from her father. Since then, she has been unstoppable. Luna aspires to be a gen z, and the road to success is paved with environmental advocacy, urban gardening and lots of quality time with her Voo-Doo’d (as pictured).
Lauren's programming career peaked when she first discovered the `<marquee>` tag. She’s been chasing that high ever since. She studied Finance instead of CS in college, so she learned to code using Excel. Lauren enjoys dropping cheeky memes in chat, playing video games with her partner, learning Korean, and petting her dog Zelda.
</TeamMember>

<TeamMember name="Matt Carroll" permalink="matt-carroll" photo="/images/team/matt-carroll.png" github="mattcarrollcode" twitter="mattcarrollcode" threads="mattcarrollcode" title="Developer Advocate at Meta">
Matt stumbled into coding, and since then, has become enamored with creating things in communities that can’t be created alone. Prior to React, he worked on YouTube, the Google Assistant, Fuchsia, and Google Cloud AI and Evernote. When he's not trying to make better developer tools he enjoys the mountains, jazz, and spending time with his family.
</TeamMember>

<TeamMember name="Mike Vitousek" permalink="mike-vitousek" photo="/images/team/mike.jpg" github="mvitousek" title="Engineer at Meta">
Mike went to grad school dreaming of becoming a professor but realized that he liked building things a lot more than writing grant applications. Mike joined Meta to work on Javascript infrastructure, which ultimately led him to work on the React Compiler. When not hacking on either Javascript or OCaml, Mike can often be found hiking or skiing in the Pacific Northwest.
</TeamMember>

<TeamMember name="Mofei Zhang" permalink="mofei-zhang" photo="/images/team/mofei-zhang.png" github="mofeiZ" threads="z_mofei" title="Engineer at Meta">
Mofei started programming when she realized it can help her cheat in video games. She focused on operating systems in undergrad / grad school, but now finds herself happily tinkering on React. Outside of work, she enjoys debugging bouldering problems and planning her next backpacking trip(s).
</TeamMember>

<TeamMember name="Noah Lemen" permalink="noah-lemen" photo="/images/team/noahlemen.jpg" github="noahlemen" twitter="noahlemen" threads="noahlemen" personal="noahle.men" title="Engineer at Meta">
Noah’s interest in UI programming sparked during his education in music technology at NYU. At Meta, he's worked on internal tools, browsers, web performance, and is currently focused on React. Outside of work, Noah can be found tinkering with synthesizers or spending time with his cat.
<TeamMember name="Pieter Vanderwerff" permalink="pieter-vanderwerff" photo="/images/team/pieter.jpg" github="pieterv" threads="pietervanderwerff" title="Engineer at Meta">
Pieter studied building science but after failing to get a job he made himself a website and things escalated from there. At Meta, he enjoys working on performance, languages and now React. When he's not programming you can find him off-road in the mountains.
</TeamMember>

<TeamMember name="Rick Hanlon" permalink="rick-hanlon" photo="/images/team/rickhanlonii.jpg" github="rickhanlonii" twitter="rickhanlonii" threads="rickhanlonii" bsky="ricky.fm" title="Engineer at Meta">
@@ -70,10 +78,6 @@ Current members of the React team are listed in alphabetical order below.
Ruslan's introduction to UI programming started when he was a kid by manually editing HTML templates for his custom gaming forums. Somehow, he ended up majoring in Computer Science. He enjoys music, games, and memes. Mostly memes.
</TeamMember>

<TeamMember name="Sathya Gunasekaran " permalink="sathya-gunasekaran" photo="/images/team/sathya.jpg" github="gsathya" twitter="_gsathya" threads="gsathya.03" title="Engineer at Meta">
Sathya hated the Dragon Book in school but somehow ended up working on compilers all his career. When he's not compiling React components, he's either drinking coffee or eating yet another Dosa.
</TeamMember>

<TeamMember name="Sebastian Markbåge" permalink="sebastian-markbåge" photo="/images/team/sebmarkbage.jpg" github="sebmarkbage" twitter="sebmarkbage" threads="sebmarkbage" title="Engineer at Vercel">
Sebastian majored in psychology. He's usually quiet. Even when he says something, it often doesn't make sense to the rest of us until a few months later. The correct way to pronounce his surname is "mark-boa-geh" but he settled for "mark-beige" out of pragmatism -- and that's how he approaches React.
</TeamMember>
@@ -90,10 +94,6 @@ Current members of the React team are listed in alphabetical order below.
Four days after React was released, Sophie rewrote the entirety of her then-current project to use it, which she now realizes was perhaps a bit reckless. After she became the project's #1 committer, she wondered why she wasn't getting paid by Facebook like everyone else was and joined the team officially to lead React through its adolescent years. Though she quit that job years ago, somehow she's still in the team's group chats and “providing value”.
</TeamMember>

<TeamMember name="Tianyu Yao" permalink="tianyu-yao" photo="/images/team/tianyu.jpg" github="tyao1" twitter="tianyu0" title="Engineer at Meta">
Tianyu’s interest in computers started as a kid because he loves video games. So he majored in computer science and still plays childish games like League of Legends. When he is not in front of a computer, he enjoys playing with his two kittens, hiking and kayaking.
</TeamMember>

<TeamMember name="Yuzhi Zheng" permalink="yuzhi-zheng" photo="/images/team/yuzhi.jpg" github="yuzhi" twitter="yuzhiz" threads="yuzhiz" title="Engineering Manager at Meta">
Yuzhi studied Computer Science in school. She liked the instant gratification of seeing code come to life without having to physically be in a laboratory. Now she’s a manager in the React org. Before management, she used to work on the Relay data fetching framework. In her spare time, Yuzhi enjoys optimizing her life via gardening and home improvement projects.
</TeamMember>
6 changes: 4 additions & 2 deletions src/content/community/versioning-policy.md
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ All stable builds of React go through a high level of testing and follow semanti

</Intro>

For a list of previous releases, see the [Versions](/versions) page.
This versioning policy describes our approach to version numbers for packages such as `react` and `react-dom`. For a list of previous releases, see the [Versions](/versions) page.

## Stable releases {/*stable-releases*/}

@@ -24,7 +24,9 @@ Major releases can also contain new features, and any release can include bug fi

Minor releases are the most common type of release.

### Breaking Changes {/*breaking-changes*/}
We know our users continue to use old versions of React in production. If we learn of a security vulnerability in React, we release a backported fix for all major versions that are affected by the vulnerability.

### Breaking changes {/*breaking-changes*/}

Breaking changes are inconvenient for everyone, so we try to minimize the number of major releases – for example, React 15 was released in April 2016 and React 16 was released in September 2017, and React 17 was released in October 2020.

11 changes: 6 additions & 5 deletions src/content/learn/add-react-to-an-existing-project.md
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ Let's say you have an existing web app at `example.com` built with another serve
Here's how we recommend to set it up:

1. **Build the React part of your app** using one of the [React-based frameworks](/learn/start-a-new-react-project).
2. **Specify `/some-app` as the *base path*** in your framework's configuration (here's how: [Next.js](https://nextjs.org/docs/api-reference/next.config.js/basepath), [Gatsby](https://www.gatsbyjs.com/docs/how-to/previews-deploys-hosting/path-prefix/)).
2. **Specify `/some-app` as the *base path*** in your framework's configuration (here's how: [Next.js](https://nextjs.org/docs/app/api-reference/config/next-config-js/basePath), [Gatsby](https://www.gatsbyjs.com/docs/how-to/previews-deploys-hosting/path-prefix/)).
3. **Configure your server or a proxy** so that all requests under `/some-app/` are handled by your React app.

This ensures the React part of your app can [benefit from the best practices](/learn/start-a-new-react-project#can-i-use-react-without-a-framework) baked into those frameworks.
@@ -45,7 +45,7 @@ A modular JavaScript environment lets you write your React components in individ

* **If your app is already split into files that use `import` statements,** try to use the setup you already have. Check whether writing `<div />` in your JS code causes a syntax error. If it causes a syntax error, you might need to [transform your JavaScript code with Babel](https://babeljs.io/setup), and enable the [Babel React preset](https://babeljs.io/docs/babel-preset-react) to use JSX.

* **If your app doesn't have an existing setup for compiling JavaScript modules,** set it up with [Vite](https://vitejs.dev/). The Vite community maintains [many integrations with backend frameworks](https://github.com/vitejs/awesome-vite#integrations-with-backends), including Rails, Django, and Laravel. If your backend framework is not listed, [follow this guide](https://vitejs.dev/guide/backend-integration.html) to manually integrate Vite builds with your backend.
* **If your app doesn't have an existing setup for compiling JavaScript modules,** set it up with [Vite](https://vite.dev/). The Vite community maintains [many integrations with backend frameworks](https://github.com/vitejs/awesome-vite#integrations-with-backends), including Rails, Django, and Laravel. If your backend framework is not listed, [follow this guide](https://vite.dev/guide/backend-integration.html) to manually integrate Vite builds with your backend.

To check whether your setup works, run this command in your project folder:

@@ -57,12 +57,13 @@ Then add these lines of code at the top of your main JavaScript file (it might b

<Sandpack>

```html index.html hidden
```html public/index.html hidden
<!DOCTYPE html>
<html>
<head><title>My app</title></head>
<body>
<!-- Your existing page content (in this example, it gets replaced) -->
<div id="root"></div>
</body>
</html>
```
@@ -84,7 +85,7 @@ If the entire content of your page was replaced by a "Hello, world!", everything

<Note>

Integrating a modular JavaScript environment into an existing project for the first time can feel intimidating, but it's worth it! If you get stuck, try our [community resources](/community) or the [Vite Chat](https://chat.vitejs.dev/).
Integrating a modular JavaScript environment into an existing project for the first time can feel intimidating, but it's worth it! If you get stuck, try our [community resources](/community) or the [Vite Chat](https://chat.vite.dev/).

</Note>

@@ -119,7 +120,7 @@ This lets you find that HTML element with [`document.getElementById`](https://de

<Sandpack>

```html index.html
```html public/index.html
<!DOCTYPE html>
<html>
<head><title>My app</title></head>
2 changes: 1 addition & 1 deletion src/content/learn/index.md
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ title: Quick Start

<Intro>

Welcome to the React documentation! This page will give you an introduction to the 80% of React concepts that you will use on a daily basis.
Welcome to the React documentation! This page will give you an introduction to 80% of the React concepts that you will use on a daily basis.

</Intro>

142 changes: 37 additions & 105 deletions src/content/learn/manipulating-the-dom-with-refs.md
Original file line number Diff line number Diff line change
@@ -256,11 +256,11 @@ export default function CatFriends() {
key={cat}
ref={(node) => {
const map = getMap();
if (node) {
map.set(cat, node);
} else {
map.set(cat, node);

return () => {
map.delete(cat);
}
};
}}
>
<img src={cat} />
@@ -309,42 +309,10 @@ li {
}
```

```json package.json hidden
{
"dependencies": {
"react": "canary",
"react-dom": "canary",
"react-scripts": "^5.0.0"
}
}
```

</Sandpack>

In this example, `itemsRef` doesn't hold a single DOM node. Instead, it holds a [Map](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map) from item ID to a DOM node. ([Refs can hold any values!](/learn/referencing-values-with-refs)) The [`ref` callback](/reference/react-dom/components/common#ref-callback) on every list item takes care to update the Map:

```js
<li
key={cat.id}
ref={node => {
const map = getMap();
if (node) {
// Add to the Map
map.set(cat, node);
} else {
// Remove from the Map
map.delete(cat);
}
}}
>
```

This lets you read individual DOM nodes from the Map later.

<Canary>

This example shows another approach for managing the Map with a `ref` callback cleanup function.

```js
<li
key={cat.id}
@@ -361,81 +329,53 @@ This example shows another approach for managing the Map with a `ref` callback c
>
```

</Canary>
This lets you read individual DOM nodes from the Map later.

<Note>

When Strict Mode is enabled, ref callbacks will run twice in development.

Read more about [how this helps find bugs](/reference/react/StrictMode#fixing-bugs-found-by-re-running-ref-callbacks-in-development) in callback refs.

</Note>

</DeepDive>

## Accessing another component's DOM nodes {/*accessing-another-components-dom-nodes*/}

When you put a ref on a built-in component that outputs a browser element like `<input />`, React will set that ref's `current` property to the corresponding DOM node (such as the actual `<input />` in the browser).
<Pitfall>
Refs are an escape hatch. Manually manipulating _another_ component's DOM nodes can make your code fragile.
</Pitfall>

However, if you try to put a ref on **your own** component, like `<MyInput />`, by default you will get `null`. Here is an example demonstrating it. Notice how clicking the button **does not** focus the input:

<Sandpack>
You can pass refs from parent component to child components [just like any other prop](/learn/passing-props-to-a-component).

```js
```js {3-4,9}
import { useRef } from 'react';

function MyInput(props) {
return <input {...props} />;
function MyInput({ ref }) {
return <input ref={ref} />;
}

export default function MyForm() {
function MyForm() {
const inputRef = useRef(null);

function handleClick() {
inputRef.current.focus();
}

return (
<>
<MyInput ref={inputRef} />
<button onClick={handleClick}>
Focus the input
</button>
</>
);
return <MyInput ref={inputRef} />
}
```

</Sandpack>

To help you notice the issue, React also prints an error to the console:

<ConsoleBlock level="error">

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

</ConsoleBlock>

This happens because by default React does not let a component access the DOM nodes of other components. Not even for its own children! This is intentional. Refs are an escape hatch that should be used sparingly. Manually manipulating _another_ component's DOM nodes makes your code even more fragile.

Instead, components that _want_ to expose their DOM nodes have to **opt in** to that behavior. A component can specify that it "forwards" its ref to one of its children. Here's how `MyInput` can use the `forwardRef` API:

```js
const MyInput = forwardRef((props, ref) => {
return <input {...props} ref={ref} />;
});
```

This is how it works:

1. `<MyInput ref={inputRef} />` tells React to put the corresponding DOM node into `inputRef.current`. However, it's up to the `MyInput` component to opt into that--by default, it doesn't.
2. The `MyInput` component is declared using `forwardRef`. **This opts it into receiving the `inputRef` from above as the second `ref` argument** which is declared after `props`.
3. `MyInput` itself passes the `ref` it received to the `<input>` inside of it.
In the above example, a ref is created in the parent component, `MyForm`, and is passed to the child component, `MyInput`. `MyInput` then passes the ref to `<input>`. Because `<input>` is a [built-in component](/reference/react-dom/components/common) React sets the `.current` property of the ref to the `<input>` DOM element.

Now clicking the button to focus the input works:
The `inputRef` created in `MyForm` now points to the `<input>` DOM element returned by `MyInput`. A click handler created in `MyForm` can access `inputRef` and call `focus()` to set the focus on `<input>`.

<Sandpack>

```js
import { forwardRef, useRef } from 'react';
import { useRef } from 'react';

const MyInput = forwardRef((props, ref) => {
return <input {...props} ref={ref} />;
});
function MyInput({ ref }) {
return <input ref={ref} />;
}

export default function Form() {
export default function MyForm() {
const inputRef = useRef(null);

function handleClick() {
@@ -455,33 +395,27 @@ export default function Form() {

</Sandpack>

In design systems, it is a common pattern for low-level components like buttons, inputs, and so on, to forward their refs to their DOM nodes. On the other hand, high-level components like forms, lists, or page sections usually won't expose their DOM nodes to avoid accidental dependencies on the DOM structure.

<DeepDive>

#### Exposing a subset of the API with an imperative handle {/*exposing-a-subset-of-the-api-with-an-imperative-handle*/}

In the above example, `MyInput` exposes the original DOM input element. This lets the parent component call `focus()` on it. However, this also lets the parent component do something else--for example, change its CSS styles. In uncommon cases, you may want to restrict the exposed functionality. You can do that with `useImperativeHandle`:
In the above example, the ref passed to `MyInput` is passed on to the original DOM input element. This lets the parent component call `focus()` on it. However, this also lets the parent component do something else--for example, change its CSS styles. In uncommon cases, you may want to restrict the exposed functionality. You can do that with [`useImperativeHandle`](/reference/react/useImperativeHandle):

<Sandpack>

```js
import {
forwardRef,
useRef,
useImperativeHandle
} from 'react';
import { useRef, useImperativeHandle } from "react";

const MyInput = forwardRef((props, ref) => {
function MyInput({ ref }) {
const realInputRef = useRef(null);
useImperativeHandle(ref, () => ({
// Only expose focus and nothing else
focus() {
realInputRef.current.focus();
},
}));
return <input {...props} ref={realInputRef} />;
});
return <input ref={realInputRef} />;
};

export default function Form() {
const inputRef = useRef(null);
@@ -493,17 +427,15 @@ export default function Form() {
return (
<>
<MyInput ref={inputRef} />
<button onClick={handleClick}>
Focus the input
</button>
<button onClick={handleClick}>Focus the input</button>
</>
);
}
```

</Sandpack>

Here, `realInputRef` inside `MyInput` holds the actual input DOM node. However, `useImperativeHandle` instructs React to provide your own special object as the value of a ref to the parent component. So `inputRef.current` inside the `Form` component will only have the `focus` method. In this case, the ref "handle" is not the DOM node, but the custom object you create inside `useImperativeHandle` call.
Here, `realInputRef` inside `MyInput` holds the actual input DOM node. However, [`useImperativeHandle`](/reference/react/useImperativeHandle) instructs React to provide your own special object as the value of a ref to the parent component. So `inputRef.current` inside the `Form` component will only have the `focus` method. In this case, the ref "handle" is not the DOM node, but the custom object you create inside [`useImperativeHandle`](/reference/react/useImperativeHandle) call.

</DeepDive>

@@ -615,7 +547,7 @@ export default function TodoList() {
const newTodo = { id: nextId++, text: text };
flushSync(() => {
setText('');
setTodos([ ...todos, newTodo]);
setTodos([ ...todos, newTodo]);
});
listRef.current.lastChild.scrollIntoView({
behavior: 'smooth',
2 changes: 1 addition & 1 deletion src/content/learn/react-compiler.md
Original file line number Diff line number Diff line change
@@ -347,7 +347,7 @@ React Compiler can verify many of the Rules of React statically, and will safely

### How do I know my components have been optimized? {/*how-do-i-know-my-components-have-been-optimized*/}

[React Devtools](/learn/react-developer-tools) (v5.0+) has built-in support for React Compiler and will display a "Memo ✨" badge next to components that have been optimized by the compiler.
[React DevTools](/learn/react-developer-tools) (v5.0+) and [React Native DevTools](https://reactnative.dev/docs/react-native-devtools) have built-in support for React Compiler and will display a "Memo ✨" badge next to components that have been optimized by the compiler.

### Something is not working after compilation {/*something-is-not-working-after-compilation*/}
If you have eslint-plugin-react-compiler installed, the compiler will display any violations of the rules of React in your editor. When it does this, it means that the compiler has skipped over optimizing that component or hook. This is perfectly okay, and the compiler can recover and continue optimizing other components in your codebase. **You don't have to fix all ESLint violations straight away.** You can address them at your own pace to increase the amount of components and hooks being optimized.
21 changes: 3 additions & 18 deletions src/content/learn/react-developer-tools.md
Original file line number Diff line number Diff line change
@@ -53,24 +53,9 @@ Reload your website in the browser now to view it in developer tools.
![React Developer Tools standalone](/images/docs/react-devtools-standalone.png)

## Mobile (React Native) {/*mobile-react-native*/}
React Developer Tools can be used to inspect apps built with [React Native](https://reactnative.dev/) as well.

The easiest way to use React Developer Tools is to install it globally:
```bash
# Yarn
yarn global add react-devtools

# Npm
npm install -g react-devtools
```

Next open the developer tools from the terminal.
```bash
react-devtools
```

It should connect to any local React Native app that's running.
To inspect apps built with [React Native](https://reactnative.dev/), you can use [React Native DevTools](https://reactnative.dev/docs/react-native-devtools), the built-in debugger that deeply integrates React Developer Tools. All features work identically to the browser extension, including native element highlighting and selection.

> Try reloading the app if developer tools doesn't connect after a few seconds.
[Learn more about debugging in React Native.](https://reactnative.dev/docs/debugging)

[Learn more about debugging React Native.](https://reactnative.dev/docs/debugging)
> For versions of React Native earlier than 0.76, please use the standalone build of React DevTools by following the [Safari and other browsers](#safari-and-other-browsers) guide above.
2 changes: 1 addition & 1 deletion src/content/learn/start-a-new-react-project.md
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ Even if you don't need routing or data fetching at first, you'll likely want to

**React frameworks on this page solve problems like these by default, with no extra work from your side.** They let you start very lean and then scale your app with your needs. Each React framework has a community, so finding answers to questions and upgrading tooling is easier. Frameworks also give structure to your code, helping you and others retain context and skills between different projects. Conversely, with a custom setup it's easier to get stuck on unsupported dependency versions, and you'll essentially end up creating your own framework—albeit one with no community or upgrade path (and if it's anything like the ones we've made in the past, more haphazardly designed).

If your app has unusual constraints not served well by these frameworks, or you prefer to solve these problems yourself, you can roll your own custom setup with React. Grab `react` and `react-dom` from npm, set up your custom build process with a bundler like [Vite](https://vitejs.dev/) or [Parcel](https://parceljs.org/), and add other tools as you need them for routing, static generation or server-side rendering, and more.
If your app has unusual constraints not served well by these frameworks, or you prefer to solve these problems yourself, you can roll your own custom setup with React. Grab `react` and `react-dom` from npm, set up your custom build process with a bundler like [Vite](https://vite.dev/) or [Parcel](https://parceljs.org/), and add other tools as you need them for routing, static generation or server-side rendering, and more.

</DeepDive>

Loading