diff --git a/next-env.d.ts b/next-env.d.ts
index 52e831b43..3cd7048ed 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,5 +1,6 @@
///
///
+///
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
+// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/src/components/MDX/Sandpack/ClearButton.tsx b/src/components/MDX/Sandpack/ClearButton.tsx
new file mode 100644
index 000000000..868f9fb66
--- /dev/null
+++ b/src/components/MDX/Sandpack/ClearButton.tsx
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ */
+
+import * as React from 'react';
+import {IconClose} from '../../Icon/IconClose';
+export interface ClearButtonProps {
+ onClear: () => void;
+}
+
+export function ClearButton({onClear}: ClearButtonProps) {
+ return (
+
+ );
+}
diff --git a/src/components/MDX/Sandpack/NavigationBar.tsx b/src/components/MDX/Sandpack/NavigationBar.tsx
index bf2c3186c..d115868dd 100644
--- a/src/components/MDX/Sandpack/NavigationBar.tsx
+++ b/src/components/MDX/Sandpack/NavigationBar.tsx
@@ -17,7 +17,8 @@ import {
useSandpackNavigation,
} from '@codesandbox/sandpack-react/unstyled';
import {OpenInCodeSandboxButton} from './OpenInCodeSandboxButton';
-import {ResetButton} from './ResetButton';
+import {ReloadButton} from './ReloadButton';
+import {ClearButton} from './ClearButton';
import {DownloadButton} from './DownloadButton';
import {IconChevron} from '../../Icon/IconChevron';
import {Listbox} from '@headlessui/react';
@@ -95,7 +96,7 @@ export function NavigationBar({providedFiles}: {providedFiles: Array}) {
// Note: in a real useEvent, onContainerResize would be omitted.
}, [isMultiFile, onContainerResize]);
- const handleReset = () => {
+ const handleClear = () => {
/**
* resetAllFiles must come first, otherwise
* the previous content will appear for a second
@@ -103,13 +104,13 @@ export function NavigationBar({providedFiles}: {providedFiles: Array}) {
*
* Plus, it should only prompt if there's any file changes
*/
- if (
- sandpack.editorState === 'dirty' &&
- confirm('Reset all your edits too?')
- ) {
+ if (sandpack.editorState === 'dirty' && confirm('Clear all your edits?')) {
sandpack.resetAllFiles();
}
+ refresh();
+ };
+ const handleReload = () => {
refresh();
};
@@ -188,7 +189,8 @@ export function NavigationBar({providedFiles}: {providedFiles: Array}) {
className="px-3 flex items-center justify-end text-start"
translate="yes">
-
+
+
{activeFile.endsWith('.tsx') && (
void;
+export interface ReloadButtonProps {
+ onReload: () => void;
}
-export function ResetButton({onReset}: ResetButtonProps) {
+export function ReloadButton({onReload}: ReloadButtonProps) {
return (
);
}
diff --git a/src/content/blog/2025/04/21/react-compiler-rc.md b/src/content/blog/2025/04/21/react-compiler-rc.md
index ecbbb8747..2ebbf3bae 100644
--- a/src/content/blog/2025/04/21/react-compiler-rc.md
+++ b/src/content/blog/2025/04/21/react-compiler-rc.md
@@ -57,23 +57,23 @@ During the RC period, we encourage all React users to try the compiler and provi
As noted in the Beta announcement, React Compiler is compatible with React 17 and up. If you are not yet on React 19, you can use React Compiler by specifying a minimum target in your compiler config, and adding `react-compiler-runtime` as a dependency. You can find docs on this [here](https://react.dev/learn/react-compiler#using-react-compiler-with-react-17-or-18).
## Migrating from eslint-plugin-react-compiler to eslint-plugin-react-hooks {/*migrating-from-eslint-plugin-react-compiler-to-eslint-plugin-react-hooks*/}
-If you have already installed eslint-plugin-react-compiler, you can now remove it and use `eslint-plugin-react-hooks@6.0.0-rc.1`. Many thanks to [@michaelfaith](https://bsky.app/profile/michael.faith) for contributing to this improvement!
+If you have already installed eslint-plugin-react-compiler, you can now remove it and use `eslint-plugin-react-hooks@rc`. Many thanks to [@michaelfaith](https://bsky.app/profile/michael.faith) for contributing to this improvement!
To install:
npm
-{`npm install --save-dev eslint-plugin-react-hooks@6.0.0-rc.1`}
+{`npm install --save-dev eslint-plugin-react-hooks@rc`}
pnpm
-{`pnpm add --save-dev eslint-plugin-react-hooks@6.0.0-rc.1`}
+{`pnpm add --save-dev eslint-plugin-react-hooks@rc`}
yarn
-{`yarn add --dev eslint-plugin-react-hooks@6.0.0-rc.1`}
+{`yarn add --dev eslint-plugin-react-hooks@rc`}
```js
diff --git a/src/content/community/conferences.md b/src/content/community/conferences.md
index 5efaf19ba..6a8087cde 100644
--- a/src/content/community/conferences.md
+++ b/src/content/community/conferences.md
@@ -10,36 +10,6 @@ Bạn có biết về hội nghị React.js ở địa phương hay khu vực c
## Upcoming Conferences {/*upcoming-conferences*/}
-### CityJS London 2025 {/*cityjs-london*/}
-April 23 - 25, 2025. In-person in London, UK
-
-[Website](https://london.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social)
-
-### 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 Norway 2025 {/*react-norway-2025*/}
-June 13, 2025. In-person in Oslo, Norway + remote (virtual event)
-
-[Website](https://reactnorway.com/) - [Twitter](https://x.com/ReactNorway)
-
-### 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 Nexus 2025 {/*react-nexus-2025*/}
-July 03 - 05, 2025. In-person in Bangalore, India
-
-[Website](https://reactnexus.com/) - [Twitter](https://x.com/ReactNexus) - [Bluesky](https://bsky.app/profile/reactnexus.com) - [Linkedin](https://www.linkedin.com/company/react-nexus) - [YouTube](https://www.youtube.com/reactify_in)
-
### React Universe Conf 2025 {/*react-universe-conf-2025*/}
September 2-4, 2025. Wrocław, Poland.
@@ -60,6 +30,12 @@ October 31 - November 01, 2025. In-person in Goa, India (hybrid event) + Oct 15
[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)
+
+### CityJS New Delhi 2025 {/*cityjs-newdelhi*/}
+November 6-7, 2025. In-person in New Delhi, India
+
+[Website](https://india.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social)
+
### React Summit US 2025 {/*react-summit-us-2025*/}
November 18 - 21, 2025. In-person in New York, USA + remote (hybrid event)
@@ -70,13 +46,49 @@ November 28 & December 1, 2025. In-person in London, UK + online (hybrid event)
[Website](https://reactadvanced.com/) - [Twitter](https://x.com/reactadvanced)
+### React Paris 2026 {/*react-paris-2026*/}
+March 26 - 27, 2026. In-person in Paris, France (hybrid event)
+
+[Website](https://react.paris/) - [Twitter](https://x.com/BeJS_)
+
## Past Conferences {/*past-conferences*/}
+
+### React Nexus 2025 {/*react-nexus-2025*/}
+July 03 - 05, 2025. In-person in Bangalore, India
+
+[Website](https://reactnexus.com/) - [Twitter](https://x.com/ReactNexus) - [Bluesky](https://bsky.app/profile/reactnexus.com) - [Linkedin](https://www.linkedin.com/company/react-nexus) - [YouTube](https://www.youtube.com/reactify_in)
+
+### 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 Norway 2025 {/*react-norway-2025*/}
+June 13, 2025. In-person in Oslo, Norway + remote (virtual event)
+
+[Website](https://reactnorway.com/) - [Twitter](https://x.com/ReactNorway)
+
+### 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)
+
+### 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 London 2025 {/*cityjs-london*/}
+April 23 - 25, 2025. In-person in London, UK
+
+[Website](https://london.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social)
+
### React Paris 2025 {/*react-paris-2025*/}
March 20 - 21, 2025. In-person in Paris, France (hybrid event)
-[Website](https://react.paris/) - [Twitter](https://x.com/BeJS_)
+[Website](https://react.paris/) - [Twitter](https://x.com/BeJS_) - [YouTube](https://www.youtube.com/playlist?list=PL53Z0yyYnpWitP8Zv01TSEQmKLvuRh_Dj)
### React Native Connection 2025 {/*react-native-connection-2025*/}
April 3 (Reanimated Training) + April 4 (Conference), 2025. Paris, France.
diff --git a/src/content/learn/react-compiler/installation.md b/src/content/learn/react-compiler/installation.md
index 3606c9c6d..a40b1f5af 100644
--- a/src/content/learn/react-compiler/installation.md
+++ b/src/content/learn/react-compiler/installation.md
@@ -176,16 +176,7 @@ Install the ESLint plugin:
npm install -D eslint-plugin-react-hooks@rc
-Then enable the compiler rule in your ESLint configuration:
-
-```js {3}
-// .eslintrc.js
-module.exports = {
- rules: {
- 'react-hooks/react-compiler': 'error',
- },
-};
-```
+If you haven't already configured eslint-plugin-react-hooks, follow the [installation instructions in the readme](https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/README.md#installation). The compiler rule is enabled by default in the latest RC, so no additional configuration is needed.
The ESLint rule will:
- Identify violations of the [Rules of React](/reference/rules)
diff --git a/src/content/learn/react-compiler/introduction.md b/src/content/learn/react-compiler/introduction.md
index 440c66ab6..96fdf70db 100644
--- a/src/content/learn/react-compiler/introduction.md
+++ b/src/content/learn/react-compiler/introduction.md
@@ -154,7 +154,7 @@ Next.js users can enable the swc-invoked React Compiler by using [v15.3.1](https
## What should I do about useMemo, useCallback, and React.memo? {/*what-should-i-do-about-usememo-usecallback-and-reactmemo*/}
-If you are using React Compiler, [`useMemo`](/reference/react/useMemo), [`useCallback`](/reference/react/useCallback), and [`React.memo`](/reference/react/memo) can be removed. React Compiler adds automatic memoization more precisely and granularly than is possible with these hooks. If you choose to keep manual memoization, React Compiler will analyze them and determine if your manual memoization matches its automatically inferred memoization. If there isn't a match, the compiler will choose to bail out of optimizing that component.
+React Compiler adds automatic memoization more precisely and granularly than is possible with [`useMemo`](/reference/react/useMemo), [`useCallback`](/reference/react/useCallback), and [`React.memo`](/reference/react/memo). If you choose to keep manual memoization, React Compiler will analyze them and determine if your manual memoization matches its automatically inferred memoization. If there isn't a match, the compiler will choose to bail out of optimizing that component.
This is done out of caution as a common anti-pattern with manual memoization is using it for correctness. This means your app depends on specific values being memoized to work properly. For example, in order to prevent an infinite loop, you may have memoized some values to stop a `useEffect` call from firing. This breaks the Rules of React, but since it can potentially be dangerous for the compiler to automatically remove manual memoization, the compiler will just bail out instead. You should manually remove your handwritten memoization and verify that your app still works as expected.
diff --git a/src/content/reference/react-dom/components/index.md b/src/content/reference/react-dom/components/index.md
index ec2e1d2ee..586663398 100644
--- a/src/content/reference/react-dom/components/index.md
+++ b/src/content/reference/react-dom/components/index.md
@@ -162,23 +162,137 @@ Similar to the [DOM standard,](https://developer.mozilla.org/en-US/docs/Web/API/
### Custom HTML elements {/*custom-html-elements*/}
-If you render a tag with a dash, like ``, React will assume you want to render a [custom HTML element.](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements) In React, rendering custom elements works differently from rendering built-in browser tags:
-
-- All custom element props are serialized to strings and are always set using attributes.
-- Custom elements accept `class` rather than `className`, and `for` rather than `htmlFor`.
+If you render a tag with a dash, like ``, React will assume you want to render a [custom HTML element.](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements)
If you render a built-in browser HTML element with an [`is`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/is) attribute, it will also be treated as a custom element.
-
+#### Setting values on custom elements {/*attributes-vs-properties*/}
+
+Custom elements have two methods of passing data into them:
+
+1) Attributes: Which are displayed in markup and can only be set to string values
+2) Properties: Which are not displayed in markup and can be set to arbitrary JavaScript values
+
+By default, React will pass values bound in JSX as attributes:
+
+```jsx
+
+```
+
+Non-string JavaScript values passed to custom elements will be serialized by default:
+
+```jsx
+// Will be passed as `"1,2,3"` as the output of `[1,2,3].toString()`
+
+```
+
+React will, however, recognize an custom element's property as one that it may pass arbitrary values to if the property name shows up on the class during construction:
+
+
+
+```js src/index.js hidden
+import {MyElement} from './MyElement.js';
+import { createRoot } from 'react-dom/client';
+import {App} from "./App.js";
+
+customElements.define('my-element', MyElement);
+
+const root = createRoot(document.getElementById('root'))
+root.render();
+```
+
+```js src/MyElement.js active
+export class MyElement extends HTMLElement {
+ constructor() {
+ super();
+ // The value here will be overwritten by React
+ // when initialized as an element
+ this.value = undefined;
+ }
+
+ connectedCallback() {
+ this.innerHTML = this.value.join(", ");
+ }
+}
+```
-[A future version of React will include more comprehensive support for custom elements.](https://github.com/facebook/react/issues/11347#issuecomment-1122275286)
+```js src/App.js
+export function App() {
+ return
+}
+```
-You can try it by upgrading React packages to the most recent experimental version:
+
+
+#### Listening for events on custom elements {/*custom-element-events*/}
+
+A common pattern when using custom elements is that they may dispatch [`CustomEvent`s](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) rather than accept a function to call when an event occur. You can listen for these events using an `on` prefix when binding to the event via JSX.
+
+
+
+```js src/index.js hidden
+import {MyElement} from './MyElement.js';
+import { createRoot } from 'react-dom/client';
+import {App} from "./App.js";
+
+customElements.define('my-element', MyElement);
+
+const root = createRoot(document.getElementById('root'))
+root.render();
+```
+
+```javascript src/MyElement.js
+export class MyElement extends HTMLElement {
+ constructor() {
+ super();
+ this.test = undefined;
+ this.emitEvent = this._emitEvent.bind(this);
+ }
+
+ _emitEvent() {
+ const event = new CustomEvent('speak', {
+ detail: {
+ message: 'Hello, world!',
+ },
+ });
+ this.dispatchEvent(event);
+ }
+
+ connectedCallback() {
+ this.el = document.createElement('button');
+ this.el.innerText = 'Say hi';
+ this.el.addEventListener('click', this.emitEvent);
+ this.appendChild(this.el);
+ }
+
+ disconnectedCallback() {
+ this.el.removeEventListener('click', this.emitEvent);
+ }
+}
+```
+
+```jsx src/App.js active
+export function App() {
+ return (
+ console.log(e.detail.message)}
+ >
+ )
+}
+```
+
+
+
+
-- `react@experimental`
-- `react-dom@experimental`
+Events are case-sensitive and support dashes (`-`). Preserve the casing of the event and include all dashes when listening for custom element's events:
-Experimental versions of React may contain bugs. Don't use them in production.
+```jsx
+// Listens for `say-hi` events
+
+// Listens for `sayHi` events
+
+```
---
diff --git a/src/content/reference/react/Activity.md b/src/content/reference/react/Activity.md
index f437a74da..09b79c79f 100644
--- a/src/content/reference/react/Activity.md
+++ b/src/content/reference/react/Activity.md
@@ -51,7 +51,7 @@ While hidden, children still re-render in response to new props, albeit at a low
When the boundary becomes visible again, React will reveal the children with their previous state restored, and re-create their Effects.
-In this way, Activity can thought of as a mechanism for rendering "background activity". Rather than completely discarding content that's likely to become visible again, you can use Activity to maintain and restore that content's UI and internal state, while ensuring hidden content has no unwanted side effects.
+In this way, Activity can be thought of as a mechanism for rendering "background activity". Rather than completely discarding content that's likely to become visible again, you can use Activity to maintain and restore that content's UI and internal state, while ensuring that your hidden content has no unwanted side effects.
[See more examples below.](#usage)
@@ -62,7 +62,7 @@ In this way, Activity can thought of as a mechanism for rendering "background ac
#### Caveats {/*caveats*/}
-- When used with ``, hidden activities that reveal in a transition will activate an "enter" animation. Visible Activities hidden in a transition will activate an "exit" animation.
+- If an Activity is rendered inside of a [ViewTransition](/reference/react/ViewTransition), and it becomes visible as a result of an update caused by [startTransition](/reference/react/startTransition), it will activate the ViewTransition's `enter` animation. If it becomes hidden, it will activate its `exit` animation.
---
@@ -70,7 +70,7 @@ In this way, Activity can thought of as a mechanism for rendering "background ac
### Restoring the state of hidden components {/*restoring-the-state-of-hidden-components*/}
-Typically in React, when you want to conditionally show or hide a component, you mount and unmount it:
+In React, when you want to conditionally show or hide a component, you typically mount or unmount it based on that condition:
```jsx
{isShowingSidebar && (
@@ -88,11 +88,11 @@ When you hide a component using an Activity boundary instead, React will "save"
```
-This makes it possible to restore components to their previous state.
+This makes it possible to hide and then later restore components in the state they were previously in.
-The following example has a sidebar with an expandable section – you can press "Overview" to reveal the three subitems below it. The main app area also has a button that hides and shows the sidebar.
+The following example has a sidebar with an expandable section. You can press "Overview" to reveal the three subitems below it. The main app area also has a button that hides and shows the sidebar.
-Try expanding the Overview section, then toggling the sidebar closed and open:
+Try expanding the Overview section, and then toggling the sidebar closed then open: