diff --git a/beta/plugins/remark-header-custom-ids.js b/beta/plugins/remark-header-custom-ids.js
index ec0c9562..356de1bf 100644
--- a/beta/plugins/remark-header-custom-ids.js
+++ b/beta/plugins/remark-header-custom-ids.js
@@ -11,7 +11,7 @@
const toString = require('mdast-util-to-string');
const visit = require('unist-util-visit');
-const slugs = require('github-slugger')();
+const toSlug = require('github-slugger').slug;
function patch(context, key, value) {
if (!context[key]) {
@@ -22,30 +22,50 @@ function patch(context, key, value) {
const svgIcon = ``;
-module.exports = ({
- icon = svgIcon,
- className = `anchor`,
- maintainCase = false,
-} = {}) => {
- slugs.reset();
+module.exports = ({icon = svgIcon, className = `anchor`} = {}) => {
return function transformer(tree) {
+ const ids = new Set();
visit(tree, 'heading', (node) => {
- const children = node.children;
- let tail = children[children.length - 1];
- // Generate slugs on the fly (even if not specified in markdown)
- // so that it's possible to copy anchor links in newly written content.
- let id = slugs.slug(toString(node), maintainCase);
- // However, for committed docs, we'll extract slug from the headers.
- if (tail && tail.type === 'text' && tail.value === '/}') {
- tail = children[children.length - 2];
- if (tail && tail.type === 'emphasis') {
- // Use custom ID instead.
- id = toString(tail);
+ let children = [...node.children];
+ let id;
+ if (children[children.length - 1].type === 'mdxTextExpression') {
+ // # My header {/*my-header*/}
+ id = children.pop().value;
+ const isValidCustomId = id.startsWith('/*') && id.endsWith('*/');
+ if (!isValidCustomId) {
+ throw Error(
+ 'Expected header ID to be like: {/*some-header*/}. ' +
+ 'Instead, received: ' +
+ id
+ );
}
+ id = id.slice(2, id.length - 2);
+ if (id !== toSlug(id)) {
+ throw Error(
+ 'Expected header ID to be a valid slug. You specified: {/*' +
+ id +
+ '*/}. Replace it with: {/*' +
+ toSlug(id) +
+ '*/}'
+ );
+ }
+ } else {
+ // # My header
+ id = toSlug(toString(node));
}
- const data = patch(node, 'data', {});
+ if (ids.has(id)) {
+ throw Error(
+ 'Cannot have a duplicate header with id "' +
+ id +
+ '" on the page. ' +
+ 'Rename the section or give it an explicit unique ID. ' +
+ 'For example: #### Arguments {/*setstate-arguments*/}'
+ );
+ }
+ ids.add(id);
+ const data = patch(node, 'data', {});
patch(data, 'id', id);
patch(data, 'htmlAttributes', {});
patch(data, 'hProperties', {});
diff --git a/beta/scripts/headingIDHelpers/generateHeadingIDs.js b/beta/scripts/headingIDHelpers/generateHeadingIDs.js
index 855f2d09..40925d44 100644
--- a/beta/scripts/headingIDHelpers/generateHeadingIDs.js
+++ b/beta/scripts/headingIDHelpers/generateHeadingIDs.js
@@ -82,7 +82,7 @@ function addHeaderIDs(lines) {
}
async function main(paths) {
- paths = paths.length === 0 ? ['src/pages'] : paths;
+ paths = paths.length === 0 ? ['src/content'] : paths;
const [unifiedMod, remarkParseMod, remarkSlugMod] = await Promise.all([
import('unified'),
diff --git a/beta/scripts/headingIDHelpers/validateHeadingIDs.js b/beta/scripts/headingIDHelpers/validateHeadingIDs.js
index 535613e7..c3cf1ab8 100644
--- a/beta/scripts/headingIDHelpers/validateHeadingIDs.js
+++ b/beta/scripts/headingIDHelpers/validateHeadingIDs.js
@@ -17,9 +17,7 @@ function validateHeaderId(line) {
const match = /\{\/\*(.*?)\*\/}/.exec(line);
const id = match;
if (!id) {
- console.error(
- 'Run yarn fix-headings to generate headings.'
- );
+ console.error('Run yarn fix-headings to generate headings.');
process.exit(1);
}
}
@@ -51,7 +49,7 @@ function validateHeaderIds(lines) {
* @param {Array} paths
*/
async function main(paths) {
- paths = paths.length === 0 ? ['src/pages'] : paths;
+ paths = paths.length === 0 ? ['src/content'] : paths;
const files = paths.map((path) => [...walk(path)]).flat();
files.forEach((file) => {
diff --git a/beta/src/components/MDX/Convention.tsx b/beta/src/components/MDX/Convention.tsx
deleted file mode 100644
index 434053aa..00000000
--- a/beta/src/components/MDX/Convention.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) Facebook, Inc. and its affiliates.
- */
-
-import * as React from 'react';
-import {H3} from './Heading';
-
-interface ConventionProps {
- children: React.ReactNode;
- name: string;
-}
-
-function Convention({children, name}: ConventionProps) {
- const id = name ? `${name}-conventions` : 'conventions';
- return (
-
-
- Conventions
-
- {children}
-
- );
-}
-
-export default Convention;
diff --git a/beta/src/components/MDX/MDXComponents.tsx b/beta/src/components/MDX/MDXComponents.tsx
index 3312d813..8280670b 100644
--- a/beta/src/components/MDX/MDXComponents.tsx
+++ b/beta/src/components/MDX/MDXComponents.tsx
@@ -9,7 +9,6 @@ import cn from 'classnames';
import CodeBlock from './CodeBlock';
import {CodeDiagram} from './CodeDiagram';
import ConsoleBlock from './ConsoleBlock';
-import Convention from './Convention';
import ExpandableCallout from './ExpandableCallout';
import ExpandableExample from './ExpandableExample';
import {H1, H2, H3, H4} from './Heading';
@@ -356,7 +355,6 @@ export const MDXComponents = {
pre: CodeBlock,
CodeDiagram,
ConsoleBlock,
- Convention,
DeepDive: (props: {
children: React.ReactNode;
title: string;
diff --git a/beta/src/content/apis/react-dom/client/createRoot.md b/beta/src/content/apis/react-dom/client/createRoot.md
index df9fb311..2439d994 100644
--- a/beta/src/content/apis/react-dom/client/createRoot.md
+++ b/beta/src/content/apis/react-dom/client/createRoot.md
@@ -284,16 +284,16 @@ React will display `` in the `root`, and take over managing the DOM insid
[See examples above.](#usage)
-#### Parameters {/*parameters*/}
+#### Parameters {/*root-render-parameters*/}
* `reactNode`: A *React node* that you want to display. This will usually be a piece of JSX like ``, but you can also pass a React element constructed with [`createElement()`](/apis/react/createElement), a string, a number, `null`, or `undefined`.
-#### Returns {/*returns*/}
+#### Returns {/*root-render-returns*/}
`root.render` returns `undefined`.
-#### Caveats {/*caveats*/}
+#### Caveats {/*root-render-caveats*/}
* The first time you call `root.render`, React will clear all the existing HTML content inside the React root before rendering the React component into it.
@@ -318,16 +318,16 @@ This is mostly useful if your React root's DOM node (or any of its ancestors) ma
Calling `root.unmount` will unmount all the components in the root and "detach" React from the root DOM node, including removing any event handlers or state in the tree.
-#### Parameters {/*parameters*/}
+#### Parameters {/*root-unmount-parameters*/}
`root.unmount` does not accept any parameters.
-#### Returns {/*returns*/}
+#### Returns {/*root-unmount-returns*/}
`root.unmount` returns `undefined`.
-#### Caveats {/*caveats*/}
+#### Caveats {/*root-unmount-caveats*/}
* Calling `root.unmount` will unmount all the components in the tree and "detach" React from the root DOM node.
diff --git a/beta/src/content/apis/react-dom/client/hydrateRoot.md b/beta/src/content/apis/react-dom/client/hydrateRoot.md
index 63aa4e25..7afa5f4d 100644
--- a/beta/src/content/apis/react-dom/client/hydrateRoot.md
+++ b/beta/src/content/apis/react-dom/client/hydrateRoot.md
@@ -196,16 +196,16 @@ React will update `` in the hydrated `root`.
[See examples above.](#usage)
-#### Parameters {/*parameters*/}
+#### Parameters {/*root-render-parameters*/}
* `reactNode`: A "React node" that you want to update. This will usually be a piece of JSX like ``, but you can also pass a React element constructed with [`createElement()`](/apis/react/createElement), a string, a number, `null`, or `undefined`.
-#### Returns {/*returns*/}
+#### Returns {/*root-render-returns*/}
`root.render` returns `undefined`.
-#### Caveats {/*caveats*/}
+#### Caveats {/*root-render-caveats*/}
* If you call `root.render` before the root has finished hydrating, React will clear the existing server-rendered HTML content and switch the entire root to client rendering.
@@ -226,16 +226,16 @@ This is mostly useful if your React root's DOM node (or any of its ancestors) ma
Calling `root.unmount` will unmount all the components in the root and "detach" React from the root DOM node, including removing any event handlers or state in the tree.
-#### Parameters {/*parameters*/}
+#### Parameters {/*root-unmount-parameters*/}
`root.unmount` does not accept any parameters.
-#### Returns {/*returns*/}
+#### Returns {/*root-unmount-returns*/}
`render` returns `null`.
-#### Caveats {/*caveats*/}
+#### Caveats {/*root-unmount-caveats*/}
* Calling `root.unmount` will unmount all the components in the tree and "detach" React from the root DOM node.
diff --git a/beta/src/content/apis/react/forwardRef.md b/beta/src/content/apis/react/forwardRef.md
index c61403d6..6210fcfc 100644
--- a/beta/src/content/apis/react/forwardRef.md
+++ b/beta/src/content/apis/react/forwardRef.md
@@ -579,7 +579,7 @@ const MyInput = forwardRef(function MyInput(props, ref) {
* `ref`: The `ref` attribute passed by the parent component. The `ref` can be an object or a function. If the parent component has not passed a ref, it will be `null`. You should either pass the `ref` you receive to another component, or pass it to [`useImperativeHandle`.](/apis/react/useImperativeHandle)
-#### Returns {/*returns*/}
+#### Returns {/*render-returns*/}
`forwardRef` returns a React component that you can render in JSX. Unlike React components defined as plain functions, the component returned by `forwardRef` is able to take a `ref` prop.
diff --git a/beta/src/content/apis/react/memo.md b/beta/src/content/apis/react/memo.md
index 772796ca..59f2afe8 100644
--- a/beta/src/content/apis/react/memo.md
+++ b/beta/src/content/apis/react/memo.md
@@ -177,7 +177,7 @@ If you set a state variable to its current value, React will skip re-rendering y
---
-### Updating a memoized component using a context {/*updating-a-memoized-component-using-state*/}
+### Updating a memoized component using a context {/*updating-a-memoized-component-using-a-context*/}
Even when a component is memoized, it will still re-render when a context that it's using changes. Memoization only has to do with props that are passed to the component from its parent.
diff --git a/beta/src/content/blog/2016/04/07/react-v15.md b/beta/src/content/blog/2016/04/07/react-v15.md
index d9e82b64..7486c239 100644
--- a/beta/src/content/blog/2016/04/07/react-v15.md
+++ b/beta/src/content/blog/2016/04/07/react-v15.md
@@ -85,7 +85,7 @@ If you can’t use `npm` yet, we provide pre-built browser builds for your conve
### Breaking changes {/*breaking-changes*/}
-- #### No more extra ``s
+- #### No extra ``s
It’s worth calling out the DOM structure changes above again, in particular the change from ``s. In the course of updating the Facebook codebase, we found a very small amount of code that was depending on the markup that React generated. Some of these cases were integration tests like WebDriver which were doing very specific XPath queries to target nodes. Others were simply tests using `ReactDOM.renderToStaticMarkup` and comparing markup. Again, there were a very small number of changes that had to be made, but we don’t want anybody to be blindsided. We encourage everybody to run their test suites when upgrading and consider alternative approaches when possible. One approach that will work for some cases is to explicitly use ``s in your `render` method.
diff --git a/beta/src/content/blog/2019/08/08/react-v16.9.0.md b/beta/src/content/blog/2019/08/08/react-v16.9.0.md
index e93c950d..e21cfe23 100644
--- a/beta/src/content/blog/2019/08/08/react-v16.9.0.md
+++ b/beta/src/content/blog/2019/08/08/react-v16.9.0.md
@@ -216,12 +216,12 @@ Refer to the documentation for [detailed installation instructions](/docs/instal
## Changelog {/*changelog*/}
-### React {/*react*/}
+### React {/*changelog-react*/}
- Add `` API for gathering performance measurements programmatically. ([@bvaughn](https://github.com/bvaughn) in [#15172](https://github.com/facebook/react/pull/15172))
- Remove `unstable_ConcurrentMode` in favor of `unstable_createRoot`. ([@acdlite](https://github.com/acdlite) in [#15532](https://github.com/facebook/react/pull/15532))
-### React DOM {/*react-dom*/}
+### React DOM {/*changelog-react-dom*/}
- Deprecate old names for the `UNSAFE_*` lifecycle methods. ([@bvaughn](https://github.com/bvaughn) in [#15186](https://github.com/facebook/react/pull/15186) and [@threepointone](https://github.com/threepointone) in [#16103](https://github.com/facebook/react/pull/16103))
- Deprecate `javascript:` URLs as a common attack surface. ([@sebmarkbage](https://github.com/sebmarkbage) in [#15047](https://github.com/facebook/react/pull/15047))
@@ -238,11 +238,11 @@ Refer to the documentation for [detailed installation instructions](/docs/instal
- Fix hiding Suspense fallback nodes when there is an `!important` style. ([@acdlite](https://github.com/acdlite) in [#15861](https://github.com/facebook/react/pull/15861) and [#15882](https://github.com/facebook/react/pull/15882))
- Slightly improve hydration performance. ([@bmeurer](https://github.com/bmeurer) in [#15998](https://github.com/facebook/react/pull/15998))
-### React DOM Server {/*react-dom-server*/}
+### React DOM Server {/*changelog-react-dom-server*/}
- Fix incorrect output for camelCase custom CSS property names. ([@bedakb](https://github.com/bedakb) in [#16167](https://github.com/facebook/react/pull/16167))
-### React Test Utilities and Test Renderer {/*react-test-utilities-and-test-renderer*/}
+### React Test Utilities and Test Renderer {/*changelog-react-test-utilities-and-test-renderer*/}
- Add `act(async () => ...)` for testing asynchronous state updates. ([@threepointone](https://github.com/threepointone) in [#14853](https://github.com/facebook/react/pull/14853))
- Add support for nesting `act` from different renderers. ([@threepointone](https://github.com/threepointone) in [#16039](https://github.com/facebook/react/pull/16039) and [#16042](https://github.com/facebook/react/pull/16042))
diff --git a/beta/src/content/blog/2020/02/26/react-v16.13.0.md b/beta/src/content/blog/2020/02/26/react-v16.13.0.md
index 6aaad78d..7b713aeb 100644
--- a/beta/src/content/blog/2020/02/26/react-v16.13.0.md
+++ b/beta/src/content/blog/2020/02/26/react-v16.13.0.md
@@ -186,12 +186,12 @@ Refer to the documentation for [detailed installation instructions](/docs/instal
## Changelog {/*changelog*/}
-### React {/*react*/}
+### React {/*changelog-react*/}
- Warn when a string ref is used in a manner that's not amenable to a future codemod ([@lunaruan](https://github.com/lunaruan) in [#17864](https://github.com/facebook/react/pull/17864))
- Deprecate `React.createFactory()` ([@trueadm](https://github.com/trueadm) in [#17878](https://github.com/facebook/react/pull/17878))
-### React DOM {/*react-dom*/}
+### React DOM {/*changelog-react-dom*/}
- Warn when changes in `style` may cause an unexpected collision ([@sophiebits](https://github.com/sophiebits) in [#14181](https://github.com/facebook/react/pull/14181), [#18002](https://github.com/facebook/react/pull/18002))
- Warn when a function component is updated during another component's render phase ([@acdlite](<(https://github.com/acdlite)>) in [#17099](https://github.com/facebook/react/pull/17099))
@@ -202,7 +202,7 @@ Refer to the documentation for [detailed installation instructions](/docs/instal
- Don't call `toString()` of `dangerouslySetInnerHTML` ([@sebmarkbage](https://github.com/sebmarkbage) in [#17773](https://github.com/facebook/react/pull/17773))
- Show component stacks in more warnings ([@gaearon](https://github.com/gaearon) in [#17922](https://github.com/facebook/react/pull/17922), [#17586](https://github.com/facebook/react/pull/17586))
-### Concurrent Mode (Experimental) {/*concurrent-mode-experimental*/}
+### Concurrent Mode (Experimental) {/*changelog-concurrent-mode-experimental*/}
- Warn for problematic usages of `ReactDOM.createRoot()` ([@trueadm](https://github.com/trueadm) in [#17937](https://github.com/facebook/react/pull/17937))
- Remove `ReactDOM.createRoot()` callback params and added warnings on usage ([@bvaughn](https://github.com/bvaughn) in [#17916](https://github.com/facebook/react/pull/17916))
diff --git a/beta/src/content/learn/extracting-state-logic-into-a-reducer.md b/beta/src/content/learn/extracting-state-logic-into-a-reducer.md
index b2d2293b..a3f835fc 100644
--- a/beta/src/content/learn/extracting-state-logic-into-a-reducer.md
+++ b/beta/src/content/learn/extracting-state-logic-into-a-reducer.md
@@ -17,7 +17,7 @@ Components with many state updates spread across many event handlers can get ove
-## Consolidate state logic with a reducer {/* consolidate-state-logic-with-a-reducer */}
+## Consolidate state logic with a reducer {/*consolidate-state-logic-with-a-reducer*/}
As your components grow in complexity, it can get harder to see at a glance all the different ways in which a component's state gets updated. For example, the `TaskApp` component below holds an array of `tasks` in state and uses three different event handlers to add, remove, and edit tasks:
@@ -187,7 +187,7 @@ Reducers are a different way to handle state. You can migrate from `useState` to
2. **Write** a reducer function.
3. **Use** the reducer from your component.
-### Step 1: Move from setting state to dispatching actions {/* step-1-move-from-setting-state-to-dispatching-actions */}
+### Step 1: Move from setting state to dispatching actions {/*step-1-move-from-setting-state-to-dispatching-actions*/}
Your event handlers currently specify _what to do_ by setting state:
@@ -268,9 +268,11 @@ function handleDeleteTask(taskId) {
It is a regular JavaScript object. You decide what to put in it, but generally it should contain the minimal information about _what happened_. (You will add the `dispatch` function itself in a later step.)
-
+
-An action object can have any shape. By convention, it is common to give it a string `type` that describes what happened, and pass any additional information in other fields. The `type` is specific to a component, so in this example either `'added'` or `'added_task'` would be fine. Choose a name that says what happened!
+An action object can have any shape.
+
+By convention, it is common to give it a string `type` that describes what happened, and pass any additional information in other fields. The `type` is specific to a component, so in this example either `'added'` or `'added_task'` would be fine. Choose a name that says what happened!
```js
dispatch({
@@ -280,9 +282,9 @@ dispatch({
});
```
-
+
-### Step 2: Write a reducer function {/* step-2-write-a-reducer-function */}
+### Step 2: Write a reducer function {/*step-2-write-a-reducer-function*/}
A reducer function is where you will put your state logic. It takes two arguments, the current state and the action object, and it returns the next state:
@@ -331,9 +333,11 @@ function tasksReducer(tasks, action) {
> Because the reducer function takes state (`tasks`) as an argument, you can **declare it outside of your component.** This decreases the indentation level and can make your code easier to read.
-
+
+
+The code above uses if/else statements, but it's a convention to use [switch statements](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/switch) inside reducers. The result is the same, but it can be easier to read switch statements at a glance.
-The code above uses if/else statements, but it's a convention to use [switch statements](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/switch) inside reducers. The result is the same, but it can be easier to read switch statements at a glance. We'll be using them throughout the rest of this documentation like so:
+We'll be using them throughout the rest of this documentation like so:
```js
function tasksReducer(tasks, action) {
@@ -371,7 +375,7 @@ We recommend to wrap each `case` block into the `{` and `}` curly braces so that
If you're not yet comfortable with switch statements, using if/else is completely fine.
-
+
@@ -451,7 +455,7 @@ You probably won't need to do this yourself, but this is similar to what React d
-### Step 3: Use the reducer from your component {/* step-3-use-the-reducer-from-your-component */}
+### Step 3: Use the reducer from your component {/*step-3-use-the-reducer-from-your-component*/}
Finally, you need to hook up the `tasksReducer` to your component. Make sure to import the `useReducer` Hook from React:
@@ -858,7 +862,7 @@ li {
Component logic can be easier to read when you separate concerns like this. Now the event handlers only specify _what happened_ by dispatching actions, and the reducer function determines _how the state updates_ in response to them.
-## Comparing `useState` and `useReducer` {/* comparing-usestate-and-usereducer */}
+## Comparing `useState` and `useReducer` {/*comparing-usestate-and-usereducer*/}
Reducers are not without downsides! Here's a few ways you can compare them:
@@ -870,14 +874,14 @@ Reducers are not without downsides! Here's a few ways you can compare them:
We recommend using a reducer if you often encounter bugs due to incorrect state updates in some component, and want to introduce more structure to its code. You don't have to use reducers for everything: feel free to mix and match! You can even `useState` and `useReducer` in the same component.
-## Writing reducers well {/* writing-reducers-well */}
+## Writing reducers well {/*writing-reducers-well*/}
Keep these two tips in mind when writing reducers:
- **Reducers must be pure.** Similar to [state updater functions](/learn/queueing-a-series-of-state-updates), reducers run during rendering! (Actions are queued until the next render.) This means that reducers [must be pure](/learn/keeping-components-pure)—same inputs always result in the same output. They should not send requests, schedule timeouts, or perform any side effects (operations that impact things outside the component). They should update [objects](/learn/updating-objects-in-state) and [arrays](/learn/updating-arrays-in-state) without mutations.
- **Each action describes a single user interaction, even if that leads to multiple changes in the data.** For example, if a user presses "Reset" on a form with five fields managed by a reducer, it makes more sense to dispatch one `reset_form` action rather than five separate `set_field` actions. If you log every action in a reducer, that log should be clear enough for you to reconstruct what interactions or responses happened in what order. This helps with debugging!
-## Writing concise reducers with Immer {/* writing-concise-reducers-with-immer */}
+## Writing concise reducers with Immer {/*writing-concise-reducers-with-immer*/}
Just like with [updating objects](/learn/updating-objects-in-state#write-concise-update-logic-with-immer) and [arrays](/learn/updating-arrays-in-state#write-concise-update-logic-with-immer) in regular state, you can use the Immer library to make reducers more concise. Here, [`useImmerReducer`](https://github.com/immerjs/use-immer#useimmerreducer) lets you mutate the state with `push` or `arr[i] =` assignment:
@@ -1093,7 +1097,7 @@ Reducers must be pure, so they shouldn't mutate state. But Immer provides you wi
-#### Dispatch actions from event handlers {/* dispatch-actions-from-event-handlers */}
+#### Dispatch actions from event handlers {/*dispatch-actions-from-event-handlers*/}
Currently, the event handlers in `ContactList.js` and `Chat.js` have `// TODO` comments. This is why typing into the input doesn't work, and clicking on the buttons doesn't change the selected recipient.
@@ -1405,7 +1409,7 @@ textarea {
-#### Clear the input on sending a message {/* clear-the-input-on-sending-a-message */}
+#### Clear the input on sending a message {/*clear-the-input-on-sending-a-message*/}
Currently, pressing "Send" doesn't do anything. Add an event handler to the "Send" button that will:
@@ -1854,7 +1858,7 @@ With either solution, it's important that you **don't** place the `alert` inside
-#### Restore input values when switching between tabs {/* restore-input-values-when-switching-between-tabs */}
+#### Restore input values when switching between tabs {/*restore-input-values-when-switching-between-tabs*/}
In this example, switching between different recipients always clears the text input:
@@ -2235,7 +2239,7 @@ Notably, you didn't need to change any of the event handlers to implement this d
-#### Implement `useReducer` from scratch {/* implement-usereducer-from-scratch */}
+#### Implement `useReducer` from scratch {/*implement-usereducer-from-scratch*/}
In the earlier examples, you imported the `useReducer` Hook from React. This time, you will implement _the `useReducer` Hook itself!_ Here is a stub to get you started. It shouldn't take more than 10 lines of code.
diff --git a/beta/src/content/learn/start-a-new-react-project.md b/beta/src/content/learn/start-a-new-react-project.md
index 9c40f174..3e1d44d3 100644
--- a/beta/src/content/learn/start-a-new-react-project.md
+++ b/beta/src/content/learn/start-a-new-react-project.md
@@ -50,7 +50,7 @@ For more information, [check out the official guide.](https://create-react-app.d
> Create React App doesn't handle backend logic or databases. You can use it with any backend. When you build a project, you'll get a folder with static HTML, CSS and JS. Because Create React App can't take advantage of the server, it doesn't provide the best performance. If you're looking for faster loading times and built-in features like routing and server-side logic, we recommend using a framework instead.
-### Popular alternatives {/*popular-alternatives*/}
+### Popular alternatives {/*toolkit-popular-alternatives*/}
* [Vite](https://vitejs.dev/guide/)
* [Parcel](https://parceljs.org/getting-started/webapp/)
@@ -61,7 +61,7 @@ If you're looking to **start a production-ready project,** [Next.js](https://nex
The [Next.js Foundations](https://nextjs.org/learn/foundations/about-nextjs) tutorial is a great introduction to building with React and Next.js.
-### Popular alternatives {/*popular-alternatives*/}
+### Popular alternatives {/*framework-popular-alternatives*/}
* [Gatsby](https://www.gatsbyjs.org/)
* [Remix](https://remix.run/)
diff --git a/beta/src/pages/[[...markdownPath]].js b/beta/src/pages/[[...markdownPath]].js
index 839a61c7..ce183ccb 100644
--- a/beta/src/pages/[[...markdownPath]].js
+++ b/beta/src/pages/[[...markdownPath]].js
@@ -55,7 +55,7 @@ function reviveNodeOnClient(key, val) {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~ IMPORTANT: BUMP THIS IF YOU CHANGE ANY CODE BELOW ~~~
-const DISK_CACHE_BREAKER = 4;
+const DISK_CACHE_BREAKER = 5;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Put MDX output into JSON for client.