Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
scripts
plugins
next.config.js
.claude/
worker-bundle.dist.js
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"react-hooks/exhaustive-deps": "error",
"react/no-unknown-property": ["error", {"ignore": ["meta"]}],
"react-compiler/react-compiler": "error",
"local-rules/lint-markdown-code-blocks": "error"
"local-rules/lint-markdown-code-blocks": "error",
"no-trailing-spaces": "error"
},
"env": {
"node": true,
Expand Down
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/3-framework.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ body:
value: |
## Apply to be included as a recommended React framework

_This form is for framework authors to apply to be included as a recommended [React framework](https://react.dev/learn/start-a-new-react-project). If you are not a framework author, please contact the authors before submitting._
_This form is for framework authors to apply to be included as a recommended [React framework](https://react.dev/learn/creating-a-react-app). If you are not a framework author, please contact the authors before submitting._

Our goal when recommending a framework is to start developers with a React project that solves common problems like code splitting, data fetching, routing, and HTML generation without any extra work later. We believe this will allow users to get started quickly with React, and scale their app to production.

While we understand that many frameworks may want to be featured, this page is not a place to advertise every possible React framework or all frameworks that you can add React to. There are many great frameworks that offer support for React that are not listed in our guides. The frameworks we recommend have invested significantly in the React ecosystem, and collaborated with the React team to be compatible with our [full-stack React architecture vision](https://react.dev/learn/start-a-new-react-project#which-features-make-up-the-react-teams-full-stack-architecture-vision).
While we understand that many frameworks may want to be featured, this page is not a place to advertise every possible React framework or all frameworks that you can add React to. There are many great frameworks that offer support for React that are not listed in our guides. The frameworks we recommend have invested significantly in the React ecosystem, and collaborated with the React team to be compatible with our [full-stack React architecture vision](https://react.dev/learn/creating-a-react-app#which-features-make-up-the-react-teams-full-stack-architecture-vision).

To be included, frameworks must meet the following criteria:

Expand Down
11 changes: 10 additions & 1 deletion .github/workflows/analyze.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ jobs:
branch: ${{ github.event.pull_request.base.ref }}
name: bundle_analysis.json
path: .next/analyze/base/bundle
if_no_artifact_found: warn

# And here's the second place - this runs after we have both the current and
# base branch bundle stats, and will compare them to determine what changed.
Expand All @@ -80,7 +81,15 @@ jobs:
# entry in your package.json file.
- name: Compare with base branch bundle
if: success() && github.event.number
run: ls -laR .next/analyze/base && npx -p nextjs-bundle-analysis compare
run: |
if [ -f .next/analyze/base/bundle/__bundle_analysis.json ]; then
ls -laR .next/analyze/base
npx -p nextjs-bundle-analysis compare
else
echo "No base bundle analysis found. Creating placeholder comment."
mkdir -p .next/analyze
echo "No baseline bundle analysis was found for the base branch (it may have expired or not been generated yet)." > .next/analyze/__bundle_analysis_comment.txt
fi

- name: Upload analysis comment
uses: actions/upload-artifact@v4
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,10 @@ public/fonts/**/Optimistic_*.woff2

# rss
public/rss.xml

# claude local settings
.claude/*.local.*
.claude/react/

# worktrees
.worktrees/
52 changes: 52 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# CLAUDE.md

This file provides guidance to Claude Code when working with this repository.

## Project Overview

This is the React documentation website (react.dev), built with Next.js 15.1.11 and React 19. Documentation is written in MDX format.

## Development Commands

```bash
yarn build # Production build
yarn lint # Run ESLint
yarn lint:fix # Auto-fix lint issues
yarn tsc # TypeScript type checking
yarn check-all # Run prettier, lint:fix, tsc, and rss together
```

## Project Structure

```
src/
├── content/ # Documentation content (MDX files)
│ ├── learn/ # Tutorial/learning content
│ ├── reference/ # API reference docs
│ ├── blog/ # Blog posts
│ └── community/ # Community pages
├── components/ # React components
├── pages/ # Next.js pages
├── hooks/ # Custom React hooks
├── utils/ # Utility functions
└── styles/ # CSS/Tailwind styles
```

## Code Conventions

### TypeScript/React
- Functional components only
- Tailwind CSS for styling

### Documentation Style

When editing files in `src/content/`, the appropriate skill will be auto-suggested:
- `src/content/learn/` - Learn page structure and tone
- `src/content/reference/` - Reference page structure and tone

For MDX components (DeepDive, Pitfall, Note, etc.), invoke `/docs-components`.
For Sandpack code examples, invoke `/docs-sandpack`.

See `.claude/docs/react-docs-patterns.md` for comprehensive style guidelines.

Prettier is used for formatting (config in `.prettierrc`).
2 changes: 0 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

Thank you for your interest in contributing to the React Docs!

We are currently in the first translation phase and we will be relying completely on [Hsoub's translation](https://wiki.hsoub.com/React) as it is.

## Code of Conduct

Facebook has adopted a Code of Conduct that we expect project
Expand Down
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# reactjs.org
# react.dev

This repo contains the source code and documentation powering [reactjs.org](https://reactjs.org/).
This repo contains the source code and documentation powering [react.dev](https://react.dev/).

## Getting started

Expand All @@ -10,12 +10,12 @@ This repo contains the source code and documentation powering [reactjs.org](http
1. Node: any version starting with v16.8.0 or greater
1. Yarn: See [Yarn website for installation instructions](https://yarnpkg.com/lang/en/docs/install/)
1. A fork of the repo (for any contributions)
1. A clone of the [ar.react.dev repo](https://github.com/reactjs/ar.react.dev) on your local machine
1. A clone of the [react.dev repo](https://github.com/reactjs/react.dev) on your local machine

### Installation

1. `cd ar.react.dev` to go into the project root
1. `yarn` to install the website's npm dependencies
1. `cd react.dev` to go into the project root
3. `yarn` to install the website's npm dependencies

### Running locally

Expand All @@ -28,25 +28,26 @@ This repo contains the source code and documentation powering [reactjs.org](http

The documentation is divided into several sections with a different tone and purpose. If you plan to write more than a few sentences, you might find it helpful to get familiar with the [contributing guidelines](https://github.com/reactjs/react.dev/blob/main/CONTRIBUTING.md#guidelines-for-text) for the appropriate sections.

### Create a branch

1. `git checkout main` from any folder in your local `ar.react.dev` repository
1. `git checkout main` from any folder in your local `react.dev` repository
1. `git pull origin main` to ensure you have the latest main code
1. `git checkout -b the-name-of-my-branch` (replacing `the-name-of-my-branch` with a suitable name) to create a branch

#### Make the change
### Make the change

1. Follow the ["Running locally"](#running-locally) instructions
1. Save the files and check in the browser
1. Changes to React components in `src` will hot-reload
1. Changes to markdown files in `content` will hot-reload
1. If working with plugins, you may need to remove the `.cache` directory and restart the server

#### Test the change
### Test the change

1. If possible, test any visual changes in all latest versions of common browsers, on both desktop and mobile.
2. Run `yarn check-all`. (This will run Prettier, ESLint and validate types.)

#### Push it
### Push it

1. `git add -A && git commit -m "My message"` (replacing `My message` with a commit message, such as `Fix header logo on Android`) to stage and commit your changes
1. `git push my-fork-name the-name-of-my-branch`
Expand Down
24 changes: 24 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,30 @@ const nextConfig = {
scrollRestoration: true,
reactCompiler: true,
},
async rewrites() {
return {
beforeFiles: [
// Explicit .md extension also serves markdown
{
source: '/:path*.md',
destination: '/api/md/:path*',
},
// Serve markdown when Accept header prefers text/markdown
// Useful for LLM agents - https://www.skeptrune.com/posts/use-the-accept-header-to-serve-markdown-instead-of-html-to-llms/
{
source: '/:path((?!llms\\.txt|api/md).*)',
has: [
{
type: 'header',
key: 'accept',
value: '(.*text/markdown.*)',
},
],
destination: '/api/md/:path*',
},
],
};
},
env: {},
webpack: (config, {dev, isServer, ...options}) => {
if (process.env.ANALYZE) {
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"scripts": {
"analyze": "ANALYZE=true next build",
"dev": "next-remote-watch ./src/content",
"build": "next build && node --experimental-modules ./scripts/downloadFonts.mjs",
"prebuild:rsc": "node scripts/buildRscWorker.mjs",
"build": "node scripts/buildRscWorker.mjs && next build && node --experimental-modules ./scripts/downloadFonts.mjs",
"lint": "next lint && eslint \"src/content/**/*.md\"",
"lint:fix": "next lint --fix && eslint \"src/content/**/*.md\" --fix",
"format:source": "prettier --config .prettierrc --write \"{plugins,src}/**/*.{js,ts,jsx,tsx,css}\"",
Expand Down Expand Up @@ -35,9 +36,10 @@
"classnames": "^2.2.6",
"debounce": "^1.2.1",
"github-slugger": "^1.3.0",
"next": "15.4.8",
"next": "15.1.12",
"next-remote-watch": "^1.0.0",
"parse-numeric-range": "^1.2.0",
"raw-loader": "^4.0.2",
"react": "^19.0.0",
"react-collapsed": "4.0.4",
"react-dom": "^19.0.0",
Expand Down Expand Up @@ -65,6 +67,7 @@
"babel-eslint": "10.x",
"babel-plugin-react-compiler": "^1.0.0",
"chalk": "4.1.2",
"esbuild": "^0.24.0",
"eslint": "7.x",
"eslint-config-next": "12.0.3",
"eslint-config-react-app": "^5.2.1",
Expand All @@ -88,6 +91,7 @@
"postcss-flexbugs-fixes": "4.2.1",
"postcss-preset-env": "^6.7.0",
"prettier": "^2.5.1",
"react-server-dom-webpack": "^19.2.4",
"reading-time": "^1.2.0",
"remark": "^12.0.1",
"remark-external-links": "^7.0.0",
Expand Down
44 changes: 44 additions & 0 deletions scripts/buildRscWorker.mjs
Original file line number Diff line number Diff line change
@@ -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.
*/

import * as esbuild from 'esbuild';
import fs from 'fs';
import path from 'path';
import {fileURLToPath} from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const root = path.resolve(__dirname, '..');
const sandboxBase = path.resolve(
root,
'src/components/MDX/Sandpack/sandpack-rsc/sandbox-code/src'
);

// 1. Bundle the server Worker runtime (React server build + RSDW/server.browser + Sucrase → IIFE)
// Minified because this runs inside a Web Worker (not parsed by Sandpack's Babel).
const workerOutfile = path.resolve(sandboxBase, 'worker-bundle.dist.js');
await esbuild.build({
entryPoints: [path.resolve(sandboxBase, 'rsc-server.js')],
bundle: true,
format: 'iife',
platform: 'browser',
conditions: ['react-server', 'browser'],
outfile: workerOutfile,
define: {'process.env.NODE_ENV': '"production"'},
minify: true,
});

// Post-process worker bundle:
// Prepend the webpack shim so __webpack_require__ (used by react-server-dom-webpack)
// is defined before the IIFE evaluates. The shim sets globalThis.__webpack_require__,
// which is accessible as a bare identifier since globalThis IS the Worker's global scope.
let workerCode = fs.readFileSync(workerOutfile, 'utf8');

const shimPath = path.resolve(sandboxBase, 'webpack-shim.js');
const shimCode = fs.readFileSync(shimPath, 'utf8');
workerCode = shimCode + '\n' + workerCode;

fs.writeFileSync(workerOutfile, workerCode);
8 changes: 4 additions & 4 deletions scripts/deadLinkChecker.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const path = require('path');
const globby = require('globby');
const chalk = require('chalk');

const CONTENT_DIR = path.join(__dirname, '../src/content');
const PUBLIC_DIR = path.join(__dirname, '../public');
const CONTENT_DIR = path.join(__dirname, '../src/content').replace(/\\/g, '/');
const PUBLIC_DIR = path.join(__dirname, '../public').replace(/\\/g, '/');
const fileCache = new Map();
const anchorMap = new Map(); // Map<filepath, Set<anchorId>>
const contributorMap = new Map(); // Map<anchorId, URL>
Expand Down Expand Up @@ -135,7 +135,7 @@ async function findTargetFile(urlPath) {

for (const p of publicPaths) {
if (await fileExists(p)) {
return p;
return p.replace(/\\/g, '/');
}
}
}
Expand All @@ -154,7 +154,7 @@ async function findTargetFile(urlPath) {

for (const p of possiblePaths) {
if (await fileExists(p)) {
return p;
return p.replace(/\\/g, '/');
}
}
return null;
Expand Down
14 changes: 7 additions & 7 deletions scripts/downloadFonts.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/

import { exec } from 'child_process';
import { mkdir, promises as fsPromises } from 'fs';
import { promises as fsPromises } from 'fs';
import { dirname } from 'path';
import { promisify } from 'util';

const execAsync = promisify(exec);

// Taken from Downloads on https://www.facebook.com/brand/meta/typography/.
// To refresh the list, go to the Conf website's public/fonts/ folder and run this:
Expand Down Expand Up @@ -69,8 +65,12 @@ await Promise.all(
const localDir = dirname(localPath);
await fsPromises.mkdir(localDir, { recursive: true });

const command = `curl ${baseURL}${path} --output ${localPath}`;
await execAsync(command);
const response = await fetch(`${baseURL}${path}`);
if (!response.ok) {
throw new Error(`Failed to download ${path}: ${response.statusText}`);
}
const buffer = Buffer.from(await response.arrayBuffer());
await fsPromises.writeFile(localPath, buffer);
console.log(`Downloaded ${path}`);
})
);
Expand Down
8 changes: 7 additions & 1 deletion src/components/MDX/InlineCode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ function InlineCode({
return (
<code
// dir="ltr" // This is needed to prevent the code from inheriting the RTL direction of <html> in case of RTL languages to avoid like `()console.log` to be rendered as `console.log()`
dir={typeof props.children !== "string" ? "ltr" : ["[", "]"].includes(props.children) ? "rtl" : "ltr"}
dir={
typeof props.children !== 'string'
? 'ltr'
: ['[', ']'].includes(props.children)
? 'rtl'
: 'ltr'
}
className={cn(
'inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline',
{
Expand Down
Loading
Loading