diff --git a/docs/_canary-channel-api-warning.mdx b/docs/_canary-channel-api-warning.mdx
index 2c1ae5cf423..8f1af9f8b46 100644
--- a/docs/_canary-channel-api-warning.mdx
+++ b/docs/_canary-channel-api-warning.mdx
@@ -2,6 +2,6 @@
**This API is currently only available in React Native’s Canary and Experimental channels.**
-If you want to try it out, please [enable the Canary Channel](releases/release-levels) in your app.
+If you want to try it out, please [enable the Canary Channel](release-levels) in your app.
:::
diff --git a/docs/_experimental-channel-api-warning.mdx b/docs/_experimental-channel-api-warning.mdx
index 92a7b2c8c2f..f6bb132151d 100644
--- a/docs/_experimental-channel-api-warning.mdx
+++ b/docs/_experimental-channel-api-warning.mdx
@@ -4,6 +4,6 @@
Experimental APIs may contain bugs and are likely to change in a future version of React Native. Don't use them in production.
-If you want to try it out, please [enable the Experimental Channel](releases/release-levels) in your app.
+If you want to try it out, please [enable the Experimental Channel](release-levels) in your app.
:::
diff --git a/docs/releases/release-levels.md b/docs/release-levels.md
similarity index 100%
rename from docs/releases/release-levels.md
rename to docs/release-levels.md
diff --git a/docs/releases/releases.md b/docs/releases/releases.md
deleted file mode 100644
index c6a9bb52c6e..00000000000
--- a/docs/releases/releases.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-id: releases
-title: Releases Overview
----
-
-import ReleasesTable from '@site/src/components/releases/ReleasesTable';
-
-New React Native releases are shipped **every two months**, usually resulting in six (6) new minors per year.
-
-Below is the schedule and current status of recent and upcoming React Native releases:
-
-
-
-The different support level presented in the table are defined as such:
-
-- **Future**
- - After a new version branch gets cut, creating new Release Candidates to allow the community to test the upcoming version is very important. New RC releases are done at a high pace, as soon as viable.
-- **Active**
- - Stable releases in active support receive frequent updates. Latest stable has the highest priority, and at the start of its stable cycle (right after .0 is released) multiple patches will be done as soon as possible to stabilize the version and ensure a good upgrade experience to the community.
-- **End of Cycle**
- - A version in this support bracket will receive less patches, unless some important regressions need to be addressed. Once a next version becomes the new latest stable, before the version in EoC moves over into Unsupported one last patch released will be produced with the latest receive pick requests.
-- **Unsupported**
- - When a version is in the unsupported stage, no new released are to be expected. Only very important regressions might create exceptions to this rule; it is recommended that codebases using an unsupported version upgrade as soon as possible.
-
-## Commitment to Stability
-
-In order to support users upgrading React Native versions, we’re committed to maintain the **latest 3 minor series** (e.g. 0.78.x, 0.77.x and 0.76.x when 0.78 is the latest release).
-
-For those releases we’ll be publishing regular updates and bug fixes.
-
-You can read more about our support policy on [the react-native-releases working group](https://github.com/reactwg/react-native-releases/blob/main/docs/support.md).
-
-More information on our versioning, and what we consider a breaking change is available in our [versioning policy](./releases/versioning-policy) page.
diff --git a/docs/upgrading.md b/docs/upgrading.md
index 06158ffa652..8d052ef8980 100644
--- a/docs/upgrading.md
+++ b/docs/upgrading.md
@@ -1,6 +1,6 @@
---
id: upgrading
-title: Upgrading to new versions
+title: Upgrading to New Versions
---
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants';
diff --git a/vercel.json b/vercel.json
index 6d968ac3da5..0ad67f62d34 100644
--- a/vercel.json
+++ b/vercel.json
@@ -91,12 +91,42 @@
},
{
"source": "/contributing/versioning-policy",
- "destination": "/docs/next/releases/versioning-policy",
+ "destination": "/releases/versioning-policy",
"permanent": true
},
{
"source": "/releases/release-candidate-minor",
- "destination": "/docs/next/releases/versioning-policy",
+ "destination": "/releases/versioning-policy",
+ "permanent": true
+ },
+ {
+ "source": "/docs/releases",
+ "destination": "/releases/overview",
+ "permanent": true
+ },
+ {
+ "source": "/docs/next/releases",
+ "destination": "/releases/overview",
+ "permanent": true
+ },
+ {
+ "source": "/docs/releases/versioning-policy",
+ "destination": "/releases/versioning-policy",
+ "permanent": true
+ },
+ {
+ "source": "/docs/next/releases/versioning-policy",
+ "destination": "/releases/versioning-policy",
+ "permanent": true
+ },
+ {
+ "source": "/docs/releases/release-levels",
+ "destination": "/docs/release-levels",
+ "permanent": true
+ },
+ {
+ "source": "/docs/next/releases/release-levels",
+ "destination": "/docs/next/release-levels",
"permanent": true
},
{
diff --git a/website/blog/2025-12-10-react-native-0.83.mdx b/website/blog/2025-12-10-react-native-0.83.mdx
index d433aa6d270..4093cc1e2d6 100644
--- a/website/blog/2025-12-10-react-native-0.83.mdx
+++ b/website/blog/2025-12-10-react-native-0.83.mdx
@@ -268,7 +268,7 @@ We're working hard to make React Native releases more predictable and easier to
If you are on React Native 0.82, you should be able to upgrade your app to React Native 0.83 without any changes to your app code.
-To learn more about what we consider a breaking change, have a look at [this article](/docs/releases/versioning-policy#what-is-a-breaking-change).
+To learn more about what we consider a breaking change, have a look at [this article](/releases/versioning-policy#what-is-a-breaking-change).
## Deprecations
diff --git a/website/blog/2026-04-07-react-native-0.85.mdx b/website/blog/2026-04-07-react-native-0.85.mdx
index 90525a553e1..8e9af9a4e86 100644
--- a/website/blog/2026-04-07-react-native-0.85.mdx
+++ b/website/blog/2026-04-07-react-native-0.85.mdx
@@ -52,7 +52,7 @@ In Animated, you can now animate layout props with native driver (the [limitatio
You can find more examples under [`react-native/packages/rn-tester/js/examples/AnimationBackend/`](https://github.com/facebook/react-native/tree/main/packages/rn-tester/js/examples/AnimationBackend).
-To opt in, you can enable the experimental channel of React Native [as described in this page](/docs/releases/release-levels).
+To opt in, you can enable the experimental channel of React Native [as described in this page](/docs/release-levels).
:::info
diff --git a/website/blog/2026-06-11-react-native-0.86.mdx b/website/blog/2026-06-11-react-native-0.86.mdx
index 0e3a39b7d50..8d8e0ec705e 100644
--- a/website/blog/2026-06-11-react-native-0.86.mdx
+++ b/website/blog/2026-06-11-react-native-0.86.mdx
@@ -53,7 +53,7 @@ React Native 0.86 has **no user-facing breaking changes**.
If you are on React Native 0.85, you should be able to upgrade your app to React Native 0.86 without any changes to your app code.
-To learn more about what we consider a breaking change, have a look at [this article](/docs/releases/versioning-policy#what-is-a-breaking-change).
+To learn more about what we consider a breaking change, have a look at [this article](/releases/versioning-policy#what-is-a-breaking-change).
## Deprecations
diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts
index b0a53998ede..04af0c9015f 100644
--- a/website/docusaurus.config.ts
+++ b/website/docusaurus.config.ts
@@ -212,6 +212,8 @@ const config: Config = {
require.resolve('./src/css/index.scss'),
require.resolve('./src/css/showcase.scss'),
require.resolve('./src/css/versions.scss'),
+ require.resolve('./src/css/docs-secondary-nav.scss'),
+ require.resolve('./src/css/releases.scss'),
],
},
gtag: {
@@ -267,6 +269,16 @@ const config: Config = {
...commonDocsOptions,
} satisfies PluginContentDocs.Options,
],
+ [
+ 'content-docs',
+ {
+ id: 'releases',
+ path: 'releases',
+ routeBasePath: '/releases',
+ sidebarPath: require.resolve('./sidebarsReleases'),
+ ...commonDocsOptions,
+ } satisfies PluginContentDocs.Options,
+ ],
[
'@docusaurus/plugin-pwa',
{
@@ -426,33 +438,22 @@ const config: Config = {
style: 'dark',
items: [
{
- label: 'Development',
type: 'dropdown',
+ label: 'Docs',
position: 'right',
items: [
- {
- label: 'Guides',
- type: 'doc',
- docId: 'getting-started',
- },
- {
- label: 'Components',
- type: 'doc',
- docId: 'components-and-apis',
- },
- {
- label: 'APIs',
- type: 'doc',
- docId: 'accessibilityinfo',
- },
- {
- label: 'Architecture',
- type: 'doc',
- docId: 'architecture-overview',
- docsPluginId: 'architecture',
- },
+ {label: 'Guides', to: '/docs/getting-started'},
+ {label: 'Components', to: '/docs/components-and-apis'},
+ {label: 'APIs', to: '/docs/accessibilityinfo'},
+ {label: 'Architecture', to: '/architecture/overview'},
],
},
+ {
+ to: '/releases/overview',
+ label: 'Releases',
+ position: 'right',
+ activeBaseRegex: '^/(releases|versions)',
+ },
{
type: 'doc',
docId: 'overview',
@@ -477,17 +478,6 @@ const config: Config = {
label: 'Blog',
position: 'right',
},
- {
- type: 'docsVersionDropdown',
- position: 'left',
- dropdownActiveClassDisabled: true,
- dropdownItemsAfter: [
- {
- to: '/versions',
- label: 'All versions',
- },
- ],
- },
{
href: 'https://github.com/facebook/react-native',
'aria-label': 'GitHub repository',
diff --git a/website/releases/branches.md b/website/releases/branches.md
new file mode 100644
index 00000000000..48076af83ea
--- /dev/null
+++ b/website/releases/branches.md
@@ -0,0 +1,29 @@
+---
+title: Branches
+sidebar_label: Branches
+---
+
+import IconExternalLink from '@theme/Icon/ExternalLink';
+
+Each React Native release pins a specific set of platform components — the versions of React, Hermes, Yoga, and other core pieces it ships with.
+
+The table below indicates what's included in the React Native platform for each release version, read from the tip of the corresponding `X-stable` branch in [`react/react-native`](https://github.com/react/react-native).
+
+## Platform Versions
+
+
diff --git a/website/releases/overview.md b/website/releases/overview.md
new file mode 100644
index 00000000000..5297eb77f54
--- /dev/null
+++ b/website/releases/overview.md
@@ -0,0 +1,60 @@
+---
+title: Releases Overview
+sidebar_label: Overview
+---
+
+import ReleasesTable from '@site/src/components/releases/ReleasesTable';
+
+## Schedule
+
+New React Native releases are shipped **every two months**, usually resulting in six (6) new minors per year.
+
+Below is the schedule and current status of recent and upcoming React Native releases:
+
+
+
+
+
+### Commitment to Stability
+
+In order to support users upgrading React Native versions, we’re committed to maintain the **latest 3 minor series** (e.g. 0.78.x, 0.77.x and 0.76.x when 0.78 is the latest release).
+
+For these releases we’ll be publishing regular updates and bug fixes.
+
+You can read more about our support policy on [the react-native-releases working group](https://github.com/reactwg/react-native-releases/blob/main/docs/support.md).
+
+For more information on versioning and what we consider a breaking change, see our [Versioning Policy](/releases/versioning-policy).
+
+### Support definitions
+
+The different support levels presented in the table are defined as follows:
+
+- **Future**
+ - After a new version branch gets cut, creating new Release Candidates to allow the community to test the upcoming version is very important. New RC releases are done at a high pace, as soon as viable.
+- **Active**
+ - Stable releases in active support receive frequent updates. Latest stable has the highest priority, and at the start of its stable cycle (right after .0 is released) multiple patches will be done as soon as possible to stabilize the version and ensure a good upgrade experience to the community.
+- **End of Cycle**
+ - A version in this support bracket will receive less patches, unless some important regressions need to be addressed. Once a next version becomes the new latest stable, before the version in EoC moves over into Unsupported one last patch released will be produced with the latest receive pick requests.
+- **Unsupported**
+ - When a version is in the unsupported stage, no new released are to be expected. Only very important regressions might create exceptions to this rule; it is recommended that codebases using an unsupported version upgrade as soon as possible.
+
+## Release channels
+
+React Native is published to [npm](https://www.npmjs.com/package/react-native) under three release channels, each identified by an npm [dist-tag](https://docs.npmjs.com/cli/v10/commands/npm-dist-tag). They trade stability off against how early you receive new changes.
+
+| Channel | Install | Stability | Use it for |
+| --------- | ---------------------- | -------------------- | ---------------------------------- |
+| `latest` | `react-native@latest` | Stable | Production apps |
+| `next` | `react-native@next` | ⚠️ Release candidate | Testing an upcoming release |
+| `nightly` | `react-native@nightly` | ⚠️ Unstable | Tracking `main` for early feedback |
+
+:::note
+
+**Release candidates and nightlies are not intended for production use.** This section will be most relevant to developers who work on frameworks, libraries, or developer tooling. Developers who use React Native primarily to build user-facing applications should not need to worry about release channels other than `latest`.
+
+:::
+
+- **Release Candidates**
+ - Published under the `next` tag ahead of every stable release, starting at `rc.0` (versioned like `0.79.0-rc.0`).
+- **Nightlies**
+ - Published daily from the `main` branch of [`react/react-native`](https://github.com/react/react-native), versioned like `0.80.0-nightly--` (`` is the build date, `` the source commit).
diff --git a/docs/releases/versioning-policy.md b/website/releases/versioning-policy.md
similarity index 59%
rename from docs/releases/versioning-policy.md
rename to website/releases/versioning-policy.md
index 1b37c94bdc2..e211778308b 100644
--- a/docs/releases/versioning-policy.md
+++ b/website/releases/versioning-policy.md
@@ -2,15 +2,9 @@
title: Versioning Policy
---
-This page describes the versioning policy we follow for the `react-native` package.
+This page describes our versioning policy for `react-native` and the packages under the `@react-native` scope.
-We test each version of React Native thoroughly, both with manual and automated tests, to ensure the quality doesn't regress.
-
-The `stable` channel of React Native follows the 0.x.y release policy described below.
-
-React Native also offers a `nightly` release channel to encourage early feedback on experimental features.
-
-This page describes our approach to version numbers for `react-native` and for packages under the `@react-native` scope.
+The `stable` channel follows the 0.x.y release policy described below, and every version is tested thoroughly — both manually and automatically — so quality doesn't regress. We also publish a `nightly` channel to encourage early feedback on experimental features.
## Stable Release Versions
@@ -26,13 +20,13 @@ Stable releases are shipped regularly, with the latest tagged as `latest` on NPM
A series of releases under the same minor number is called a **minor series** (e.g. 0.76.x is the minor series for 0.76.0, 0.76.1, 0.76.2, etc.).
-You can read more about our **commitment to stability** in [the releases page](./).
+You can read more about our **commitment to stability** on the [Releases Overview](/releases/overview#commitment-to-stability).
### Breaking changes
Breaking changes are inconvenient for everyone, and we’re trying to minimize them to the bare minimum. All the breaking changes we ship in each stable release will be highlighted in:
-- The _Breaking_ and the _Removed_ section of [the React Native Changelog](https://github.com/facebook/react-native/blob/main/CHANGELOG.md)
+- The _Breaking_ and the _Removed_ section of [the React Native Changelog](https://github.com/react/react-native/blob/main/CHANGELOG.md)
- Each release blogpost in the _Breaking Changes_ section
For each breaking change we’re committed to explaining the reasoning behind it, provide a replacement API if possible, and minimize the impact on final users.
@@ -75,37 +69,3 @@ Once an API is deprecated, it will remain available **also** for the **following
For example: if an API is deprecated in React Native 0.76.x, it will still be available in 0.77.x and won’t be removed sooner than React Native 0.78.x.
Sometimes we decide to keep a deprecated API for a longer time, if we feel that the ecosystem needs more time to migrate away from it. For those APIs we generally provide warnings to help users migrate away from them.
-
-## Release channels
-
-React Native relies on a thriving open source community to file bug reports, open pull requests, and submit RFCs. To encourage feedback we do support several release channels.
-
-:::note
-This section will be most relevant to developers who work on frameworks, libraries, or developer tooling. Developers who use React Native primarily to build user-facing applications should not need to worry about release channels other than latest.
-:::
-
-### latest
-
-`latest` is for stable, semver React Native releases. It’s what you get when you install React Native from npm. This is the channel you’re already using today. User-facing applications that consume React Native directly use this channel.
-
-We publish a newer minor series of React Native regularly, and we update the `latest` tag to reflect the latest stable version.
-
-### next
-
-Before we declare a new React Native release stable, we publish a series of **release candidate**, starting from RC0. Those versions are pre-release versions (following the versioning schema `0.79.0-rc.0`) and are tagged as `next` on NPM.
-
-When a new branch cut happens, and RCs start to get published on NPM and GitHub, it’s a good idea to test your library/framework against a `next` version of React Native.
-
-That will ensure that your project will keep on working well with the upcoming versions of React Native.
-
-However, do not use prereleases/RCs in user-facing applications directly as they’re not considered production ready.
-
-### nightly
-
-We also publish a `nightly` release channel. Nightlies are published every day starting from the `main` branch of [facebook/react-native](https://github.com/facebook/react-native). Nightlies are considered unstable versions of React Native and are not recommended for production use.
-
-Nightlies follow the versioning schema as `0.80.0-nightly--` where `` is the date of the nightly and `` is the SHA of the commit that was used to publish this nightly.
-
-The nightly releases are provided for testing purposes only, and we provide no guarantees that behavior won’t change between nightlies. They do not follow the semver protocol that we use for releases from latest/next.
-
-It is a good idea to set up a CI workflow to test your library against a react-native@nightly version every day, to make sure your library will keep on working with future releases.
diff --git a/website/sidebars.ts b/website/sidebars.ts
index 8f14145c3a3..363f0c5c05b 100644
--- a/website/sidebars.ts
+++ b/website/sidebars.ts
@@ -28,6 +28,7 @@ export default {
'libraries',
'typescript',
'strict-typescript-api',
+ 'release-levels',
'upgrading',
],
'UI & Interaction': [
@@ -63,11 +64,6 @@ export default {
items: ['accessibility'],
},
],
- Releases: [
- 'releases/releases',
- 'releases/release-levels',
- 'releases/versioning-policy',
- ],
Debugging: [
'debugging',
'react-native-devtools',
diff --git a/website/sidebarsCommunity.ts b/website/sidebarsCommunity.ts
index cbe83d78989..d517a6794b6 100644
--- a/website/sidebarsCommunity.ts
+++ b/website/sidebarsCommunity.ts
@@ -1,13 +1,5 @@
import type {SidebarsConfig} from '@docusaurus/plugin-content-docs';
export default {
- community: [
- {
- type: 'category',
- label: 'Community',
- collapsed: false,
- collapsible: false,
- items: ['overview', 'staying-updated', 'communities', 'support'],
- },
- ],
+ community: ['overview', 'staying-updated', 'communities', 'support'],
} satisfies SidebarsConfig;
diff --git a/website/sidebarsReleases.ts b/website/sidebarsReleases.ts
new file mode 100644
index 00000000000..5ccef8a3cab
--- /dev/null
+++ b/website/sidebarsReleases.ts
@@ -0,0 +1,14 @@
+import type {SidebarsConfig} from '@docusaurus/plugin-content-docs';
+
+export default {
+ releases: [
+ 'overview',
+ 'branches',
+ 'versioning-policy',
+ {
+ type: 'link',
+ label: 'Docs Versions',
+ href: '/versions',
+ },
+ ],
+} satisfies SidebarsConfig;
diff --git a/website/src/components/DocsSecondaryNav/index.tsx b/website/src/components/DocsSecondaryNav/index.tsx
new file mode 100644
index 00000000000..638ebcd3042
--- /dev/null
+++ b/website/src/components/DocsSecondaryNav/index.tsx
@@ -0,0 +1,234 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React, {useEffect, useRef, useState} from 'react';
+import clsx from 'clsx';
+import Link from '@docusaurus/Link';
+import {useLocation} from '@docusaurus/router';
+import {useActiveDocContext} from '@docusaurus/plugin-content-docs/client';
+import DocsVersionDropdownNavbarItem from '@theme/NavbarItem/DocsVersionDropdownNavbarItem';
+import CopyPageButton from 'docusaurus-plugin-copy-page-button/react';
+
+import styles from './styles.module.css';
+
+// The entry points that used to live under the navbar "Development" dropdown.
+const SECTION_LINKS = [
+ {label: 'Guides', to: '/docs/getting-started'},
+ {label: 'Components', to: '/docs/components-and-apis'},
+ {label: 'APIs', to: '/docs/accessibilityinfo'},
+ {label: 'Architecture', to: '/architecture/overview'},
+] as const;
+
+// Guides, Components and APIs all share the /docs/ URL space, so the active
+// section is read from the current doc's sidebar rather than the pathname.
+const SECTION_BY_SIDEBAR: Record = {
+ docs: 'Guides',
+ components: 'Components',
+ api: 'APIs',
+ architecture: 'Architecture',
+};
+
+type Section = {
+ title: string;
+ // The active entry to show on the dropdown toggle, or null to hide the
+ // dropdown entirely (sections outside the Docs area).
+ activeSectionLink: string | null;
+ // A "return to index" link shown to the right of the heading, or null.
+ backLink: {label: string; href: string} | null;
+ showCopyButton: boolean;
+};
+
+function getSection(
+ pathname: string,
+ sidebarName: string | undefined
+): Section {
+ if (pathname.startsWith('/blog')) {
+ // The index and pagination are the blog listing itself; tags, archive,
+ // authors and individual posts all link back to it via "All posts".
+ const isBlogIndex =
+ pathname === '/blog' ||
+ pathname === '/blog/' ||
+ pathname.startsWith('/blog/page/');
+ // Copy page is only meaningful on an individual post, not on the listing or
+ // the other list-style blog routes (tags, archive, authors).
+ const isBlogPost =
+ !isBlogIndex &&
+ !pathname.startsWith('/blog/tags') &&
+ !pathname.startsWith('/blog/archive') &&
+ !pathname.startsWith('/blog/authors');
+ return {
+ title: 'Blog',
+ activeSectionLink: null,
+ backLink: isBlogIndex ? null : {label: 'All posts', href: '/blog'},
+ showCopyButton: isBlogPost,
+ };
+ }
+ if (pathname.startsWith('/community')) {
+ return {
+ title: 'Community',
+ activeSectionLink: null,
+ backLink: null,
+ showCopyButton: true,
+ };
+ }
+ if (pathname.startsWith('/contributing')) {
+ return {
+ title: 'Contributing',
+ activeSectionLink: null,
+ backLink: null,
+ showCopyButton: true,
+ };
+ }
+ if (pathname.startsWith('/releases') || pathname.startsWith('/versions')) {
+ // The releases docs and the standalone /versions listing share a "Releases"
+ // heading. Copy page applies to the releases docs, not the versions list.
+ return {
+ title: 'Releases',
+ activeSectionLink: null,
+ backLink: null,
+ showCopyButton: pathname.startsWith('/releases'),
+ };
+ }
+ // Docs area (main docs + architecture): the active section follows the doc's
+ // sidebar (Guides / Components / APIs / Architecture).
+ return {
+ title: 'Docs',
+ activeSectionLink: sidebarName
+ ? (SECTION_BY_SIDEBAR[sidebarName] ?? null)
+ : null,
+ backLink: null,
+ showCopyButton: true,
+ };
+}
+
+function SectionDropdown({activeLabel}: {activeLabel: string}) {
+ const [open, setOpen] = useState(false);
+ const containerRef = useRef(null);
+
+ useEffect(() => {
+ if (!open) {
+ return undefined;
+ }
+ const onDocumentClick = (event: MouseEvent) => {
+ if (
+ containerRef.current &&
+ !containerRef.current.contains(event.target as Node)
+ ) {
+ setOpen(false);
+ }
+ };
+ document.addEventListener('click', onDocumentClick);
+ return () => document.removeEventListener('click', onDocumentClick);
+ }, [open]);
+
+ return (
+
+
+
+ {SECTION_LINKS.map(link => (
+
+ setOpen(false)}>
+ {link.label}
+
+
+ ))}
+
+
+ );
+}
+
+export default function DocsSecondaryNav({
+ sidebarName,
+}: {
+ sidebarName?: string;
+}) {
+ const {pathname} = useLocation();
+ const {title, activeSectionLink, backLink, showCopyButton} = getSection(
+ pathname,
+ sidebarName
+ );
+ // The docs version dropdown belongs to the main docs; it self-hides elsewhere.
+ const {activeVersion, activeDoc} = useActiveDocContext('default');
+ const showVersionDropdown = Boolean(activeDoc);
+ const isNextVersion = activeVersion?.name === 'current';
+
+ return (
+
+ );
+}
diff --git a/website/src/components/DocsSecondaryNav/styles.module.css b/website/src/components/DocsSecondaryNav/styles.module.css
new file mode 100644
index 00000000000..04dedf7cd2c
--- /dev/null
+++ b/website/src/components/DocsSecondaryNav/styles.module.css
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+.secondaryNav {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 1rem;
+ height: var(--rn-subnav-height);
+ padding: 0 1.5rem;
+ background-color: var(--ifm-background-color);
+
+ /* Pin directly below the main navbar so page content scrolls underneath. */
+ position: sticky;
+ top: var(--ifm-navbar-height);
+ z-index: calc(var(--ifm-z-index-fixed) - 1);
+}
+
+/* Bottom keyline, inset from both edges so it comes in from the screen edges
+ without lining up with the inner elements' padding. */
+.secondaryNav:after {
+ content: "";
+ position: absolute;
+ right: 0.75rem;
+ bottom: 0;
+ left: 0.75rem;
+ height: 1px;
+ background-color: var(--ifm-toc-border-color);
+}
+
+.start {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ min-width: 0;
+}
+
+.end {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+}
+
+.title {
+ font-size: 1.5rem;
+ font-weight: var(--ifm-heading-font-weight);
+ line-height: 1.2;
+}
+
+/* Outlined controls: the section dropdown toggle and the back link share the
+ bordered box style of the Copy page button. */
+
+.dropdown {
+ font-size: 0.9rem;
+}
+
+.dropdownToggle,
+.backLink {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ padding: 0.35rem 0.6rem;
+ font-family: inherit;
+ font-size: 0.9rem;
+ color: var(--ifm-font-color-base);
+ background: transparent;
+ border: 1px solid var(--ifm-color-gray-500);
+ border-radius: var(--ifm-global-radius);
+ text-decoration: none;
+}
+
+.dropdownToggle {
+ cursor: pointer;
+}
+
+.dropdownToggle:after {
+ content: "";
+ display: inline-block;
+ width: 0;
+ height: 0;
+ border-left: 0.3rem solid transparent;
+ border-right: 0.3rem solid transparent;
+ border-top: 0.3rem solid currentcolor;
+ opacity: 0.6;
+ transform: translateY(1px);
+}
+
+.backLink {
+ /* Trim vertical padding so the taller chevron doesn't inflate the box, and
+ tighten the inset before the icon. Match the Copy page button weight. */
+ padding: 0.2rem 0.6rem 0.2rem 0.4rem;
+ font-weight: 500;
+}
+
+.backChevron {
+ opacity: 0.75;
+}
+
+.dropdownToggle:hover,
+.backLink:hover {
+ color: var(--ifm-font-color-base);
+ text-decoration: none;
+ background-color: var(--ifm-menu-color-background-hover);
+ border-color: var(--ifm-color-gray-400);
+}
+
+/* Docs version dropdown wrapper. The dropdown reuses the theme navbar dropdown;
+ its pill styling lives in docs-secondary-nav.scss (it targets the theme's
+ global navbar classes). */
+
+.versionDropdown {
+ display: flex;
+ align-items: center;
+
+ /* Sit closer to the section dropdown than the .start gap allows. */
+ margin-left: -0.5rem;
+}
+
+/* Copy page button — appearance shared with its former home in DocItem */
+
+.copyPageContainer {
+ margin-bottom: 0;
+}
+
+button.copyPageButton {
+ border-radius: var(--ifm-global-radius);
+ border-color: var(--ifm-color-gray-500);
+}
+
+button.copyPageButton:hover {
+ background-color: var(--ifm-menu-color-background-hover) !important;
+ border-color: var(--ifm-color-gray-400) !important;
+}
+
+button.copyPageButton svg {
+ opacity: 0.75;
+}
+
+.copyPageDropdown {
+ border-color: var(--ifm-table-border-color) !important;
+}
+
+.copyPageDropdown button[class^="dropdownItem"] {
+ border-bottom-color: var(--ifm-table-border-color) !important;
+}
+
+.copyPageDropdown button[class^="dropdownItem"]:hover {
+ background-color: var(--ifm-menu-color-background-hover);
+}
+
+.copyPageDropdown div[class^="itemDescription"] {
+ font-weight: 300;
+ font-size: 12px;
+}
+
+[data-theme="dark"] .dropdownToggle:hover,
+[data-theme="dark"] .backLink:hover {
+ background-color: var(--dark);
+ border-color: var(--ifm-color-gray-800);
+}
+
+[data-theme="dark"] button.copyPageButton:hover {
+ background-color: var(--dark) !important;
+ border-color: var(--ifm-color-gray-800) !important;
+}
+
+[data-theme="dark"] .copyPageDropdown {
+ background-color: var(--ifm-navbar-background-color);
+}
+
+[data-theme="dark"] .copyPageDropdown button[class^="dropdownItem"]:hover {
+ background-color: var(--dark);
+}
+
+[data-theme="dark"] .copyPageDropdown div[class^="itemDescription"] {
+ color: var(--ifm-color-gray-600) !important;
+}
diff --git a/website/src/components/releases/_releases-table.md b/website/src/components/releases/_releases-table.md
index f6fcf54369b..72303570d89 100644
--- a/website/src/components/releases/_releases-table.md
+++ b/website/src/components/releases/_releases-table.md
@@ -1,15 +1,15 @@
-| Version | Branch-cut Date | Release Date | Support | Blogpost |
-| -------- | --------------- | ------------ | ------------ | --------------------------------------------- |
-| `0.89.x` | 2026-11-03 | 2026-12-07 | Future | |
-| `0.88.x` | 2026-09-07 | 2026-10-12 | Future | |
-| `0.87.x` | 2026-07-06 | 2026-08-10 | Future | |
-| `0.86.x` | 2026-05-04 | 2026-06-09 | Active | [Details](/blog/2026/06/11/react-native-0.86) |
-| `0.85.x` | 2026-03-02 | 2026-04-06 | Active | [Details](/blog/2026/04/07/react-native-0.85) |
-| `0.84.x` | 2026-01-05 | 2026-02-09 | End of Cycle | [Details](/blog/2026/02/11/react-native-0.84) |
-| `0.83.x` | 2025-11-03 | 2025-12-10 | Unsupported | [Details](/blog/2025/12/10/react-native-0.83) |
-| `0.82.x` | 2025-09-01 | 2025-10-06 | Unsupported | [Details](/blog/2025/10/08/react-native-0.82) |
-| `0.81.x` | 2025-07-10 | 2025-08-12 | Unsupported | [Details](/blog/2025/08/12/react-native-0.81) |
-| `0.80.x` | 2025-05-07 | 2025-06-12 | Unsupported | [Details](/blog/2025/06/12/react-native-0.80) |
-| `0.79.x` | 2025-03-04 | 2025-04-08 | Unsupported | [Details](/blog/2025/04/08/react-native-0.79) |
-| `0.78.x` | 2025-01-15 | 2025-02-19 | Unsupported | [Details](/blog/2025/02/19/react-native-0.78) |
-| `0.77.x` | 2024-11-26 | 2025-01-21 | Unsupported | [Details](/blog/2025/01/21/version-0.77) |
+| Version | Branch cut date | Release date | Support | Blog post |
+| ------- | --------------- | ------------ | ------------ | --------------------------------------------- |
+| 0.89.x | 2026-11-03 | 2026-12-07 | Future | |
+| 0.88.x | 2026-09-07 | 2026-10-12 | Future | |
+| 0.87.x | 2026-07-06 | 2026-08-10 | Future | |
+| 0.86.x | 2026-05-04 | 2026-06-09 | Active | [Details](/blog/2026/06/11/react-native-0.86) |
+| 0.85.x | 2026-03-02 | 2026-04-06 | Active | [Details](/blog/2026/04/07/react-native-0.85) |
+| 0.84.x | 2026-01-05 | 2026-02-09 | End of Cycle | [Details](/blog/2026/02/11/react-native-0.84) |
+| 0.83.x | 2025-11-03 | 2025-12-10 | Unsupported | [Details](/blog/2025/12/10/react-native-0.83) |
+| 0.82.x | 2025-09-01 | 2025-10-06 | Unsupported | [Details](/blog/2025/10/08/react-native-0.82) |
+| 0.81.x | 2025-07-10 | 2025-08-12 | Unsupported | [Details](/blog/2025/08/12/react-native-0.81) |
+| 0.80.x | 2025-05-07 | 2025-06-12 | Unsupported | [Details](/blog/2025/06/12/react-native-0.80) |
+| 0.79.x | 2025-03-04 | 2025-04-08 | Unsupported | [Details](/blog/2025/04/08/react-native-0.79) |
+| 0.78.x | 2025-01-15 | 2025-02-19 | Unsupported | [Details](/blog/2025/02/19/react-native-0.78) |
+| 0.77.x | 2024-11-26 | 2025-01-21 | Unsupported | [Details](/blog/2025/01/21/version-0.77) |
diff --git a/website/src/css/customTheme.scss b/website/src/css/customTheme.scss
index b08da1ee456..078da62b474 100644
--- a/website/src/css/customTheme.scss
+++ b/website/src/css/customTheme.scss
@@ -312,6 +312,40 @@ hr {
margin-bottom: var(--ifm-spacing-vertical);
}
+// The doc layout nests flex columns (.docRoot > .docMainContainer > .container,
+// then .row > .col). Each defaults to min-width: auto, so a wide child forces
+// the whole layout past the viewport. Zeroing min-width lets them shrink so a
+// horizontally scrollable child can scroll instead of overflowing the page.
+[class*="docMainContainer"],
+[class*="docMainContainer"] .container {
+ min-width: 0;
+}
+
+// Opt-in wrapper for wide markdown tables. Wrap the table in
+// `
` in MDX. The table itself becomes the
+// horizontal scroll container (display: block + overflow) — more reliable
+// across the doc layout's nested flex columns than scrolling the wrapper.
+.markdown .table-scroll table {
+ display: block;
+ width: max-content;
+ max-width: 100%;
+ overflow-x: auto;
+ table-layout: auto;
+
+ // Keep cells on a single line; scroll horizontally instead of wrapping.
+ th,
+ td {
+ white-space: nowrap;
+ }
+
+ // Shaded, bold row-header column for the branch names (matches the schedule table).
+ td:first-child {
+ background-color: var(--ifm-table-head-background);
+ color: var(--ifm-font-color-base);
+ font-weight: var(--ifm-font-weight-bold);
+ }
+}
+
.markdown {
h2:first-child {
margin-top: 0;
@@ -754,6 +788,41 @@ html[data-theme="dark"] .homepage {
/* Blog */
+// Compact multi-author blog grid: three-up at the widest (fixed-width) layout,
+// two-up on smaller desktops, one-up on mobile.
+.col--6[class*="authorCol"] {
+ --ifm-avatar-intro-margin: 0.7rem;
+
+ flex: 0 0 33.3333%;
+
+ // 1416px is where the site header locks to a fixed width.
+ @media (max-width: 1416px) {
+ flex: 0 0 50%;
+ }
+
+ @media (max-width: 768px) {
+ flex: 0 0 100%;
+ }
+
+ [class*="authorImage"] {
+ --ifm-avatar-photo-size: 1.75rem;
+ }
+
+ [class*="authorName"] {
+ font-size: 0.9rem;
+ }
+
+ [class*="authorTitle"] {
+ font-size: 0.75rem;
+
+ // Don't truncate long titles.
+ display: block;
+ overflow: visible;
+ line-clamp: none;
+ -webkit-line-clamp: none;
+ }
+}
+
.avatar__name {
font-weight: 600;
display: inline-flex;
@@ -2257,13 +2326,21 @@ html[data-theme="dark"] .docsRating {
/* Blog */
+// Keep blog anchors clear of the sticky DocsSecondaryNav.
+html.blog-wrapper {
+ scroll-padding-top: calc(var(--ifm-navbar-height) + var(--rn-subnav-height));
+}
+
.blog-wrapper .main-wrapper {
h3[class*="sidebarItemTitle"] {
color: var(--ifm-font-color-secondary);
}
div[class*="tableOfContents"] {
- top: calc(var(--ifm-navbar-height));
+ top: calc(var(--ifm-navbar-height) + var(--rn-subnav-height));
+ max-height: calc(
+ 100vh - (var(--ifm-navbar-height) + var(--rn-subnav-height) + 2rem)
+ );
}
.table-of-contents {
diff --git a/website/src/css/docs-secondary-nav.scss b/website/src/css/docs-secondary-nav.scss
new file mode 100644
index 00000000000..f8fbcf66d02
--- /dev/null
+++ b/website/src/css/docs-secondary-nav.scss
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+/**
+ * Offsets that keep the sticky doc sidebar, table of contents and anchor
+ * scrolling clear of the sticky DocsSecondaryNav. Scoped to `.plugin-docs`, the
+ * class Docusaurus sets on for every content-docs page (the pages that
+ * render the secondary nav).
+ */
+
+:root {
+ --rn-subnav-height: 3rem;
+}
+
+html.plugin-docs {
+ scroll-padding-top: calc(var(--ifm-navbar-height) + var(--rn-subnav-height));
+}
+
+@media (min-width: 997px) {
+ // Position the sticky sidebar like the blog sidebar: drop the theme's
+ // negative margin and instead stick the viewport just below the secondary
+ // nav. This keeps the first item's normal top spacing at every scroll
+ // position (the negative-margin mechanism otherwise drifts once a second
+ // sticky bar is added above it).
+ html.plugin-docs aside[class^="theme-doc-sidebar-container"] {
+ margin-top: 0;
+ }
+
+ html.plugin-docs aside[class^="theme-doc-sidebar-container"] > div {
+ top: calc(var(--ifm-navbar-height) + var(--rn-subnav-height));
+ max-height: calc(
+ 100vh - (var(--ifm-navbar-height) + var(--rn-subnav-height))
+ );
+ }
+
+ // The viewport now clears both bars, so the content box no longer needs the
+ // theme's navbar-height top padding.
+ html.plugin-docs aside[class^="theme-doc-sidebar-container"] > div > div {
+ padding-top: 0;
+ }
+
+ html.plugin-docs div[class^="tableOfContents"] {
+ top: calc(var(--ifm-navbar-height) + var(--rn-subnav-height) + 34px);
+ max-height: calc(
+ 100vh - (var(--ifm-navbar-height) + var(--rn-subnav-height) + 2rem)
+ );
+ }
+}
+
+/**
+ * Docs version dropdown. Reuses the theme navbar dropdown, styled to match the
+ * other outlined controls in this nav but with fully rounded corners for
+ * differentiation. Only the "Next" version is highlighted in the brand blue;
+ * released versions use the same white/grey outline as the other dropdowns.
+ */
+
+[class*="versionDropdown"] {
+ .navbar__item {
+ // Keep it visible on mobile too — Infima hides navbar items below 996px.
+ display: inline-flex;
+ margin: 0;
+ padding: 0;
+ }
+
+ .navbar__link {
+ display: inline-flex;
+ align-items: center;
+ margin: 0;
+ padding: 0.35rem 0.6rem;
+ font-size: 0.9rem;
+ font-weight: var(--ifm-font-weight-normal);
+
+ // Match the section dropdown button's compact height (it uses the browser
+ // default line-height rather than the taller inherited base).
+ line-height: normal;
+ color: var(--ifm-font-color-base);
+ background: transparent;
+ border: 1px solid var(--ifm-color-gray-500);
+ border-radius: 999px;
+
+ // Match the section dropdown caret: nudged down and dimmed to grey.
+ &:after {
+ opacity: 0.6;
+ transform: translateY(-1px);
+ }
+
+ &:hover {
+ color: var(--ifm-font-color-base);
+ background-color: var(--ifm-menu-color-background-hover);
+ border-color: var(--ifm-color-gray-400);
+ }
+ }
+}
+
+[data-theme="dark"] [class*="versionDropdown"] .navbar__link:hover {
+ background-color: var(--dark);
+ border-color: var(--ifm-color-gray-800);
+}
+
+[class*="versionDropdown"][data-version-next] .navbar__link {
+ color: var(--ifm-button-color, #fff);
+ background-color: var(--ifm-color-primary);
+ border-color: var(--ifm-color-primary);
+
+ &:hover {
+ color: var(--ifm-button-color, #fff);
+ background-color: var(--ifm-color-primary);
+ border-color: var(--ifm-color-primary);
+ filter: brightness(0.92);
+ }
+}
diff --git a/website/src/css/releases.scss b/website/src/css/releases.scss
new file mode 100644
index 00000000000..836a41a92df
--- /dev/null
+++ b/website/src/css/releases.scss
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+.releases-header {
+ border-bottom: 1px solid var(--ifm-toc-border-color);
+
+ h1 {
+ margin: 0;
+ padding: 28px 0;
+ font-size: 3rem;
+ line-height: 1.1;
+ }
+}
+
+// Tables are auto-wrapped in `.table-wrapper` (border + `overflow: hidden`), so
+// make that box the scroll container: it stays put and content scrolls inside.
+.markdown .releases-schedule-table .table-wrapper {
+ overflow-x: auto;
+}
+
+// Content-sized columns (override the base `table-layout: fixed`); keep
+// `display: table` on mobile, where the base switches tables to `display: block`.
+.markdown .releases-schedule-table table {
+ display: table;
+ table-layout: auto;
+}
+
+.markdown .releases-schedule-table th,
+.markdown .releases-schedule-table td {
+ white-space: nowrap;
+ min-width: 100px;
+}
+
+// Shaded, bold row-header column for the Version cells (matches /versions).
+.markdown .releases-schedule-table table tbody td:first-child {
+ background-color: var(--ifm-table-head-background);
+ color: var(--ifm-font-color-base);
+ font-weight: var(--ifm-font-weight-bold);
+ text-align: left;
+}
diff --git a/website/src/css/versions.scss b/website/src/css/versions.scss
index 9971f9897c7..d1257a585cd 100644
--- a/website/src/css/versions.scss
+++ b/website/src/css/versions.scss
@@ -9,7 +9,6 @@
.versions-page {
max-width: 1400px !important;
- padding: 28px;
h1 {
font-size: 2.5rem;
diff --git a/website/src/pages/versions.tsx b/website/src/pages/versions.tsx
index 611c89197a7..0c889b7f0eb 100644
--- a/website/src/pages/versions.tsx
+++ b/website/src/pages/versions.tsx
@@ -5,9 +5,11 @@
* LICENSE file in the root directory of this source tree.
*/
+import type {PropSidebar} from '@docusaurus/plugin-content-docs';
+
+import {DocsSidebarProvider} from '@docusaurus/plugin-content-docs/client';
import useBaseUrl from '@docusaurus/useBaseUrl';
-import ReleasesTable from '@site/src/components/releases/ReleasesTable';
-import Admonition from '@theme/Admonition';
+import DocRootLayout from '@theme/DocRoot/Layout';
import Layout from '@theme/Layout';
import versions from '../../versions.json';
@@ -37,13 +39,13 @@ const VersionItem = ({
);
const documentationLink = Documentation;
- let releaseNotesURL = 'https://github.com/facebook/react-native/releases';
+ let releaseNotesURL = 'https://github.com/react/react-native/releases';
let releaseNotesTitle = 'Changelog';
if (isNext) {
- releaseNotesURL = `https://github.com/facebook/react-native/compare/${latestMajorVersion}-stable...main`;
+ releaseNotesURL = `https://github.com/react/react-native/compare/${latestMajorVersion}-stable...main`;
releaseNotesTitle = 'Commits since ' + latestMajorVersion;
} else if (!isRC) {
- releaseNotesURL = `https://github.com/facebook/react-native/releases/tag/v${version}.0`;
+ releaseNotesURL = `https://github.com/react/react-native/releases/tag/v${version}.0`;
}
const releaseNotesLink = {releaseNotesTitle};
@@ -57,6 +59,19 @@ const VersionItem = ({
);
};
+// Mirrors the `releases` sidebar in sidebarsReleases.ts so the /versions page
+// (a standalone React page, not a doc) renders the same sidebar. Keep in sync.
+const releasesSidebar: PropSidebar = [
+ {type: 'link', href: '/releases/overview', label: 'Overview'},
+ {type: 'link', href: '/releases/branches', label: 'Branches'},
+ {
+ type: 'link',
+ href: '/releases/versioning-policy',
+ label: 'Versioning Policy',
+ },
+ {type: 'link', href: '/versions', label: 'Docs Versions'},
+];
+
const Versions = () => {
const currentVersion = versions.length > 0 ? versions[0] : null;
const latestVersions = ['next'].concat(
@@ -67,122 +82,89 @@ const Versions = () => {
);
return (
-
-
React Native versions
-
- Open source React Native releases follow a release train that is
- coordinated on GitHub through the{' '}
-
- react-native-releases
- {' '}
- repository. New releases are created off the main branch of{' '}
-
- facebook/react-native
-
- . They will follow a Release Candidate process to allow contributors
- like yourself to{' '}
- verify the changes and to
- identify any issues by{' '}
-
- writing clear, actionable bug reports
-
- . Eventually, the release candidate will be promoted to stable.
-
-
- Below is the schedule and current status of recent and upcoming React
- Native releases:
-
-
-
-
-
-
-
-
- You can read more details about release schedule and the meaning of
- statuses on the Releases Overview page.
-
-
Next version (Unreleased)
-
-
-
- {latestVersions.map(version => (
-
- ))}
-
-
-
-
- To see what changes are coming and provide better feedback to React
- Native contributors, use the latest release candidate when possible.
- Changes introduced in a release candidate will have been shipped to
- production Facebook apps for over two weeks by the time the release
- candidate is cut.
-
-
Latest version
-
- The most recent stable version will be used automatically whenever a new
- project is created using the npx react-native init command.
-
-
-
-
-
-
-
-
-
Previous versions
-
-
-
- {stableVersions.map(version => (
-
- ))}
-
-
-
-
Archived versions
-
- The documentation for unmaintained versions can be found on website
- archive snapshots, hosted as separate sites.
-
+ The documentation for versions below 0.60 can be
+ found on the separate website called{' '}
+
+ React Native Archive
+
+ .
+
+
+
+
);
};
diff --git a/website/src/theme/BlogLayout/index.tsx b/website/src/theme/BlogLayout/index.tsx
new file mode 100644
index 00000000000..b38ee78045d
--- /dev/null
+++ b/website/src/theme/BlogLayout/index.tsx
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import type {Props} from '@theme/BlogLayout';
+
+import React from 'react';
+import clsx from 'clsx';
+import {useLocation} from '@docusaurus/router';
+import Layout from '@theme/Layout';
+import BlogSidebar from '@theme/BlogSidebar';
+import DocsSecondaryNav from '@site/src/components/DocsSecondaryNav';
+
+import styles from './styles.module.css';
+
+// Individual posts live under a dated path; the index, pagination, tags,
+// archive and authors routes are the list-style pages that keep the sidebar.
+function useIsBlogPost() {
+ const {pathname} = useLocation();
+ return (
+ pathname !== '/blog' &&
+ pathname !== '/blog/' &&
+ !pathname.startsWith('/blog/page/') &&
+ !pathname.startsWith('/blog/tags') &&
+ !pathname.startsWith('/blog/archive') &&
+ !pathname.startsWith('/blog/authors')
+ );
+}
+
+// Ejected from @docusaurus/theme-classic to render the shared secondary nav
+// full-width below the main navbar, above the blog content.
+export default function BlogLayout(props: Props) {
+ const {sidebar, toc, children, ...layoutProps} = props;
+ const isBlogPost = useIsBlogPost();
+ // Individual posts drop the recent-posts sidebar and center their content.
+ const showSidebar = !isBlogPost && sidebar && sidebar.items.length > 0;
+
+ let mainClassName;
+ if (isBlogPost) {
+ mainClassName = clsx('col', 'col--7', styles.blogPostMain);
+ } else if (showSidebar) {
+ mainClassName = clsx('col', 'col--7');
+ } else {
+ mainClassName = clsx('col', 'col--9', 'col--offset-1');
+ }
+
+ return (
+
+
+
+
+ {showSidebar && }
+ {children}
+ {toc &&
{toc}
}
+
+
+
+ );
+}
diff --git a/website/src/theme/BlogLayout/styles.module.css b/website/src/theme/BlogLayout/styles.module.css
new file mode 100644
index 00000000000..a1a1c832c56
--- /dev/null
+++ b/website/src/theme/BlogLayout/styles.module.css
@@ -0,0 +1,12 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+/* Center the post content in the space left of the TOC now that the recent-
+ posts sidebar is gone, while keeping its column width. */
+.blogPostMain {
+ margin-inline: auto;
+}
diff --git a/website/src/theme/BlogSidebar/Desktop/index.tsx b/website/src/theme/BlogSidebar/Desktop/index.tsx
index 157fd9c0b0a..bbbb05b1959 100644
--- a/website/src/theme/BlogSidebar/Desktop/index.tsx
+++ b/website/src/theme/BlogSidebar/Desktop/index.tsx
@@ -23,9 +23,6 @@ export default function BlogSidebarDesktop({sidebar}: Props) {
message: 'Blog recent posts navigation',
description: 'The ARIA label for recent posts in the blog sidebar',
})}>
-
- );
-}
-
/**
* Decide if the toc should be rendered, on mobile or desktop viewports
*/
@@ -76,15 +58,7 @@ export default function DocItemLayout({children}: Props): ReactNode {
}
);
}
diff --git a/website/src/theme/DocItem/Layout/styles.module.css b/website/src/theme/DocItem/Layout/styles.module.css
index d2d6137c74e..12a0dea2bb3 100644
--- a/website/src/theme/DocItem/Layout/styles.module.css
+++ b/website/src/theme/DocItem/Layout/styles.module.css
@@ -10,94 +10,12 @@
margin-top: 0;
}
-.docHeaderContainer {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.copyPageAsideAction {
- margin-bottom: 1rem;
-}
-
-div[class^="copyPageArticleAction"] {
- margin-bottom: 0;
-}
-
-.copyPageArticleAction {
- margin-left: auto;
-}
-
-button[class^="copyPageButton"] {
- border-radius: var(--ifm-global-radius);
- border-color: var(--ifm-color-gray-500);
-
- &:hover {
- background-color: var(--ifm-menu-color-background-hover) !important;
- border-color: var(--ifm-color-gray-400) !important;
- }
-
- svg {
- opacity: 0.75;
- }
-}
-
-div[class^="copyPageDropdown"] {
- border-color: var(--ifm-table-border-color) !important;
-
- button[class^="dropdownItem"] {
- border-bottom-color: var(--ifm-table-border-color) !important;
-
- &:hover {
- background-color: var(--ifm-menu-color-background-hover);
- }
-
- &:not([data-copy-page-action="copy"], [data-copy-page-action="view"]) {
- div[class^="itemTitle"] {
- margin-bottom: 0;
- }
-
- div[class^="itemDescription"] {
- display: none;
- }
- }
- }
-
- div[class^="itemDescription"] {
- font-weight: 300;
- font-size: 12px;
- }
-}
-
-[data-theme="dark"] {
- button[class^="copyPageButton"] {
- &:hover {
- background-color: var(--dark) !important;
- border-color: var(--ifm-color-gray-800) !important;
- }
- }
-
- button[class^="dropdownItem"] {
- &:hover {
- background-color: var(--dark);
- }
- }
-
- div[class^="copyPageDropdown"] {
- background-color: var(--ifm-navbar-background-color);
-
- div[class^="itemDescription"] {
- color: var(--ifm-color-gray-600) !important;
- }
- }
-}
-
@media (min-width: 997px) {
.docItemCol {
max-width: 75% !important;
- }
- .copyPageArticleActionWithToc {
- display: none;
+ /* Allow the column to shrink so wide children (e.g. scrollable tables) can
+ scroll instead of forcing the column past the viewport. */
+ min-width: 0;
}
}
diff --git a/website/src/theme/DocRoot/Layout/index.tsx b/website/src/theme/DocRoot/Layout/index.tsx
new file mode 100644
index 00000000000..d65fed9a6f1
--- /dev/null
+++ b/website/src/theme/DocRoot/Layout/index.tsx
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import type {Props} from '@theme/DocRoot/Layout';
+
+import React from 'react';
+import {useDocsSidebar} from '@docusaurus/plugin-content-docs/client';
+import OriginalDocRootLayout from '@theme-original/DocRoot/Layout';
+import DocsSecondaryNav from '@site/src/components/DocsSecondaryNav';
+
+// Renders a full-width secondary nav above every docs-plugin layout (docs,
+// architecture, community, contributing). The sidebar name drives which section
+// the nav shows as active.
+export default function DocRootLayout(props: Props) {
+ const sidebar = useDocsSidebar();
+ return (
+ <>
+
+
+ >
+ );
+}
diff --git a/website/static/_redirects b/website/static/_redirects
index 65b2ea39555..bd638193f6e 100644
--- a/website/static/_redirects
+++ b/website/static/_redirects
@@ -18,8 +18,16 @@
/contributing/how-to-contribute /contributing/overview
/contributing/how-to-file-an-issue /contributing/how-to-report-a-bug
-/contributing/versioning-policy /docs/next/releases/versioning-policy
-/releases/release-candidate-minor /docs/next/releases/versioning-policy
+/contributing/versioning-policy /releases/versioning-policy
+/releases/release-candidate-minor /releases/versioning-policy
+
+# Release docs consolidated under the /releases section
+/docs/releases /releases/overview
+/docs/next/releases /releases/overview
+/docs/releases/versioning-policy /releases/versioning-policy
+/docs/next/releases/versioning-policy /releases/versioning-policy
+/docs/releases/release-levels /docs/release-levels
+/docs/next/releases/release-levels /docs/next/release-levels
# Redirect New Architecture docs of all versions
# Note: We had to delete the older versions to get redirects to work
diff --git a/website/versioned_docs/version-0.86/_canary-channel-api-warning.mdx b/website/versioned_docs/version-0.86/_canary-channel-api-warning.mdx
index 2c1ae5cf423..8f1af9f8b46 100644
--- a/website/versioned_docs/version-0.86/_canary-channel-api-warning.mdx
+++ b/website/versioned_docs/version-0.86/_canary-channel-api-warning.mdx
@@ -2,6 +2,6 @@
**This API is currently only available in React Native’s Canary and Experimental channels.**
-If you want to try it out, please [enable the Canary Channel](releases/release-levels) in your app.
+If you want to try it out, please [enable the Canary Channel](release-levels) in your app.
:::
diff --git a/website/versioned_docs/version-0.86/_experimental-channel-api-warning.mdx b/website/versioned_docs/version-0.86/_experimental-channel-api-warning.mdx
index 92a7b2c8c2f..f6bb132151d 100644
--- a/website/versioned_docs/version-0.86/_experimental-channel-api-warning.mdx
+++ b/website/versioned_docs/version-0.86/_experimental-channel-api-warning.mdx
@@ -4,6 +4,6 @@
Experimental APIs may contain bugs and are likely to change in a future version of React Native. Don't use them in production.
-If you want to try it out, please [enable the Experimental Channel](releases/release-levels) in your app.
+If you want to try it out, please [enable the Experimental Channel](release-levels) in your app.
:::
diff --git a/website/versioned_docs/version-0.86/releases/release-levels.md b/website/versioned_docs/version-0.86/release-levels.md
similarity index 100%
rename from website/versioned_docs/version-0.86/releases/release-levels.md
rename to website/versioned_docs/version-0.86/release-levels.md
diff --git a/website/versioned_docs/version-0.86/releases/releases.md b/website/versioned_docs/version-0.86/releases/releases.md
deleted file mode 100644
index c6a9bb52c6e..00000000000
--- a/website/versioned_docs/version-0.86/releases/releases.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-id: releases
-title: Releases Overview
----
-
-import ReleasesTable from '@site/src/components/releases/ReleasesTable';
-
-New React Native releases are shipped **every two months**, usually resulting in six (6) new minors per year.
-
-Below is the schedule and current status of recent and upcoming React Native releases:
-
-
-
-The different support level presented in the table are defined as such:
-
-- **Future**
- - After a new version branch gets cut, creating new Release Candidates to allow the community to test the upcoming version is very important. New RC releases are done at a high pace, as soon as viable.
-- **Active**
- - Stable releases in active support receive frequent updates. Latest stable has the highest priority, and at the start of its stable cycle (right after .0 is released) multiple patches will be done as soon as possible to stabilize the version and ensure a good upgrade experience to the community.
-- **End of Cycle**
- - A version in this support bracket will receive less patches, unless some important regressions need to be addressed. Once a next version becomes the new latest stable, before the version in EoC moves over into Unsupported one last patch released will be produced with the latest receive pick requests.
-- **Unsupported**
- - When a version is in the unsupported stage, no new released are to be expected. Only very important regressions might create exceptions to this rule; it is recommended that codebases using an unsupported version upgrade as soon as possible.
-
-## Commitment to Stability
-
-In order to support users upgrading React Native versions, we’re committed to maintain the **latest 3 minor series** (e.g. 0.78.x, 0.77.x and 0.76.x when 0.78 is the latest release).
-
-For those releases we’ll be publishing regular updates and bug fixes.
-
-You can read more about our support policy on [the react-native-releases working group](https://github.com/reactwg/react-native-releases/blob/main/docs/support.md).
-
-More information on our versioning, and what we consider a breaking change is available in our [versioning policy](./releases/versioning-policy) page.
diff --git a/website/versioned_docs/version-0.86/releases/versioning-policy.md b/website/versioned_docs/version-0.86/releases/versioning-policy.md
deleted file mode 100644
index 1b37c94bdc2..00000000000
--- a/website/versioned_docs/version-0.86/releases/versioning-policy.md
+++ /dev/null
@@ -1,111 +0,0 @@
----
-title: Versioning Policy
----
-
-This page describes the versioning policy we follow for the `react-native` package.
-
-We test each version of React Native thoroughly, both with manual and automated tests, to ensure the quality doesn't regress.
-
-The `stable` channel of React Native follows the 0.x.y release policy described below.
-
-React Native also offers a `nightly` release channel to encourage early feedback on experimental features.
-
-This page describes our approach to version numbers for `react-native` and for packages under the `@react-native` scope.
-
-## Stable Release Versions
-
-React Native releases stable versions at a regular cadence.
-
-We follow the 0.x.y versioning schema:
-
-- Breaking changes will be shipped in a new minor version, i.e. we increment the x number (e.g.: 0.78.0 to 0.79.0).
-- New features and APIs will also be shipped in a new minor version, i.e. we increment the x number (e.g.: 0.78.0 to 0.79.0).
-- Critical bug fixes will be shipped in a new patch version, i.e. we increment the y number (e.g.: 0.78.1 to 0.78.2).
-
-Stable releases are shipped regularly, with the latest tagged as `latest` on NPM.
-
-A series of releases under the same minor number is called a **minor series** (e.g. 0.76.x is the minor series for 0.76.0, 0.76.1, 0.76.2, etc.).
-
-You can read more about our **commitment to stability** in [the releases page](./).
-
-### Breaking changes
-
-Breaking changes are inconvenient for everyone, and we’re trying to minimize them to the bare minimum. All the breaking changes we ship in each stable release will be highlighted in:
-
-- The _Breaking_ and the _Removed_ section of [the React Native Changelog](https://github.com/facebook/react-native/blob/main/CHANGELOG.md)
-- Each release blogpost in the _Breaking Changes_ section
-
-For each breaking change we’re committed to explaining the reasoning behind it, provide a replacement API if possible, and minimize the impact on final users.
-
-### What is a breaking change?
-
-We consider a breaking change for React Native:
-
-- An incompatible API change (i.e. an API that is changed or removed so that your code won’t compile/run anymore due to that change). Examples:
- - Changes of any JS/Java/Kotlin/Obj-c/C++ APIs that would require your code to be changed in order to compile.
- - Changes inside `@react-native/codegen` that are not backward compatible.
-- A significant behavior/runtime change. Example:
- - The layout logic of a prop is changed drastically.
-- A significant change in the development experience. Example:
- - A debugging feature is entirely removed.
-- A major bump of any of our transitive dependencies. Examples:
- - Bumping React from 18.x to 19.x
- - Bumping the Target SDK on Android from 34 to 35).
-- A reduction of any of our supported platform versions. Examples:
- - Bumping min SDK on Android from 21 to 23
- - Bumping the min iOS version to 15.1.
-
-We don’t consider those changes to be breaking:
-
-- Modifying APIs starting with `unstable_` prefix: These APIs expose experimental features, and we are not confident on their final shape. By releasing these with an `unstable_` prefix, we can iterate faster and get to a stable API sooner.
-- Changes to private or internal APIs: These APIs are often prefixed with either `internal_` , `private_` or living inside a `internal/` or `private/` folder/package. While some of those APIs might have public visibility due to tooling constraints, we don’t consider them part of our public API, so we’ll be changing them without previous notice.
- - Similarly, If you access internal property names like `__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED` or `__reactInternalInstance$uk43rzhitjg`, there are no guarantees. You are on your own.
- - Classes annotated with `@FrameworkAPI` are also considered internal
-- Changes to tooling/development APIs: Some public APIs of React Native are reserved for integration with frameworks and other tools. For example, some of the Metro APIs or React Native DevTools APIs are supposed to be used only by other frameworks or tools. Changes to those APIs are discussed directly with the affected tools and are not considered breaking changes (we won’t be communicating them broadly in the release blogposts).
-- Development warnings: Since warnings don’t affect runtime behavior, we may add new warnings or modify existing warnings in between any versions.
-
-If we expect a change to cause broad problems in the community, we will still do our best to provide a gradual migration path for the ecosystem.
-
-### Deprecation Cycles
-
-As we keep on developing and evolving React Native, we write new APIs and sometimes we need to deprecate existing ones. Those APIs will go through a deprecation cycle.
-
-Once an API is deprecated, it will remain available **also** for the **following** stable releases.
-
-For example: if an API is deprecated in React Native 0.76.x, it will still be available in 0.77.x and won’t be removed sooner than React Native 0.78.x.
-
-Sometimes we decide to keep a deprecated API for a longer time, if we feel that the ecosystem needs more time to migrate away from it. For those APIs we generally provide warnings to help users migrate away from them.
-
-## Release channels
-
-React Native relies on a thriving open source community to file bug reports, open pull requests, and submit RFCs. To encourage feedback we do support several release channels.
-
-:::note
-This section will be most relevant to developers who work on frameworks, libraries, or developer tooling. Developers who use React Native primarily to build user-facing applications should not need to worry about release channels other than latest.
-:::
-
-### latest
-
-`latest` is for stable, semver React Native releases. It’s what you get when you install React Native from npm. This is the channel you’re already using today. User-facing applications that consume React Native directly use this channel.
-
-We publish a newer minor series of React Native regularly, and we update the `latest` tag to reflect the latest stable version.
-
-### next
-
-Before we declare a new React Native release stable, we publish a series of **release candidate**, starting from RC0. Those versions are pre-release versions (following the versioning schema `0.79.0-rc.0`) and are tagged as `next` on NPM.
-
-When a new branch cut happens, and RCs start to get published on NPM and GitHub, it’s a good idea to test your library/framework against a `next` version of React Native.
-
-That will ensure that your project will keep on working well with the upcoming versions of React Native.
-
-However, do not use prereleases/RCs in user-facing applications directly as they’re not considered production ready.
-
-### nightly
-
-We also publish a `nightly` release channel. Nightlies are published every day starting from the `main` branch of [facebook/react-native](https://github.com/facebook/react-native). Nightlies are considered unstable versions of React Native and are not recommended for production use.
-
-Nightlies follow the versioning schema as `0.80.0-nightly--` where `` is the date of the nightly and `` is the SHA of the commit that was used to publish this nightly.
-
-The nightly releases are provided for testing purposes only, and we provide no guarantees that behavior won’t change between nightlies. They do not follow the semver protocol that we use for releases from latest/next.
-
-It is a good idea to set up a CI workflow to test your library against a react-native@nightly version every day, to make sure your library will keep on working with future releases.
diff --git a/website/versioned_docs/version-0.86/upgrading.md b/website/versioned_docs/version-0.86/upgrading.md
index 06158ffa652..8d052ef8980 100644
--- a/website/versioned_docs/version-0.86/upgrading.md
+++ b/website/versioned_docs/version-0.86/upgrading.md
@@ -1,6 +1,6 @@
---
id: upgrading
-title: Upgrading to new versions
+title: Upgrading to New Versions
---
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants';
diff --git a/website/versioned_sidebars/version-0.86-sidebars.json b/website/versioned_sidebars/version-0.86-sidebars.json
index 0eabe9c2736..30f5165e95c 100644
--- a/website/versioned_sidebars/version-0.86-sidebars.json
+++ b/website/versioned_sidebars/version-0.86-sidebars.json
@@ -26,6 +26,7 @@
"libraries",
"typescript",
"strict-typescript-api",
+ "release-levels",
"upgrading"
],
"UI & Interaction": [
@@ -61,11 +62,6 @@
"items": ["accessibility"]
}
],
- "Releases": [
- "releases/releases",
- "releases/release-levels",
- "releases/versioning-policy"
- ],
"Debugging": [
"debugging",
"react-native-devtools",