1
0
mirror of synced 2025-12-19 18:11:23 -05:00

Upgrade next.js to 11.1.0 (#2656)

(minor)
This commit is contained in:
Brandon Bayer
2021-08-18 21:32:39 -05:00
committed by GitHub
parent 99f3f83335
commit cefb5c18ce
710 changed files with 24132 additions and 7456 deletions

View File

@@ -48,6 +48,8 @@ eslint.config.*
/nextjs/packages/next-codemod/**/*.js
/nextjs/packages/next-codemod/**/*.d.ts
/nextjs/packages/next-env/**/*.d.ts
/nextjs/packages/next/build/swc/tests/fixture/**
/nextjs/test/integration/async-modules/**
/nextjs/test/integration/eslint/**
/nextjs/test/integration/babel/**
/nextjs/test-timings.json

View File

@@ -1,5 +1,5 @@
module.exports = {
parser: "babel-eslint",
parser: "@babel/eslint-parser",
env: {
browser: true,
commonjs: true,
@@ -8,10 +8,18 @@ module.exports = {
},
parserOptions: {
ecmaVersion: 6,
requireConfigFile: false,
sourceType: "module",
ecmaFeatures: {
jsx: true,
},
babelOptions: {
presets: ["@babel/preset-env", "@babel/preset-react"],
caller: {
// Eslint supports top level await when a parser for it is included. We enable the parser by default for Babel.
supportsTopLevelAwait: true,
},
},
},
plugins: ["import", "unicorn", "simple-import-sort"],
extends: ["react-app"],

View File

@@ -41,8 +41,8 @@ jobs:
run: yarn manypkg check
env:
CI: true
- name: Build next.js
run: yarn build:nextjs
- name: Build packages
run: yarn build
env:
CI: true
- name: yarn lint
@@ -186,7 +186,7 @@ jobs:
with:
path: ./*
key: ${{ runner.os }}-${{ github.sha }}
- run: ./check-pre-compiled.sh
- run: ./scripts/check-pre-compiled.sh
testUnit:
name: Nextjs - Test Unit

1
.gitignore vendored
View File

@@ -31,3 +31,4 @@ db.sqlite-journal
test/integration/**/db.json
test/**/*/out
.blitz**

View File

@@ -19,11 +19,12 @@
6. Resolve all merge conflicts and complete merge
7. Run `yarn` and make sure all builds complete
8. Run `yarn lint` and fix any issues
9. `git push`
4. Run `yarn pull next-nextjs`
9. Commit all changes to finish merge
10. `git push`
4. Run `yarn pull-nextjs`
5. Run `yarn`
6. Run `yarn manypkg check` and optionally `yarn manypkg fix` to fix any issues
7. Under `nextjs/`, run `./check-pre-compiled.sh` and commit the changes
7. Under `nextjs/`, run `./scripts/check-pre-compiled.sh` and commit the changes
8. Run `yarn build:nextjs`
9. Run `yarn lint` - fix any issues
10. Run `yarn build` - fix any issues
@@ -33,3 +34,38 @@
14. Any doc updates needed?
15. Merge PR
16. `yarn push-nextjs`
#### Troubleshooting
##### yarn lint - Failed to load parser
Caused by invalid version of `@babel/eslint-parser`. `7.13.14` is a working version. I think it may be an incompatibility between this version and the version of eslint?
- change version of eslint-parser
- run `yarn --check-files`
- run `./scripts/check-pre-compiled.sh` from `./nextjs/`
- run `yarn build:nextjs` from root
- Try linting again
```
~/c/blitz> yarn lint
yarn run v1.22.10
$ eslint --ext ".js,.ts,.tsx" .
Oops! Something went wrong! :(
ESLint: 7.21.0
Error: Failed to load parser './parser.js' declared in 'examples/auth/.eslintrc.js » eslint-config-blitz » eslint-config-next': Cannot find module '@babel/parser'
at webpackEmptyContext (/Users/b/c/blitz/nextjs/packages/next/dist/compiled/babel/bundle.js:1:33258)
at Object.73139 (/Users/b/c/blitz/nextjs/packages/next/dist/compiled/babel/bundle.js:2194:783181)
at __nccwpck_require__ (/Users/b/c/blitz/nextjs/packages/next/dist/compiled/babel/bundle.js:2194:1065271)
at Object.eslintParser (/Users/b/c/blitz/nextjs/packages/next/dist/compiled/babel/bundle.js:1:43676)
at Object.<anonymous> (/Users/b/c/blitz/nextjs/packages/next/dist/compiled/babel/eslint-parser.js:1:100)
at Module._compile (/Users/b/c/blitz/node_modules/v8-compile-cache/v8-compile-cache.js:192:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19)
error Command failed with exit code 2.
```

View File

@@ -41,7 +41,6 @@
"@testing-library/react-hooks": "^4.0.1",
"@types/react": "17.0.2",
"@types/secure-password": "3.1.0",
"babel-eslint": "~10.1.0",
"eslint": "7.21.0",
"eslint-config-react-app": "~6.0.0",
"eslint-plugin-flowtype": "~5.2.0",

View File

@@ -34,7 +34,6 @@
},
"devDependencies": {
"@types/react": "17.0.2",
"babel-eslint": "~10.1.0",
"eslint": "7.21.0",
"eslint-config-react-app": "~6.0.0",
"eslint-plugin-flowtype": "~5.2.0",

View File

@@ -39,7 +39,6 @@
"react-dom": "0.0.0-experimental-6a589ad71"
},
"devDependencies": {
"babel-eslint": "~10.1.0",
"eslint": "7.21.0",
"eslint-config-react-app": "~6.0.0",
"eslint-plugin-flowtype": "~5.2.0",

View File

@@ -1,4 +1,2 @@
CODE_OF_CONDUCT.md
docs/
errors/
examples/

21
nextjs/.alexrc Normal file
View File

@@ -0,0 +1,21 @@
{
"allow": [
"attacks",
"color",
"dead",
"execute",
"executed",
"executes",
"execution",
"executions",
"failed",
"failure",
"failures",
"fire",
"fires",
"hook",
"hooks",
"host-hostess",
"invalid"
]
}

View File

@@ -6,6 +6,10 @@ e2e-tests/**
examples/with-eslint/**
examples/with-typescript-eslint-jest/**
examples/with-kea/**
examples/with-custom-babel-config/**
examples/with-flow/**
examples/with-mobx-state-tree/**
examples/with-mobx/**
packages/next/bundles/webpack/packages/*.runtime.js
packages/next/compiled/**/*
packages/react-refresh-utils/**/*.js
@@ -21,3 +25,4 @@ packages/create-next-app/templates/**
test/integration/async-modules/**
test/integration/eslint/**
test-timings.json
packages/next/build/swc/tests/fixture/**

View File

@@ -1,6 +1,6 @@
{
"root": true,
"parser": "babel-eslint",
"parser": "@babel/eslint-parser",
"plugins": ["react", "react-hooks", "jest", "import"],
"env": {
"browser": true,
@@ -9,10 +9,17 @@
"node": true
},
"parserOptions": {
"ecmaVersion": 2018,
"requireConfigFile": false,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
},
"babelOptions": {
"presets": ["@babel/preset-env", "@babel/preset-react"],
"caller": {
// Eslint supports top level await when a parser for it is included. We enable the parser by default for Babel.
"supportsTopLevelAwait": true
}
}
},
"settings": {

View File

@@ -1,6 +1,6 @@
# Learn how to add code owners here:
# https://help.github.com/en/articles/about-code-owners
* @timneutkens @ijjk @lfades @divmain @shuding
/docs/ @timneutkens @ijjk @lfades @divmain @shuding @leerob
/examples/ @timneutkens @ijjk @lfades @divmain @shuding @leerob
* @timneutkens @ijjk @shuding @styfle @huozhi @padmaia
/docs/ @timneutkens @ijjk @shuding @styfle @huozhi @padmaia @leerob @lfades
/examples/ @timneutkens @ijjk @shuding @leerob @lfades

View File

@@ -102,13 +102,17 @@ if (!allowedActions.has(actionInfo.actionName) && !actionInfo.isRelease) {
logger(`Running initial build for ${dir}`)
if (!actionInfo.skipClone) {
let buildCommand = `cd ${dir}${
!statsConfig.skipInitialInstall ? ' && yarn install' : ''
!statsConfig.skipInitialInstall
? ' && yarn install --network-timeout 1000000'
: ''
}`
if (statsConfig.initialBuildCommand) {
buildCommand += ` && ${statsConfig.initialBuildCommand}`
}
await exec(buildCommand)
// allow 5 minutes node_modules install + building all packages
// in case of noisy environment slowing down initial repo build
await exec(buildCommand, false, { timeout: 5 * 60 * 1000 })
}
logger(`Linking packages in ${dir}`)

View File

@@ -9,13 +9,24 @@
"packages/react-refresh-utils/**",
"packages/next-codemod/**"
],
"type: chrome": [
"created-by: Chrome Aurora": [
{ "type": "user", "pattern": "spanicker" },
{ "type": "user", "pattern": "housseindjirdeh" },
{ "type": "user", "pattern": "devknoll" },
{ "type": "user", "pattern": "janicklas-ralph" },
{ "type": "user", "pattern": "atcastle" },
{ "type": "user", "pattern": "Joonpark13" }
{ "type": "user", "pattern": "kyliau" },
{ "type": "user", "pattern": "kara" }
],
"created-by: Next.js team": [
{ "type": "user", "pattern": "ijjk" },
{ "type": "user", "pattern": "padmaia" },
{ "type": "user", "pattern": "huozhi" },
{ "type": "user", "pattern": "shuding" },
{ "type": "user", "pattern": "sokra" },
{ "type": "user", "pattern": "styfle" },
{ "type": "user", "pattern": "leerob" },
{ "type": "user", "pattern": "timneutkens" }
]
}
}

View File

@@ -8,6 +8,7 @@ Choose the right checklist for the change that you're making:
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
@@ -16,6 +17,7 @@ Choose the right checklist for the change that you're making:
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples

View File

@@ -0,0 +1,154 @@
on:
workflow_dispatch:
pull_request:
types: [opened, synchronize]
paths:
- 'packages/next/build/swc/**'
name: Build next-swc native binaries
jobs:
build:
strategy:
matrix:
os: [ubuntu-18.04, macos-latest, windows-latest]
name: stable - ${{ matrix.os }} - node@14
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: 14
check-latest: true
- name: Install
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
- name: Cache cargo registry
uses: actions/cache@v1
with:
path: ~/.cargo/registry
key: stable-${{ matrix.os }}-node@14-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v1
with:
path: ~/.cargo/git
key: stable-${{ matrix.os }}-node@14-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }}
- name: Cache NPM dependencies
uses: actions/cache@v1
with:
path: node_modules
key: npm-cache-${{ matrix.os }}-node@14-${{ hashFiles('yarn.lock') }}
- name: 'Install dependencies'
run: yarn install --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000
- name: 'Build'
run: yarn --cwd packages/next build-native
env:
MACOSX_DEPLOYMENT_TARGET: '10.13'
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: next-swc-binaries
path: packages/next/native
- name: Clear the cargo caches
run: |
cargo install cargo-cache --no-default-features --features ci-autoclean
cargo-cache
build-apple-silicon:
name: stable - aarch64-apple-darwin - node@14
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: 14
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
override: true
toolchain: nightly-2021-03-25
target: aarch64-apple-darwin
- name: Install dependencies
run: yarn install --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000
- name: Cross build aarch64
run: yarn --cwd packages/next build-native --target aarch64-apple-darwin
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: next-swc-binaries
path: packages/next/native
- name: Clear the cargo caches
run: |
cargo install cargo-cache --no-default-features --features ci-autoclean
cargo-cache
commit:
needs: [build, build-apple-silicon]
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
if: ${{ github.event_name == 'workflow_dispatch' }}
- uses: actions/download-artifact@v2
with:
name: next-swc-binaries
path: packages/next/native
if: ${{ github.event_name == 'workflow_dispatch' }}
- uses: EndBug/add-and-commit@v7
with:
add: 'packages/next/native --force'
message: 'Build next-swc binaries'
if: ${{ github.event_name == 'workflow_dispatch' }}
check:
needs: [build, build-apple-silicon]
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
if: ${{ github.event_name == 'pull_request' }}
- uses: actions/download-artifact@v2
with:
name: next-swc-binaries
path: packages/next/native
if: ${{ github.event_name == 'pull_request' }}
- run: git diff --exit-code
if: ${{ github.event_name == 'pull_request' }}
test:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
if: ${{ github.event_name == 'pull_request' }}
- name: Install
if: ${{ github.event_name == 'pull_request' }}
uses: actions-rs/toolchain@v1
with:
toolchain: nightly-2021-03-25
profile: minimal
- run: cd packages/next/build/swc && cargo test
if: ${{ github.event_name == 'pull_request' }}

View File

@@ -40,6 +40,7 @@ jobs:
with:
path: ./*
key: ${{ github.sha }}
- run: ./scripts/check-manifests.js
- run: yarn lint
checkPrecompiled:
@@ -55,7 +56,7 @@ jobs:
with:
path: ./*
key: ${{ github.sha }}
- run: ./check-pre-compiled.sh
- run: ./scripts/check-pre-compiled.sh
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testUnit:
@@ -146,7 +147,7 @@ jobs:
path: ./*
key: ${{ github.sha }}
- run: bash ./test-pnp.sh
- run: bash ./scripts/test-pnp.sh
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testsPass:
@@ -251,9 +252,9 @@ jobs:
path: ./*
key: ${{ github.sha }}
- run: ./publish-release.sh
- run: ./scripts/publish-release.sh
prStats:
releaseStats:
name: Release Stats
runs-on: ubuntu-latest
needs: [publishRelease]
@@ -263,7 +264,7 @@ jobs:
with:
path: ./*
key: ${{ github.sha }}
- run: ./release-stats.sh
- run: ./scripts/release-stats.sh
- uses: ./.github/actions/next-stats-action
env:
PR_STATS_COMMENT_TOKEN: ${{ secrets.PR_STATS_COMMENT_TOKEN }}

5
nextjs/.gitignore vendored
View File

@@ -1,6 +1,7 @@
# build output
dist
.next
target
# dependencies
node_modules
@@ -37,3 +38,7 @@ test-timings.json
# Vercel
.vercel
.now
#blitz
/packages/next/db.json
/db.json

View File

@@ -6,7 +6,7 @@
[subrepo]
remote = git@github.com:blitz-js/next.js.git
branch = canary
commit = 08cae3bd023ba14074fde394231890cf65db0427
parent = aa85d1d47ea23dbeeb718fd98089a8700786055b
commit = a0fcfae6319bf775ece700c2b2d817b869f594b5
parent = b7dadba616c9aa022327f4f95e1b452a0c6e878e
method = merge
cmdver = 0.4.3

View File

@@ -16,6 +16,7 @@ packages/next-codemod/**/*.js
packages/next-codemod/**/*.d.ts
packages/next-env/**/*.d.ts
test-timings.json
test/**/out/**
// Because file from nextjs upstream isn't formatted properly
nextjs/packages/next/build/webpack-config.ts

View File

@@ -72,6 +72,8 @@ stages:
- job: test_ie11
pool:
vmImage: 'windows-2019'
variables:
BROWSER_NAME: internet explorer
steps:
- checkout: none
- task: NodeTool@0
@@ -86,7 +88,7 @@ stages:
path: $(System.DefaultWorkingDirectory)
displayName: Cache Build
- script: |
yarn testie --forceExit test/integration/production/ test/integration/css-client-nav/ test/integration/rewrites-has-condition/
node run-tests.js -c 1 test/integration/production/test/index.test.js test/integration/css-client-nav/test/index.test.js test/integration/rewrites-has-condition/test/index.test.js
displayName: 'Run tests'
- job: test_unit
@@ -111,36 +113,37 @@ stages:
- script: |
node run-tests.js -g 1/1 --timings --azure --type unit
displayName: 'Run tests'
- job: test_chrome_integration
pool:
vmImage: 'windows-2019'
strategy:
matrix:
nodejs-1:
group: 1/4
nodejs-2:
group: 2/4
nodejs-3:
group: 3/4
nodejs-4:
group: 4/4
steps:
- checkout: none
- script: |
wmic datafile where name="C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" get Version /value
displayName: 'List Chrome version'
- task: NodeTool@0
inputs:
versionSpec: $(node_version)
displayName: 'Install Node.js'
- task: Cache@2
inputs:
# use deterministic cache key that is specific
# to this test run
key: $(Build.SourceVersion)
path: $(System.DefaultWorkingDirectory)
displayName: Cache Build
- script: |
node run-tests.js -g $(group) --timings --azure
displayName: 'Run tests'
# TODO: investigate re-enabling when stability matches running in
# tests in ubuntu environment
# - job: test_chrome_integration
# pool:
# vmImage: 'windows-2019'
# strategy:
# matrix:
# nodejs-1:
# group: 1/4
# nodejs-2:
# group: 2/4
# nodejs-3:
# group: 3/4
# nodejs-4:
# group: 4/4
# steps:
# - checkout: none
# - script: |
# wmic datafile where name="C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" get Version /value
# displayName: 'List Chrome version'
# - task: NodeTool@0
# inputs:
# versionSpec: $(node_version)
# displayName: 'Install Node.js'
# - task: Cache@2
# inputs:
# # use deterministic cache key that is specific
# # to this test run
# key: $(Build.SourceVersion)
# path: $(System.DefaultWorkingDirectory)
# displayName: Cache Build
# - script: |
# node run-tests.js -g $(group) --timings --azure
# displayName: 'Run tests'

View File

@@ -12,7 +12,34 @@ Read about our [Commitment to Open Source](https://vercel.com/oss).
> You may need to run `yarn types` again if your types get outdated.
To contribute to [our examples](examples), take a look at the [“Adding examples” section](#adding-examples).
To contribute to [our examples](examples), take a look at the [“Adding examples”
section](#adding-examples).
## Building
You can build the project, including all type definitions, with:
```bash
yarn build
# - or -
yarn prepublish
```
If you need to clean the project for any reason, use `yarn clean`.
## Adding warning/error descriptions
In Next.js we have a system to add helpful links to warnings and errors.
This allows for the logged message to be short while giving a broader description and instructions on how to solve the warning/error.
In general all warnings and errors added should have these links attached.
Below are the steps to add a new link:
- Create a new markdown file under the `errors` directory based on `errors/template.md`: `cp errors/template.md errors/<error-file-name>.md`
- Add the newly added file to `errors/manifest.json`
- Add the following url to your warning/error: `https://nextjs.org/docs/messages/<file-path-without-dotmd>`. For example to link to `errors/api-routes-static-export.md` you use the url: `https://nextjs.org/docs/messages/api-routes-static-export`
## To run tests
@@ -22,6 +49,8 @@ Make sure you have `chromedriver` installed for your Chrome version. You can ins
- `chocolatey install chromedriver` on Windows
- Or manually download the version that matches your installed chrome version (if there's no match, download a version under it, but not above) from the [chromedriver repo](https://chromedriver.storage.googleapis.com/index.html) and add the binary to `<next-repo>/node_modules/.bin`
You may also have to [install Rust](https://www.rust-lang.org/tools/install) and build our native packages to see all tests pass locally. We check in binaries for the most common targets and those required for CI so that most people don't have to, but if you do not see a binary for your target in `packages/next/native`, you can build it by running `yarn --cwd packages/next build-native`. If you are working on the Rust code and you need to build the binaries for ci, you can manually trigger [the workflow](https://github.com/vercel/next.js/actions/workflows/build_native.yml) to build and commit with the "Run workflow" button.
Running all tests:
```sh
@@ -79,6 +108,14 @@ EXAMPLE=./test/integration/basic
## Running your own app with locally compiled version of Next.js
1. Move your app inside of the Next.js monorepo.
2. Run with `yarn next-with-deps ./app-path-in-monorepo`
This will use the version of `next` built inside of the Next.js monorepo and the main `yarn dev` monorepo command can be running to make changes to the local Next.js version at the same time (some changes might require re-running `yarn next-with-deps` to take affect).
or
1. In your app's `package.json`, replace:
```json
@@ -155,3 +192,7 @@ yarn create next-app --example DIRECTORY_NAME DIRECTORY_NAME-app
Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
````
## Publishing
Repository maintainers can use `yarn publish-canary` to publish a new version of all packages to npm.

View File

@@ -1,8 +0,0 @@
{
"users": [
{
"id": 1
}
],
"sessions": []
}

View File

@@ -169,7 +169,7 @@ export default withRouter(
)
```
This is just one case. All the cases that are transformed (and tested) can be found in the [`__testfixtures__` directory](https://github.com/vercel/next.js/tree/canary/packages/next-codemod/transforms/__testfixtures__/url-to-withrouter).
This is one case. All the cases that are transformed (and tested) can be found in the [`__testfixtures__` directory](https://github.com/vercel/next.js/tree/canary/packages/next-codemod/transforms/__testfixtures__/url-to-withrouter).
#### Usage

View File

@@ -42,7 +42,7 @@ The `Component` prop is the active `page`, so whenever you navigate between rout
### Caveats
- If your app is running and you just added a custom `App`, you'll need to restart the development server. Only required if `pages/_app.js` didn't exist before.
- If your app is running and you added a custom `App`, you'll need to restart the development server. Only required if `pages/_app.js` didn't exist before.
- Adding a custom `getInitialProps` in your `App` will disable [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md) in pages without [Static Generation](/docs/basic-features/data-fetching.md#getstaticprops-static-generation).
- When you add `getInitialProps` in your custom app, you must `import App from "next/app"`, call `App.getInitialProps(appContext)` inside `getInitialProps` and merge the returned object into the return value.
- `App` currently does not support Next.js [Data Fetching methods](/docs/basic-features/data-fetching.md) like [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) or [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering).

View File

@@ -17,9 +17,9 @@ description: Start a Next.js app programmatically using a custom server.
By default, Next.js includes its own server with `next start`. If you have an existing backend, you can still use it with Next.js (this is not a custom server). A custom Next.js server allows you to start a server 100% programmatically in order to use custom server patterns. Most of the time, you will not need this but it's available for complete customization.
> A custom server **can not** be deployed on [Vercel](https://vercel.com/solutions/nextjs), the platform Next.js was made for.
> **Note:** A custom server **can not** be deployed on [Vercel](https://vercel.com/solutions/nextjs).
> Before deciding to use a custom server please keep in mind that it should only be used when the integrated router of Next.js can't meet your app requirements. A custom server will remove important performance optimizations, like **serverless functions** and **[Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md).**
> Before deciding to use a custom server, please keep in mind that it should only be used when the integrated router of Next.js can't meet your app requirements. A custom server will remove important performance optimizations, like **serverless functions** and **[Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md).**
Take a look at the following example of a custom server:

View File

@@ -55,7 +55,7 @@ Create a file named `.vscode/launch.json` at the root of your project with this
{
"type": "node",
"request": "attach",
"name": "Launch Program",
"name": "Attach to application",
"skipFiles": ["<node_internals>/**"],
"port": 9229
}
@@ -69,7 +69,7 @@ Now hit <kdb>F5</kbd> or select **Debug: Start Debugging** from the Command Pale
Now you can use the [`debugger`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger) statement to pause your backend or frontend code anytime you want to observe and debug your code more precisely.
If you trigger the underlying code by refreshing the current page, clicking on a page link or fetching an API route, your code will be paused and the debugger window will pop up.
If you trigger the underlying code by refreshing the current page, clicking on a page link or fetching an API route, your code will be paused and the debugger window will appear.
To learn more on how to use a JavaScript debugger, take a look at the following documentation:

View File

@@ -45,7 +45,7 @@ export default function Page() {
You can think of dynamic imports as another way to split your code into manageable chunks.
React components can also be imported using dynamic imports, but in this case we use it in conjunction with `next/dynamic` to make sure it works just like any other React Component. Check out the sections below for more details on how it works.
React components can also be imported using dynamic imports, but in this case we use it in conjunction with `next/dynamic` to make sure it works like any other React Component. Check out the sections below for more details on how it works.
## Basic usage

View File

@@ -281,3 +281,8 @@ export const getStaticPaths = ({ locales }) => {
}
}
```
## Limits for the i18n config
- `locales`: 100 total locales
- `domains`: 100 total locale domain items

View File

@@ -18,7 +18,7 @@ With multi zones support, you can merge both these apps into a single one allowi
## How to define a zone
There are no special zones related APIs. You only need to do following:
There are no zone related APIs. You only need to do the following:
- Make sure to keep only the pages you need in your app, meaning that an app can't have pages from another app, if app `A` has `/blog` then app `B` shouldn't have it too.
- Make sure to configure a [basePath](/docs/api-reference/next.config.js/basepath.md) to avoid conflicts with pages and static files.

View File

@@ -48,7 +48,7 @@ If you're deploying to [Vercel](https://vercel.com/docs/edge-network/headers#str
```jsx
{
key: 'Strict-Transport-Security',
value: 'max-age=31536000; includeSubDomains; preload'
value: 'max-age=63072000; includeSubDomains; preload'
}
```

View File

@@ -17,7 +17,7 @@ The exported app supports almost every feature of Next.js, including dynamic rou
`next export` works by prerendering all pages to HTML. For [dynamic routes](/docs/routing/dynamic-routes.md), your page can export a [`getStaticPaths`](/docs/basic-features/data-fetching.md#getstaticpaths-static-generation) function to let the exporter know which HTML pages to generate for that route.
> `next export` is intended for scenarios where **none** of your pages have server-side or incremental data requirements (though statically-rendered pages can still [fetch data on the client side](/docs/basic-features/data-fetching.md#fetching-data-on-the-client-side) just fine).
> `next export` is intended for scenarios where **none** of your pages have server-side or incremental data requirements (though statically-rendered pages can still [fetch data on the client side](/docs/basic-features/data-fetching.md#fetching-data-on-the-client-side)).
>
> If you're looking to make a hybrid site where only _some_ pages are prerendered to static HTML, Next.js already does that automatically for you! Read up on [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md) for details.
>

View File

@@ -46,7 +46,7 @@ NODE_OPTIONS='--inspect' next
- **Size** The number of assets downloaded when navigating to the page client-side. The size for each route only includes its dependencies.
- **First Load JS** The number of assets downloaded when visiting the page from the server. The amount of JS shared by all is shown as a separate metric.
The first load is colored green, yellow, or red. Aim for green for performant applications.
The first load is indicated by green, yellow, or red. Aim for green for performant applications.
You can enable production profiling for React with the `--profile` flag in `next build`. This requires [Next.js 9.5](https://nextjs.org/blog/next-9-5):

View File

@@ -4,7 +4,7 @@ description: Create Next.js apps in one command with create-next-app.
# Create Next App
The easiest way to get started with Next.js is by using `create-next-app`. This simple CLI tool enables you to quickly start building a new Next.js application, with everything set up for you. You can create a new app using the default Next.js template, or by using one of the [official Next.js examples](https://github.com/vercel/next.js/tree/canary/examples). To get started, use the following command:
The easiest way to get started with Next.js is by using `create-next-app`. This CLI tool enables you to quickly start building a new Next.js application, with everything set up for you. You can create a new app using the default Next.js template, or by using one of the [official Next.js examples](https://github.com/vercel/next.js/tree/canary/examples). To get started, use the following command:
```bash
npx create-next-app

View File

@@ -10,7 +10,7 @@ Open `next.config.js` and add the `pageExtensions` config:
```js
module.exports = {
pageExtensions: ['mdx', 'jsx', 'js', 'ts', 'tsx'],
pageExtensions: ['mdx', 'md', 'jsx', 'js', 'tsx', 'ts'],
}
```

View File

@@ -0,0 +1,36 @@
---
description: Next.js will automatically use HTTP Keep-Alive by default. Learn more about how to disable HTTP Keep-Alive here.
---
# Disabling HTTP Keep-Alive
Next.js automatically polyfills [node-fetch](/docs/basic-features/supported-browsers-features#polyfills) and enables [HTTP Keep-Alive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive) by default. You may want to disable HTTP Keep-Alive for certain `fetch()` calls or globally.
For a single `fetch()` call, you can add the agent option:
```js
import { Agent } from 'https'
const url = 'https://example.com'
const agent = new Agent({ keepAlive: false })
fetch(url, { agent })
```
To override all `fetch()` calls globally, you can use `next.config.js`:
```js
module.exports = {
httpAgentOptions: {
keepAlive: false,
},
}
```
## Related
<div class="card">
<a href="/docs/api-reference/next.config.js/introduction.md">
<b>Introduction to next.config.js:</b>
<small>Learn more about the configuration file used by Next.js.</small>
</a>
</div>

View File

@@ -166,13 +166,17 @@ The following characters `(`, `)`, `{`, `}`, `:`, `*`, `+`, `?` are used for reg
```js
module.exports = {
async redirects() {
async headers() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
permanent: false,
headers: [
{
key: 'x-header',
value: 'value',
},
],
},
]
},

View File

@@ -6,16 +6,14 @@ description: Next.js reports ESLint errors and warnings during builds by default
When ESLint is detected in your project, Next.js fails your **production build** (`next build`) when errors are present.
If you'd like Next.js to dangerously produce production code even when your application has ESLint errors, you can disable the built-in linting step completely.
> Be sure you have configured ESLint to run in a separate part of your workflow (for example, in CI or a pre-commit hook).
If you'd like Next.js to produce production code even when your application has ESLint errors, you can disable the built-in linting step completely. This is not recommended unless you already have ESLint configured to run in a separate part of your workflow (for example, in CI or a pre-commit hook).
Open `next.config.js` and enable the `ignoreDuringBuilds` option in the `eslint` config:
```js
module.exports = {
eslint: {
// Warning: Dangerously allow production builds to successfully complete even if
// Warning: This allows production builds to successfully complete even if
// your project has ESLint errors.
ignoreDuringBuilds: true,
},

View File

@@ -11,22 +11,31 @@ For custom advanced behavior of Next.js, you can create a `next.config.js` in th
Take a look at the following `next.config.js` example:
```js
module.exports = {
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
/* config options here */
}
module.exports = nextConfig
```
You can also use a function:
```js
module.exports = (phase, { defaultConfig }) => {
return {
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
/* config options here */
}
return nextConfig
}
```
`phase` is the current context in which the configuration is loaded. You can see the [available phases](https://github.com/vercel/next.js/blob/canary/packages/next/next-server/lib/constants.ts#L1-L4). Phases can be imported from `next/constants`:
`phase` is the current context in which the configuration is loaded. You can see the [available phases](https://github.com/vercel/next.js/blob/canary/packages/next/shared/lib/constants.ts#L1-L4). Phases can be imported from `next/constants`:
```js
const { PHASE_DEVELOPMENT_SERVER } = require('next/constants')
@@ -44,7 +53,7 @@ module.exports = (phase, { defaultConfig }) => {
}
```
The commented lines are the place where you can put the configs allowed by `next.config.js`, which are [defined in this file](https://github.com/vercel/next.js/blob/canary/packages/next/next-server/server/config-shared.ts#L68).
The commented lines are the place where you can put the configs allowed by `next.config.js`, which are [defined in this file](https://github.com/vercel/next.js/blob/canary/packages/next/server/config-shared.ts#L68).
However, none of the configs are required, and it's not necessary to understand what each config does. Instead, search for the features you need to enable or modify in this section and they will show you what to do.

View File

@@ -52,6 +52,18 @@ module.exports = {
Redirects are checked before the filesystem which includes pages and `/public` files.
When a redirect is applied, any query values provided in the request will be passed through to the redirect destination. For example, see the following redirect configuration:
```js
{
source: '/old-blog/:path*',
destination: '/blog/:path*',
permanent: false
}
```
When `/old-blog/post-1?hello=world` is requested, the client will be redirected to `/blog/post-1?hello=world`.
## Path Matching
Path matches are allowed, for example `/old-blog/:slug` will match `/old-blog/hello-world` (no nested paths):

View File

@@ -87,6 +87,17 @@ module.exports = {
}
```
Note: rewrites in `beforeFiles` do not check the filesystem/dynamic routes immediately after matching a source, they continue until all `beforeFiles` have been checked.
The order Next.js routes are checked is:
1. [headers](/docs/api-reference/next.config.js/headers) are checked/applied
2. [redirects](/docs/api-reference/next.config.js/redirects) are checked/applied
3. `beforeFiles` rewrites are checked/applied
4. static files from the [public directory](/docs/basic-features/static-file-serving), `_next/static` files, and non-dynamic pages are checked/served
5. `afterFiles` rewrites are checked/applied, if one of these rewrites is matched we check dynamic routes/static files after each match
6. `fallback` rewrites are checked/applied, these are applied before rendering the 404 page and after dynamic routes/all static assets have been checked.
## Rewrite parameters
When using parameters in a rewrite the parameters will be passed in the query by default when none of the parameters are used in the `destination`.
@@ -192,13 +203,12 @@ The following characters `(`, `)`, `{`, `}`, `:`, `*`, `+`, `?` are used for reg
```js
module.exports = {
async redirects() {
async rewrites() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
permanent: false,
},
]
},

View File

@@ -61,3 +61,5 @@ In this case only the second `<meta property="og:title" />` is rendered. `meta`
`title`, `meta` or any other elements (e.g. `script`) need to be contained as **direct** children of the `Head` element,
or wrapped into maximum one level of `<React.Fragment>` or arrays—otherwise the tags won't be correctly picked up on client-side navigations.
> We recommend using [next/script](/docs/basic-features/script.md) in your component instead of manually creating a `<script>` in `next/head`.

View File

@@ -16,6 +16,7 @@ description: Enable Image Optimization with the built-in Image component.
| Version | Changes |
| --------- | ------------------------------------------------------------------------------------------------- |
| `v11.1.0` | `onLoadingComplete` and `lazyBoundary` props added. |
| `v11.0.0` | `src` prop support for static import.<br/>`placeholder` prop added.<br/>`blurDataURL` prop added. |
| `v10.0.5` | `loader` prop added. |
| `v10.0.1` | `layout` prop added. |
@@ -100,9 +101,11 @@ but maintain the original dimensions for larger viewports.
When `responsive`, the image will scale the dimensions down for smaller
viewports and scale up for larger viewports.
Note: the responsive layout may not work correctly if the parent element uses a display value other than `block` such as `display: flex` or `display: grid`.
When `fill`, the image will stretch both width and height to the dimensions of
the parent element, usually paired with the [`objectFit`](#objectFit) property.
the parent element, provided the parent element is relative. This is usually paired with the [`objectFit`](#objectFit) property.
Ensure the parent element has `position: relative` in their stylesheet.
Try it out:
@@ -195,6 +198,15 @@ The image position when using `layout="fill"`.
[Learn more](https://developer.mozilla.org/en-US/docs/Web/CSS/object-position)
### onLoadingComplete
A callback function that is invoked once the image is completely loaded and the [placeholder](#placeholder) has been removed.
The `onLoadingComplete` function accepts one parameter, an object with the following properties:
- [`naturalWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalWidth)
- [`naturalHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalHeight)
### loading
> **Attention**: This property is only meant for advanced usage. Switching an
@@ -228,6 +240,12 @@ Try it out:
You can also [generate a solid color Data URL](https://png-pixel.com) to match the image.
### lazyBoundary
A string (with similar syntax to the margin property) that acts as the bounding box used to detect the intersection of the viewport with the image and trigger lazy [loading](#loading). Defaults to `"200px"`.
[Learn more](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/rootMargin)
### unoptimized
When true, the source image will be served as-is instead of changing quality,
@@ -242,6 +260,7 @@ Other properties on the `<Image />` component will be passed to the underlying
- `srcSet`. Use
[Device Sizes](/docs/basic-features/image-optimization.md#device-sizes)
instead.
- `ref`. Use [`onLoadingComplete`](#onloadingcomplete) instead.
- `decoding`. It is always `"async"`.
## Related

View File

@@ -65,7 +65,7 @@ export default Home
## If the route has dynamic segments
There is nothing special to do when linking to a [dynamic route](/docs/routing/dynamic-routes.md), including [catch all routes](/docs/routing/dynamic-routes.md#catch-all-routes), since Next.js 9.5.3 (for older versions check our [previous docs](https://nextjs.org/docs/tag/v9.5.2/api-reference/next/link#dynamic-routes)). However, it can become quite common and handy to use [interpolation](/docs/routing/introduction.md#linking-to-dynamic-paths) or an [URL Object](#with-url-object) to generate the link.
There is nothing to do when linking to a [dynamic route](/docs/routing/dynamic-routes.md), including [catch all routes](/docs/routing/dynamic-routes.md#catch-all-routes), since Next.js 9.5.3 (for older versions check our [previous docs](https://nextjs.org/docs/tag/v9.5.2/api-reference/next/link#dynamic-routes)). However, it can become quite common and handy to use [interpolation](/docs/routing/introduction.md#linking-to-dynamic-paths) or an [URL Object](#with-url-object) to generate the link.
For example, the dynamic route `pages/blog/[slug].js` will match the following link:

View File

@@ -342,7 +342,7 @@ You can listen to different events happening inside the Next.js Router. Here's a
- `routeChangeComplete(url, { shallow })` - Fires when a route changed completely
- `routeChangeError(err, url, { shallow })` - Fires when there's an error when changing routes, or a route load is cancelled
- `err.cancelled` - Indicates if the navigation was cancelled
- `beforeHistoryChange(url, { shallow })` - Fires just before changing the browser's history
- `beforeHistoryChange(url, { shallow })` - Fires before changing the browser's history
- `hashChangeStart(url, { shallow })` - Fires when the hash will change but not the page
- `hashChangeComplete(url, { shallow })` - Fires when the hash has changed but not the page

View File

@@ -119,7 +119,7 @@ export default handler
## Extending the `req`/`res` objects with TypeScript
For better type-safety, it is not recommended to extend the `req` and `res` objects. Instead, use pure functions to work with them:
For better type-safety, it is not recommended to extend the `req` and `res` objects. Instead, use functions to work with them:
```ts
// utils/cookies.ts

View File

@@ -73,7 +73,7 @@ The `context` parameter is an object containing the following keys:
`getStaticProps` should return an object with:
- `props` - An **optional** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization)
- `revalidate` - An **optional** amount in seconds after which a page re-generation can occur (defaults to: `false` or no revalidating). More on [Incremental Static Regeneration](#incremental-static-regeneration)
- `revalidate` - An **optional** amount in seconds after which a page re-generation can occur. Defaults to `false`. When `revalidate` is `false` it means that there is no revalidation, so the page will be cached as built until your next build. More on [Incremental Static Regeneration](#incremental-static-regeneration)
- `notFound` - An **optional** boolean value to allow the page to return a 404 status and page. Below is an example of how it works:
```js
@@ -134,7 +134,7 @@ The `context` parameter is an object containing the following keys:
>
> Fetching from an external API is fine!
### Simple Example
### Example
Heres an example which uses `getStaticProps` to fetch a list of blog posts from a CMS (content management system). This example is also in the [Pages documentation](/docs/basic-features/pages.md).
@@ -299,7 +299,7 @@ When a request is made to a page that was pre-rendered at build time, it will in
- Any requests to the page after the initial request and before 10 seconds are also cached and instantaneous.
- After the 10-second window, the next request will still show the cached (stale) page
- Next.js triggers a regeneration of the page in the background.
- Once the page has been successfully generated, Next.js will invalidate the cache and show the updated product page. If the background regeneration fails, the old page remains unaltered.
- Once the page has been successfully generated, Next.js will invalidate the cache and show the updated product page. If the background regeneration fails, the old page will stay unaltered.
When a request is made to a path that hasnt been generated, Next.js will server-render the page on the first request. Future requests will serve the static file from the cache.
@@ -382,7 +382,7 @@ When a page with `getStaticProps` is pre-rendered at build time, in addition to
This JSON file will be used in client-side routing through `next/link` ([documentation](/docs/api-reference/next/link.md)) or `next/router` ([documentation](/docs/api-reference/next/router.md)). When you navigate to a page thats pre-rendered using `getStaticProps`, Next.js fetches this JSON file (pre-computed at build time) and uses it as the props for the page component. This means that client-side page transitions will **not** call `getStaticProps` as only the exported JSON is used.
When using Incremental Static Generation `getStaticProps` will be executed out of band to generate the JSON needed for client-side navigation. You may see this in the form of multiple requests being made for the same page, however, this is intended and has no impact on end-user performance
When using Incremental Static Generation `getStaticProps` will be executed out of band to generate the JSON needed for client-side navigation. You may see this in the form of multiple requests being made for the same page, however, this is intended and has no impact on end-user performance.
#### Only allowed in a page
@@ -513,7 +513,7 @@ If `fallback` is `true`, then the behavior of `getStaticProps` changes:
- The paths that have not been generated at build time will **not** result in a 404 page. Instead, Next.js will serve a “fallback” version of the page on the first request to such a path (see [“Fallback pages”](#fallback-pages) below for details).
- In the background, Next.js will statically generate the requested path HTML and JSON. This includes running `getStaticProps`.
- When thats done, the browser receives the JSON for the generated path. This will be used to automatically render the page with the required props. From the users perspective, the page will be swapped from the fallback page to the full page.
- At the same time, Next.js adds this path to the list of pre-rendered pages. Subsequent requests to the same path will serve the generated page, just like other pages pre-rendered at build time.
- At the same time, Next.js adds this path to the list of pre-rendered pages. Subsequent requests to the same path will serve the generated page, like other pages pre-rendered at build time.
> `fallback: true` is not supported when using [`next export`](/docs/advanced-features/static-html-export.md).
@@ -591,7 +591,7 @@ If `fallback` is `'blocking'`, new paths not returned by `getStaticPaths` will w
- The paths returned from `getStaticPaths` will be rendered to HTML at build time by `getStaticProps`.
- The paths that have not been generated at build time will **not** result in a 404 page. Instead, Next.js will SSR on the first request and return the generated HTML.
- When thats done, the browser receives the HTML for the generated path. From the users perspective, it will transition from "the browser is requesting the page" to "the full page is loaded". There is no flash of loading/fallback state.
- At the same time, Next.js adds this path to the list of pre-rendered pages. Subsequent requests to the same path will serve the generated page, just like other pages pre-rendered at build time.
- At the same time, Next.js adds this path to the list of pre-rendered pages. Subsequent requests to the same path will serve the generated page, like other pages pre-rendered at build time.
`fallback: 'blocking'` will not _update_ generated pages by default. To update generated pages, use [Incremental Static Regeneration](#incremental-static-regeneration) in conjunction with `fallback: 'blocking'`.
@@ -727,7 +727,7 @@ The `context` parameter is an object containing the following keys:
>
> Fetching from an external API is fine!
### Simple example
### Example
Heres an example which uses `getServerSideProps` to fetch data at request time and pre-renders it. This example is also in the [Pages documentation](/docs/basic-features/pages.md).
@@ -825,8 +825,10 @@ The team behind Next.js has created a React hook for data fetching called [**SWR
```jsx
import useSWR from 'swr'
const fetcher = (url) => fetch(url).then((res) => res.json())
function Profile() {
const { data, error } = useSWR('/api/user', fetch)
const { data, error } = useSWR('/api/user', fetcher)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>

View File

@@ -16,7 +16,7 @@ description: Learn to add and access environment variables in your Next.js appli
Next.js comes with built-in support for environment variables, which allows you to do the following:
- [Use `.env.local` to load environment variables](#loading-environment-variables)
- [Expose environment variables to the browser](#exposing-environment-variables-to-the-browser)
- [Expose environment variables to the browser by prefixing with `NEXT_PUBLIC_`](#exposing-environment-variables-to-the-browser)
## Loading Environment Variables
@@ -110,7 +110,7 @@ Next.js allows you to set defaults in `.env` (all environments), `.env.developme
`.env.local` always overrides the defaults set.
> **Note**: `.env`, `.env.development`, and `.env.production` files should be included in your repository as they define defaults. **`.env*.local` should be added to `.gitignore`**, as those files are intended to be ignored. `.env.local` is where secrets can be stored.
> **Note**: `.env`, `.env.development`, and `.env.production` files should be included in your repository as they define defaults. **`.env.*.local` should be added to `.gitignore`**, as those files are intended to be ignored. `.env.local` is where secrets can be stored.
## Environment Variables on Vercel

View File

@@ -18,39 +18,87 @@ Then run `npm run lint` or `yarn lint`:
yarn lint
```
If you don't already have ESLint configured in your application, you will be guided through the installation of the required packages.
If you don't already have ESLint configured in your application, you will be guided through the installation and configuration process.
```bash
yarn lint
# You'll see instructions like these:
# You'll see a prompt like this:
#
# Please install eslint and eslint-config-next by running:
# ? How would you like to configure ESLint?
#
# yarn add --dev eslint eslint-config-next
#
# ...
# Base configuration + Core Web Vitals rule-set (recommended)
# Base configuration
# None
```
If no ESLint configuration is present, Next.js will create an `.eslintrc` file in the root of your project and automatically configure it with the base configuration:
One of the following three options can be selected:
```js
{
"extends": "next"
}
```
- **Strict**: Includes Next.js' base ESLint configuration along with a stricter [Core Web Vitals rule-set](/docs/basic-features/eslint.md#core-web-vitals). This is the recommended configuration for developers setting up ESLint for the first time.
You can now run `next lint` every time you want to run ESLint to catch errors.
```json
{
"extends": "next/core-web-vitals"
}
```
> The default base configuration (`"extends": "next"`) can be updated at any time and will only be included if no ESLint configuration is present.
- **Base**: Includes Next.js' base ESLint configuration.
```json
{
"extends": "next"
}
```
- **Cancel**: Does not include any ESLint configuration. Only select this option if you plan on setting up your own custom ESLint configuration.
If either of the two configuration options are selected, Next.js will automatically install `eslint` and `eslint-config-next` as development dependencies in your application and create an `.eslintrc.json` file in the root of your project that includes your selected configuration.
You can now run `next lint` every time you want to run ESLint to catch errors. Once ESLint has been set up, it will also automatically run during every build (`next build`). Errors will fail the build, while warnings will not.
> If you do not want ESLint to run during `next build`, refer to the documentation for [Ignoring ESLint](/docs/api-reference/next.config.js/ignoring-eslint.md).
We recommend using an appropriate [integration](https://eslint.org/docs/user-guide/integrations#editors) to view warnings and errors directly in your code editor during development.
## Linting During Builds
## ESLint Config
Once ESLint has been set up, it will automatically run during every build (`next build`). Errors will fail the build, while warnings will not.
The default configuration (`eslint-config-next`) includes everything you need to have an optimal out-of-the-box linting experience in Next.js. If you do not have ESLint already configured in your application, we recommend using `next lint` to set up ESLint along with this configuration.
If you do not want ESLint to run as a build step, refer to the documentation for [Ignoring ESLint](/docs/api-reference/next.config.js/ignoring-eslint.md):
> If you would like to use `eslint-config-next` along with other ESLint configurations, refer to the [Additional Configurations](/docs/basic-features/eslint.md#additional-configurations) section to learn how to do so without causing any conflicts.
Recommended rule-sets from the following ESLint plugins are all used within `eslint-config-next`:
- [`eslint-plugin-react`](https://www.npmjs.com/package/eslint-plugin-react)
- [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks)
- [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next)
You can see the full details of the shareable configuration in the [`eslint-config-next`](https://www.npmjs.com/package/eslint-config-next) package.
This will take precedence over the configuration from `next.config.js`.
## ESLint Plugin
Next.js provides an ESLint plugin, [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next), already bundled within the base configuration that makes it possible to catch common issues and problems in a Next.js application. The full set of rules is as follows:
| | Rule | Description |
| :-: | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| ✔️ | [next/google-font-display](https://nextjs.org/docs/messages/google-font-display) | Enforce optional or swap font-display behavior with Google Fonts |
| ✔️ | [next/google-font-preconnect](https://nextjs.org/docs/messages/google-font-preconnect) | Enforce preconnect usage with Google Fonts |
| ✔️ | [next/link-passhref](https://nextjs.org/docs/messages/link-passhref) | Enforce passHref prop usage with custom Link components |
| ✔️ | [next/no-css-tags](https://nextjs.org/docs/messages/no-css-tags) | Prevent manual stylesheet tags |
| ✔️ | [next/no-document-import-in-page](https://nextjs.org/docs/messages/no-document-import-in-page) | Disallow importing next/document outside of pages/document.js |
| ✔️ | [next/no-head-import-in-document](https://nextjs.org/docs/messages/no-head-import-in-document) | Disallow importing next/head in pages/document.js |
| ✔️ | [next/no-html-link-for-pages](https://nextjs.org/docs/messages/no-html-link-for-pages) | Prohibit HTML anchor links to pages without a Link component |
| ✔️ | [next/no-img-element](https://nextjs.org/docs/messages/no-img-element) | Prohibit usage of HTML &lt;img&gt; element |
| ✔️ | [next/no-page-custom-font](https://nextjs.org/docs/messages/no-page-custom-font) | Prevent page-only custom fonts |
| ✔️ | [next/no-sync-scripts](https://nextjs.org/docs/messages/no-sync-scripts) | Forbid synchronous scripts |
| ✔️ | [next/no-title-in-document-head](https://nextjs.org/docs/messages/no-title-in-document-head) | Disallow using &lt;title&gt; with Head from next/document |
| ✔️ | [next/no-unwanted-polyfillio](https://nextjs.org/docs/messages/no-unwanted-polyfillio) | Prevent duplicate polyfills from Polyfill.io |
| ✔️ | next/no-typos | Ensure no typos were made declaring [Next.js's data fetching function](https://nextjs.org/docs/basic-features/data-fetching) |
- ✔: Enabled in the recommended configuration
If you already have ESLint configured in your application, we recommend extending from this plugin directly instead of including `eslint-config-next` unless a few conditions are met. Refer to the [Recommended Plugin Ruleset](/docs/basic-features/eslint.md#recommended-plugin-ruleset) to learn more.
## Linting Custom Directories
@@ -67,93 +115,42 @@ module.exports = {
Similarly, the `--dir` flag can be used for `next lint`:
```bash
yarn lint --dir pages --dir utils
next lint --dir pages --dir utils
```
## ESLint Plugin
Next.js provides an ESLint plugin, [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next), making it easier to catch common issues and problems in a Next.js application. The full set of rules is as follows:
| | Rule | Description |
| :-: | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| ✔️ | [next/google-font-display](https://nextjs.org/docs/messages/google-font-display) | Enforce optional or swap font-display behavior with Google Fonts |
| ✔️ | [next/google-font-preconnect](https://nextjs.org/docs/messages/google-font-preconnect) | Enforce preconnect usage with Google Fonts |
| ✔️ | [next/link-passhref](https://nextjs.org/docs/messages/link-passhref) | Enforce passHref prop usage with custom Link components |
| ✔️ | [next/no-css-tags](https://nextjs.org/docs/messages/no-css-tags) | Prevent manual stylesheet tags |
| ✔️ | [next/no-document-import-in-page](https://nextjs.org/docs/messages/no-document-import-in-page) | Disallow importing next/document outside of pages/document.js |
| ✔️ | [next/no-head-import-in-document](https://nextjs.org/docs/messages/no-head-import-in-document) | Disallow importing next/head in pages/document.js |
| ✔️ | [next/no-html-link-for-pages](https://nextjs.org/docs/messages/no-html-link-for-pages) | Prohibit HTML anchor links to pages without a Link component |
| ✔️ | [next/no-img-element](https://nextjs.org/docs/messages/no-img-element) | Prohibit usage of HTML &lt;img&gt; element |
| ✔️ | [next/no-page-custom-font](https://nextjs.org/docs/messages/no-page-custom-font) | Prevent page-only custom fonts |
| ✔️ | [next/no-sync-scripts](https://nextjs.org/docs/messages/no-sync-scripts) | Forbid synchronous scripts |
| ✔️ | [next/no-title-in-document-head](https://nextjs.org/docs/messages/no-title-in-document-head) | Disallow using &lt;title&gt; with Head from next/document |
| ✔️ | [next/no-unwanted-polyfillio](https://nextjs.org/docs/messages/no-unwanted-polyfillio) | Prevent duplicate polyfills from Polyfill.io |
- ✔: Enabled in the recommended configuration
## Base Configuration
The Next.js base ESLint configuration is automatically generated when `next lint` is run for the first time:
```js
{
"extends": "next"
}
```
This configuration extends recommended rule sets from various ESLint plugins:
- [`eslint-plugin-react`](https://www.npmjs.com/package/eslint-plugin-react)
- [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks)
- [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next)
You can see the full details of the shareable configuration in the [`eslint-config-next`](https://www.npmjs.com/package/eslint-config-next) package.
## Disabling Rules
If you would like to modify or disable any rules provided by the supported plugins (`react`, `react-hooks`, `next`), you can directly change them using the `rules` property in your `.eslintrc`:
```js
```json
{
"extends": "next",
"rules": {
"react/no-unescaped-entities": "off",
"@next/next/no-page-custom-font": "off",
"@next/next/no-page-custom-font": "off"
}
}
```
> **Note**: If you need to also include a separate, custom ESLint configuration, it is highly recommended that `eslint-config-next` is extended last after other configurations. For example:
>
> ```
> {
> "extends": ["eslint:recommended", "next"]
> }
> ```
>
> The `next` configuration already handles setting default values for the `parser`, `plugins` and `settings` properties.
> There is no need to manually re-declare any of these properties unless you need a different configuration for your use case.
> If you include any other shareable configurations, you will need to make sure that these properties are not overwritten or modified.
### Core Web Vitals
A stricter `next/core-web-vitals` rule set can also be added in `.eslintrc`:
The `next/core-web-vitals` rule set is enabled when `next lint` is run for the first time and the **strict** option is selected.
```
```json
{
"extends": ["next", "next/core-web-vitals"]
"extends": "next/core-web-vitals"
}
```
`next/core-web-vitals` updates `eslint-plugin-next` to error on a number of rules that are warnings by default if they affect [Core Web Vitals](https://web.dev/vitals/).
> Both `next` and `next/core-web-vitals` entry points are automatically included for new applications built with [Create Next App](/docs/api-reference/create-next-app.md).
> The `next/core-web-vitals` entry point is automatically included for new applications built with [Create Next App](/docs/api-reference/create-next-app.md).
## Usage with Prettier
ESLint also contains code formatting rules, which can conflict with your existing [Prettier](https://prettier.io/) setup. We recommend including [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) in your ESLint config to make ESLint and Prettier work together.
```js
```json
{
"extends": ["next", "prettier"]
}
@@ -161,7 +158,19 @@ ESLint also contains code formatting rules, which can conflict with your existin
## Migrating Existing Config
If you already have ESLint configured in your application, we recommend extending directly from the Next.js ESLint plugin instead of the shareable configuration.
### Recommended Plugin Ruleset
If you already have ESLint configured in your application and any of the following conditions are true:
- You have one or more of the following plugins already installed (either separately or through a different config such as `airbnb` or `react-app`):
- `react`
- `react-hooks`
- `jsx-a11y`
- `import`
- You've defined specific `parserOptions` that are different from how Babel is configured within Next.js (this is not recommended unless you have [customized your Babel configuration](/docs/advanced-features/customizing-babel-config.md))
- You have `eslint-plugin-import` installed with Node.js and/or TypeScript [resolvers](https://github.com/benmosher/eslint-plugin-import#resolvers) defined to handle imports
Then we recommend either removing these settings if you prefer how these properties have been configured within [`eslint-config-next`](https://github.com/vercel/next.js/blob/canary/packages/eslint-config-next/index.js) or extending directly from the Next.js ESLint plugin instead:
```js
module.exports = {
@@ -172,4 +181,24 @@ module.exports = {
}
```
This eliminates any risk of collisions that can occur due to importing the same plugin or parser across multiple configurations.
The plugin can be installed normally in your project without needing to run `next lint`:
```bash
npm install --save-dev @next/eslint-plugin-next
# or
yarn add --dev @next/eslint-plugin-next
```
This eliminates the risk of collisions or errors that can occur due to importing the same plugin or parser across multiple configurations.
### Additional Configurations
If you already use a separate ESLint configuration and want to include `eslint-config-next`, ensure that it is extended last after other configurations. For example:
```
{
"extends": ["eslint:recommended", "next"]
}
```
The `next` configuration already handles setting default values for the `parser`, `plugins` and `settings` properties. There is no need to manually re-declare any of these properties unless you need a different configuration for your use case. If you include any other shareable configurations, **you will need to make sure that these properties are not overwritten or modified**. Otherwise, we recommend removing any configurations that share behavior with the `next` configuration or extending directly from the Next.js ESLint plugin as mentioned above.

View File

@@ -23,7 +23,7 @@ Instead of optimizing images at build time, Next.js optimizes images on-demand,
Images are lazy loaded by default. That means your page speed isn't penalized for images outside the viewport. Images load as they are scrolled into viewport.
Images are always rendered in such a way as to avoid [Cumulative Layout Shift](https://web.dev/cls/), a [Core Web Vital](https://web.dev/vitals/) that Google is going to [use in search ranking](https://webmasters.googleblog.com/2020/05/evaluating-page-experience.html).
Images are always rendered in such a way as to avoid [Cumulative Layout Shift](https://web.dev/cls/), a [Core Web Vital](https://web.dev/vitals/) that Google [uses in search ranking](https://developers.google.com/search/blog/2020/05/evaluating-page-experience).
## Image Component
@@ -121,12 +121,15 @@ The following Image Optimization cloud providers are included:
- [Imgix](https://www.imgix.com): `loader: 'imgix'`
- [Cloudinary](https://cloudinary.com): `loader: 'cloudinary'`
- [Akamai](https://www.akamai.com): `loader: 'akamai'`
- Custom: `loader: 'custom'` use a custom cloud provider by implementing the [`loader`](/docs/api-reference/next/image.md#loader) prop on the `next/image` component
- Default: Works automatically with `next dev`, `next start`, or a custom server
If you need a different provider, you can use the [`loader`](/docs/api-reference/next/image.md#loader) prop with `next/image`.
> The `next/image` component's default loader is not supported when using [`next export`](/docs/advanced-features/static-html-export.md). However, other loader options will work.
> The `next/image` component's default loader uses the ['squoosh'](https://www.npmjs.com/package/@squoosh/lib) library for image resizing and optimization. This library is quick to install and suitable for a dev server environment. For a production environment, it is strongly recommended that you install the optional [`sharp`](https://www.npmjs.com/package/sharp) library by running `yarn add sharp` in your project directory. If sharp is already installed but can't be resolved you can manually pass the path to it via the `NEXT_SHARP_PATH` environment variable e.g. `NEXT_SHARP_PATH=/tmp/node_modules/sharp`
## Caching
The following describes the caching algorithm for the default [loader](#loader). For all other loaders, please refer to your cloud provider's documentation.
@@ -135,9 +138,11 @@ Images are optimized dynamically upon request and stored in the `<distDir>/cache
The expiration (or rather Max Age) is defined by the upstream server's `Cache-Control` header.
If `s-maxage` is found in `Cache-Control`, it is used. If no `s-maxage` is found, then `max-age` is used. If no `max-age` is found, then 60 seconds is used.
If `s-maxage` is found in `Cache-Control`, it is used. If no `s-maxage` is found, then `max-age` is used. If no `max-age` is found, then [`minimumCacheTTL`](#minimum-cache-ttl) is used.
You can configure [`deviceSizes`](#device-sizes) and [`imageSizes`](#device-sizes) to reduce the total number of possible generated images.
You can configure [`minimumCacheTTL`](#minimum-cache-ttl) to increase the cache duration when the upstream image does not include `max-age`.
You can also configure [`deviceSizes`](#device-sizes) and [`imageSizes`](#device-sizes) to reduce the total number of possible generated images.
## Advanced
@@ -171,6 +176,20 @@ module.exports = {
}
```
### Minimum Cache TTL
You can configure the time to live (TTL) in seconds for cached optimized images. In many cases, its better to use a [Static Image Import](#image-Imports) which will handle hashing file contents and caching the file forever.
```js
module.exports = {
images: {
minimumCacheTTL: 60,
},
}
```
If you need to add a `Cache-Control` header for the browser (not recommended), you can configure [`headers`](/docs/api-reference/next.config.js/headers) on the upstream image e.g. `/some-asset.jpg` not `/_next/image` itself.
### Disable Static Imports
The default behavior allows you to import static files such as `import icon from './icon.png` and then pass that to the `src` property.

View File

@@ -0,0 +1,185 @@
---
description: Learn how to share components and state between Next.js pages with Layouts.
---
# Layouts
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/layout-component">layout-component</a></li>
</ul>
</details>
The React model allows us to deconstruct a [page](/docs/basic-features/pages.md) into a series of components. Many of these components are often reused between pages. For example, you might have the same navigation bar and footer on every page.
```jsx
// components/layout.js
import Navbar from './navbar'
import Footer from './footer'
export default function Layout({ children }) {
return (
<>
<Navbar />
<main>{children}</main>
<Footer />
</>
)
}
```
## Examples
### Single Shared Layout with Custom App
If you only have one layout for your entire application, you can create a [Custom App](/docs/advanced-features/custom-app.md) and wrap your application with the layout. Since the `<Layout />` component is re-used when changing pages, its component state will be preserved (e.g. input values).
```jsx
// pages/_app.js
import Layout from '../components/layout'
export default function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
```
### Per-Page Layouts
If you need multiple layouts, you can add a property `getLayout` to your page, allowing you to return a React component for the layout. This allows you to define the layout on a _per-page basis_. Since we're returning a function, we can have complex nested layouts if desired.
```jsx
// pages/index.js
import Layout from '../components/layout'
import NestedLayout from '../components/nested-layout'
export default function Page() {
return {
/** Your content */
}
}
Page.getLayout = function getLayout(page) {
return (
<Layout>
<NestedLayout>{page}</NestedLayout>
</Layout>
)
}
```
```jsx
// pages/_app.js
export default function MyApp({ Component, pageProps }) {
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout || ((page) => page)
return getLayout(<Component {...pageProps} />)
}
```
When navigating between pages, we want to *persist* page state (input values, scroll position, etc) for a Single-Page Application (SPA) experience.
This layout pattern enables state persistence because the React component tree is maintained between page transitions. With the component tree, React can understand which elements have changed to preserve state.
> **Note**: This process is called [reconciliation](https://reactjs.org/docs/reconciliation.html), which is how React understands which elements have changed.
### With TypeScript
When using TypeScript, you must first create a new type for your pages which includes a `getLayout` function. Then, you must create a new type for your `AppProps` which overrides the `Component` property to use the previously created type.
```tsx
// pages/index.tsx
import type { ReactElement } from 'react'
import Layout from '../components/layout'
import NestedLayout from '../components/nested-layout'
export default function Page() {
return {
/** Your content */
}
}
Page.getLayout = function getLayout(page: ReactElement) {
return (
<Layout>
<NestedLayout>{page}</NestedLayout>
</Layout>
)
}
```
```tsx
// pages/_app.tsx
import type { ReactElement, ReactNode } from 'react'
import type { NextPage } from 'next'
import type { AppProps } from 'next/app'
type NextPageWithLayout = NextPage & {
getLayout?: (page: ReactElement) => ReactNode
}
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout
}
export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout ?? ((page) => page)
return getLayout(<Component {...pageProps} />)
}
```
### Data Fetching
Inside your layout, you can fetch data on the client-side using `useEffect` or a library like [SWR](https://swr.vercel.app/). Because this file is not a [Page](/docs/basic-features/pages.md), you cannot use `getStaticProps` or `getServerSideProps` currently.
```jsx
// components/layout.js
import useSWR from 'swr'
import Navbar from './navbar'
import Footer from './footer'
export default function Layout({ children }) {
const { data, error } = useSWR('/api/navigation', fetcher)
if (error) return <div>Failed to load</div>
if (!data) return <div>Loading...</div>
return (
<>
<Navbar links={data.links} />
<main>{children}</main>
<Footer />
</>
)
}
```
For more information on what to do next, we recommend the following sections:
<div class="card">
<a href="/docs/basic-features/pages.md">
<b>Pages:</b>
<small>Learn more about what pages are in Next.js.</small>
</a>
</div>
<div class="card">
<a href="/docs/advanced-features/custom-app.md">
<b>Custom App:</b>
<small>Learn more about how Next.js initialize pages.</small>
</a>
</div>

View File

@@ -56,7 +56,7 @@ You can also use **Client-side Rendering** along with Static Generation or Serve
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-prismic">Prismic Example</a> (<a href="https://next-blog-prismic.vercel.app/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-contentful">Contentful Example</a> (<a href="https://next-blog-contentful.vercel.app/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-strapi">Strapi Example</a> (<a href="https://next-blog-strapi.vercel.app/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-prepr">Prepr Example</a> (<a href="https://next-blog-prepr.vercel.app/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-prepr">Prepr Example</a> (<a href="https://next-blog-prepr.vercel.app/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-agilitycms">Agility CMS Example</a> (<a href="https://next-blog-agilitycms.vercel.app/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-cosmic">Cosmic Example</a> (<a href="https://next-blog-cosmic.vercel.app/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-buttercms">ButterCMS Example</a> (<a href="https://next-blog-buttercms.vercel.app/">Demo</a>)</li>
@@ -87,7 +87,7 @@ Note that this page does not need to fetch any external data to be pre-rendered.
### Static Generation with data
Some pages require fetching external data for pre-rendering. There are two scenarios, and one or both might apply. In each case, you can use a special function Next.js provides:
Some pages require fetching external data for pre-rendering. There are two scenarios, and one or both might apply. In each case, you can use these functions that Next.js provides:
1. Your page **content** depends on external data: Use `getStaticProps`.
2. Your page **paths** depend on external data: Use `getStaticPaths` (usually in addition to `getStaticProps`).

View File

@@ -23,7 +23,10 @@ With `next/script`, you can define the `strategy` property and Next.js will o
- `afterInteractive` (**default**): For scripts that can fetch and execute **after** the page is interactive, such as tag managers and analytics. These scripts are injected on the client-side and will run after hydration.
- `lazyOnload` For scripts that can wait to load during idle time, such as chat support and social media widgets.
> **Note:** These loading strategies work the same for inline scripts wrapped with `<Script>`. See the inline scripts example below.
> **Note:**
>
> - `<Script>` supports inline scripts with `afterInteractive` and `lazyOnload` strategy.
> - Inline scripts wrapped with `<Script>` _require an `id` attribute to be defined_ to track and optimize the script.
## Usage
@@ -35,7 +38,7 @@ Previously, you needed to define `script` tags inside the `Head` of your Next.js
// pages/index.js
import Head from 'next/head'
function Home() {
export default function Home() {
return (
<>
<Head>
@@ -46,7 +49,11 @@ function Home() {
}
```
With `next/script`, you no longer need to wrap scripts in `next/head`. Further, `next/script` should **not** be used in `pages/_document.js` as `next/script` has client-side functionality to ensure loading order. For example:
Now, you use `next/script` in the body of your Next.js page. It has client-side functionality that decides when and how to load the remote script based on the `strategy`.
> **Note:**
>
> - `next/script` **must not** be placed in either a `next/head` component or in `pages/_document.js`.
```js
// After
@@ -54,7 +61,7 @@ With `next/script`, you no longer need to wrap scripts in `next/head`. Further,
// pages/index.js
import Script from 'next/script'
function Home() {
export default function Home() {
return (
<>
<Script src="https://www.google-analytics.com/analytics.js" />
@@ -69,33 +76,54 @@ function Home() {
```js
import Script from 'next/script'
;<Script
src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver"
strategy="beforeInteractive"
/>
export default function Home() {
return (
<>
<Script
src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver"
strategy="beforeInteractive"
/>
</>
)
}
```
### Lazy-Loading
```js
import Script from 'next/script'
;<Script
src="https://connect.facebook.net/en_US/sdk.js"
strategy="lazyOnload"
/>
export default function Home() {
return (
<>
<Script
src="https://connect.facebook.net/en_US/sdk.js"
strategy="lazyOnload"
/>
</>
)
}
```
### Executing Code After Loading (`onLoad`)
```js
import Script from 'next/script'
;<Script
id="stripe-js"
src="https://js.stripe.com/v3/"
onLoad={() => {
this.setState({ stripe: window.Stripe('pk_test_12345') })
}}
/>
export default function Home() {
return (
<>
<Script
id="stripe-js"
src="https://js.stripe.com/v3/"
onLoad={() => {
this.setState({ stripe: window.Stripe('pk_test_12345') })
}}
/>
</>
)
}
```
### Inline Scripts
@@ -120,10 +148,17 @@ import Script from 'next/script'
```js
import Script from 'next/script'
;<Script
src="https://www.google-analytics.com/analytics.js"
id="analytics"
nonce="XUENAJFW"
data-test="analytics"
/>
export default function Home() {
return (
<>
<Script
src="https://www.google-analytics.com/analytics.js"
id="analytics"
nonce="XUENAJFW"
data-test="analytics"
/>
</>
)
}
```

View File

@@ -53,10 +53,12 @@ npm run dev
You're now ready to start converting files from `.js` to `.tsx` and leveraging the benefits of TypeScript!.
> A file named `next-env.d.ts` will be created in the root of your project. This file ensures Next.js types are picked up by the TypeScript compiler. **You cannot remove it**, however, you can edit it (but you don't need to).
> A file named `next-env.d.ts` will be created in the root of your project. This file ensures Next.js types are picked up by the TypeScript compiler. **You cannot remove it or edit it** as it can change at any time.
> TypeScript `strict` mode is turned off by default. When you feel comfortable with TypeScript, it's recommended to turn it on in your `tsconfig.json`.
> Instead of editing `next-env.d.ts`, you can include additional types by adding a new file e.g. `additional.d.ts` and then referencing it in the [`include`](https://www.typescriptlang.org/tsconfig#include) array in your `tsconfig.json`.
By default, Next.js will do type checking as part of `next build`. We recommend using code editor type checking during development.
If you want to silence the error reports, refer to the documentation for [Ignoring TypeScript errors](/docs/api-reference/next.config.js/ignoring-typescript-errors.md).
@@ -150,7 +152,7 @@ The `next.config.js` file must be a JavaScript file as it does not get parsed by
// @ts-check
/**
* @type {import('next/dist/next-server/server/config').NextConfig}
* @type {import('next').NextConfig}
**/
const nextConfig = {
/* config options here */

View File

@@ -16,10 +16,10 @@ Then, follow these steps:
1. [Sign up to Vercel](https://vercel.com/signup) (no credit card is required).
2. After signing up, youll arrive on the [“Import Project”](https://vercel.com/new) page. Under “From Git Repository”, choose the Git provider you use and set up an integration. (Instructions: [GitHub](https://vercel.com/docs/git/vercel-for-github) / [GitLab](https://vercel.com/docs/git/vercel-for-gitlab) / [BitBucket](https://vercel.com/docs/git/vercel-for-bitbucket)).
3. Once thats set up, click “Import Project From …” and import your Next.js app. It auto-detects that your app is using Next.js and sets up the build configuration for you. No need to change anything — everything should work just fine!
3. Once thats set up, click “Import Project From …” and import your Next.js app. It auto-detects that your app is using Next.js and sets up the build configuration for you. No need to change anything — everything should work fine!
4. After importing, itll deploy your Next.js app and provide you with a deployment URL. Click “Visit” to see your app in production.
Congratulations! Youve just deployed your Next.js app! If you have questions, take a look at the [Vercel documentation](https://vercel.com/docs).
Congratulations! Youve deployed your Next.js app! If you have questions, take a look at the [Vercel documentation](https://vercel.com/docs).
> If youre using a [custom server](/docs/advanced-features/custom-server.md), we strongly recommend migrating away from it (for example, by using [dynamic routing](/docs/routing/dynamic-routes.md)). If you cannot migrate, consider [other hosting options](#other-hosting-options).
@@ -56,7 +56,7 @@ When you deploy your Next.js application, you want to see the latest version wit
Next.js will automatically load the latest version of your application in the background when routing. For client-side navigation, `next/link` will temporarily function as a normal `<a>` tag.
If a new page (with an old version) has already been prefetched by `next/link`, Next.js will use the old version. Then, after either a full page refresh or multiple client-side transitions, Next.js will show the latest version.
**Note:** If a new page (with an old version) has already been prefetched by `next/link`, Next.js will use the old version. Then, after either a full page refresh or multiple client-side page transitions, Next.js will show the latest version.
## Other hosting options

View File

@@ -14,7 +14,7 @@ If you have questions about anything related to Next.js, you're always welcome t
#### System Requirements
- [Node.js 10.13](https://nodejs.org/) or later
- [Node.js 12.0](https://nodejs.org/) or later
- MacOS, Windows (including WSL), and Linux are supported
## Setup

View File

@@ -0,0 +1,129 @@
---
description: Before taking your Next.js application to production, here are some recommendations to ensure the best user experience.
---
# Going to Production
Before taking your Next.js application to production, here are some recommendations to ensure the best user experience.
## In General
- Use [caching](#caching) wherever possible.
- Ensure your database and backend are deployed in the same region.
- Aim to ship the least amount of JavaScript possible.
- Defer loading heavy JavaScript bundles until needed.
- Ensure [logging](#logging) is set up.
- Ensure [error handling](#error-handling) is set up.
- Configure the [404](/docs/advanced-features/custom-error-page.md#404-page) (Not Found) and [500](/docs/advanced-features/custom-error-page.md#500-page) (Error) pages.
- Ensure you are [measuring performance](/docs/advanced-features/measuring-performance.md).
- Run [Lighthouse](https://developers.google.com/web/tools/lighthouse) to check for performance, best practices, accessibility, and SEO. For best results, use a production build of Next.js and use incognito in your browser so results aren't affected by extensions.
- Review [Supported Browsers and Features](/docs/basic-features/supported-browsers-features.md).
- Improve performance using:
- [`next/image` and Automatic Image Optimization](/docs/basic-features/image-optimization.md)
- [Automatic Font Optimization](/docs/basic-features/font-optimization.md)
- [Script Optimization](/docs/basic-features/script.md)
## Caching
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/ssr-caching">ssr-caching</a></li>
</ul>
</details>
Caching improves response times and reduces the number of requests to external services. Next.js automatically adds caching headers to immutable assets served from `/_next/static` including JavaScript, CSS, static images, and other media.
```
Cache-Control: public, max-age=31536000, immutable
```
`Cache-Control` headers set in `next.config.js` will be overwritten in production to ensure that static assets can be cached effectively. If you need to revalidate the cache of a page that has been [statically generated](/docs/basic-features/pages.md#static-generation-recommended), you can do so by setting `revalidate` in the page's [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) function. If you're using `next/image`, there are also [specific caching rules](/docs/basic-features/image-optimization.md#caching) for the default Image Optimization loader.
**Note:** When running your application locally with `next dev`, your headers are overwritten to prevent caching locally.
```
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
```
You can also use caching headers inside `getServerSideProps` and API Routes for dynamic responses. For example, using [`stale-while-revalidate`](https://web.dev/stale-while-revalidate/).
```jsx
// This value is considered fresh for ten seconds (s-maxage=10).
// If a request is repeated within the next 10 seconds, the previously
// cached value will still be fresh. If the request is repeated before 59 seconds,
// the cached value will be stale but still render (stale-while-revalidate=59).
//
// In the background, a revalidation request will be made to populate the cache
// with a fresh value. If you refresh the page, you will see the new value.
export async function getServerSideProps({ req, res }) {
res.setHeader(
'Cache-Control',
'public, s-maxage=10, stale-while-revalidate=59'
)
return {
props: {},
}
}
```
> **Note:** Your deployment provider must support edge caching for dynamic responses. If you are self-hosting, you will need to add this logic to the edge yourself using a key/value store. If you are using Vercel, [edge caching works without configuration](https://vercel.com/docs/edge-network/caching).
## Reducing JavaScript Size
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-dynamic-import">with-dynamic-import</a></li>
</ul>
</details>
To reduce the amount of JavaScript sent to the browser, you can use the following tools to understand what is included inside each JavaScript bundle:
- [Import Cost](https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost) Display the size of the imported package inside VSCode.
- [Package Phobia](https://packagephobia.com/) Find the cost of adding a new dev dependency to your project.
- [Bundle Phobia](https://bundlephobia.com/) - Analyze how much a dependency can increase bundle sizes.
- [Webpack Bundle Analyzer](https://github.com/vercel/next.js/tree/canary/packages/next-bundle-analyzer) Visualize size of webpack output files with an interactive, zoomable treemap.
Each file inside your `pages/` directory will automatically be code split into its own JavaScript bundle during `next build`. You can also use [Dynamic Imports](/docs/advanced-features/dynamic-import.md) to lazy-load components and libraries. For example, you might want to defer loading your modal code until a user clicks the open button.
## Logging
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/Logflare/next-pino-logflare-logging-example">with-logging</a></li>
</ul>
</details>
Since Next.js runs on both the client and server, there are multiple forms of logging supported:
- `console.log` in the browser
- `stdout` on the server
If you want a structured logging package, we recommend [Pino](https://www.npmjs.com/package/pino). If you're using Vercel, there are [pre-built logging integrations](https://vercel.com/integrations#logging) compatible with Next.js.
## Error Handling
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-sentry">with-sentry</a></li>
</ul>
</details>
When an unhandled exception occurs, you can control the experience for your users with the [500 page](/docs/advanced-features/custom-error-page.md#500-page). We recommend customizing this to your brand instead of the default Next.js theme.
You can also log and track exceptions with a tool like Sentry. [This example](https://github.com/vercel/next.js/tree/canary/examples/with-sentry) shows how to catch & report errors on both the client and server-side, using the Sentry SDK for Next.js. There's also a [Sentry integration for Vercel](https://vercel.com/integrations/sentry).
## Related
For more information on what to do next, we recommend the following sections:
<div class="card">
<a href="/docs/deployment.md">
<b>Deployment:</b>
<small>Take your Next.js application to production.</small>
</a>
</div>

View File

@@ -21,6 +21,10 @@
"title": "Built-in CSS Support",
"path": "/docs/basic-features/built-in-css-support.md"
},
{
"title": "Layouts",
"path": "/docs/basic-features/layouts.md"
},
{
"title": "Image Optimization",
"path": "/docs/basic-features/image-optimization.md"
@@ -29,6 +33,10 @@
"title": "Font Optimization",
"path": "/docs/basic-features/font-optimization.md"
},
{
"title": "Script Optimization",
"path": "/docs/basic-features/script.md"
},
{
"title": "Static File Serving",
"path": "/docs/basic-features/static-file-serving.md"
@@ -52,10 +60,6 @@
{
"title": "Supported Browsers and Features",
"path": "/docs/basic-features/supported-browsers-features.md"
},
{
"title": "Script",
"path": "/docs/basic-features/script.md"
}
]
},
@@ -101,6 +105,10 @@
}
]
},
{
"title": "Going to Production",
"path": "/docs/going-to-production.md"
},
{
"title": "Deployment",
"path": "/docs/deployment.md"
@@ -340,6 +348,10 @@
"title": "Disabling ETag Generation",
"path": "/docs/api-reference/next.config.js/disabling-etag-generation.md"
},
{
"title": "Disabling HTTP Keep-Alive",
"path": "/docs/api-reference/next.config.js/disabling-http-keep-alive.md"
},
{
"title": "Setting a custom build directory",
"path": "/docs/api-reference/next.config.js/setting-a-custom-build-directory.md"

View File

@@ -199,7 +199,7 @@ export default function SEO({ description, title, siteTitle }) {
## Single-Page App (SPA)
If you want to move your existing Create React App to Next.js and keep a Single-Page App, you can move your old application's entry point to an [Optional Catch-All Route](/docs/routing/dynamic-routes.md#optional-catch-all-routes) named `pages/[[app]].js`.
If you want to move your existing Create React App to Next.js and keep a Single-Page App, you can move your old application's entry point to an [Optional Catch-All Route](/docs/routing/dynamic-routes.md#optional-catch-all-routes) named `pages/[[...app]].js`.
```jsx
// pages/[[...app]].js

View File

@@ -80,7 +80,7 @@ To learn more about rewrites, take a look at our [documentation](/docs/api-refer
### Micro-Frontends with Monorepos and Subdomains
Next.js and [Vercel](https://vercel.com) make it easy to adopt [micro-frontends](https://martinfowler.com/articles/micro-frontends.html) and deploy as a [Monorepo](https://vercel.com/blog/monorepos). This allows you to use [subdomains](https://en.wikipedia.org/wiki/Subdomain) to adopt new applications incrementally. Some benefits of micro-frontends:
Next.js and [Vercel](https://vercel.com) make it straightforward to adopt [micro-frontends](https://martinfowler.com/articles/micro-frontends.html) and deploy as a [Monorepo](https://vercel.com/blog/monorepos). This allows you to use [subdomains](https://en.wikipedia.org/wiki/Subdomain) to adopt new applications incrementally. Some benefits of micro-frontends:
- Smaller, more cohesive and maintainable codebases.
- More scalable organizations with decoupled, autonomous teams.

View File

@@ -145,7 +145,7 @@ For more information on what to do next, we recommend the following sections:
<div class="card">
<a href="/docs/api-reference/next/link.md">
<b>Pages:</b>
<b>next/link:</b>
<small>Enable client-side transitions with next/link.</small>
</a>
</div>

View File

@@ -56,6 +56,18 @@ Example:
PORT=4000 next start
```
### `next.config.js` customization to import images
Next.js 11 supports static image imports with `next/image`. This new feature relies on being able to process image imports. If you previously added the `next-images` or `next-optimized-images` packages you can either move to the new built-in support using `next/image` or disable the feature:
```js
module.exports = {
images: {
disableStaticImages: true,
},
}
```
### Remove `super.componentDidCatch()` from `pages/_app.js`
The `next/app` component's `componentDidCatch` has been deprecated since Next.js 9 as it's no longer needed and has since been a no-op, in Next.js 11 it has been removed.
@@ -222,7 +234,7 @@ import { AppContext, AppInitialProps } from 'next/app'
import { DocumentContext, DocumentInitialProps } from 'next/document'
```
#### The `config` key is now a special export on a page
#### The `config` key is now an export on a page
You may no longer export a custom variable named `config` from a page (i.e. `export { config }` / `export const config ...`).
This exported variable is now used to specify page-level Next.js configuration like Opt-in AMP and API Route features.

View File

@@ -0,0 +1,13 @@
# API Routes Body Size Limited to 4MB
#### Why This Error Occurred
API Routes are meant to respond quickly and are not intended to support responding with large amounts of data. The maximum size of responses is 4 MB.
#### Possible Ways to Fix It
Limit your API Route responses to less than 4 MB. If you need to support sending large files to the client, you should consider using a dedicated media host for those assets. See link below for suggestions.
### Useful Links
[Tips to avoid the 5 MB limit](https://vercel.com/support/articles/how-to-bypass-vercel-5mb-body-size-limit-serverless-functions)

View File

@@ -4,7 +4,7 @@
An `exportPathMap` path was matched to an API route. Statically exporting a Next.js application via `next export` disables API routes.
This command is meant for static-only hosts, and is not necessary to make your application static. Pages in your application without server-side data dependencies will be automatically statically exported by `next build`, including pages powered by `getStaticProps`
This command is meant for a static-only setup, and is not necessary to make your application static. Pages in your application without server-side data dependencies will be automatically statically exported by `next build`, including pages powered by `getStaticProps`
#### Possible Ways to Fix It

View File

@@ -4,7 +4,7 @@
Either you set `distDir` to `public` in your `next.config.js` or during `next export` you tried to export to the `public` directory.
This is not allowed due to `public` being a special folder in Next.js used to serve static assets.
This is not allowed because `public` is used by Next.js to serve static assets.
#### Possible Ways to Fix It

View File

@@ -4,7 +4,7 @@
Either you set `distDir` to `static` in your `next.config.js` or during `next export` you tried to export to the `static` directory.
This is not allowed due to `static` being a special folder in Next.js used to serve static assets.
This is not allowed because `static` is used by Next.js to serve static assets.
#### Possible Ways to Fix It

View File

@@ -8,12 +8,27 @@ Global CSS cannot be used in files other than your [Custom `<App>`](https://next
#### Possible Ways to Fix It
Relocate all Global CSS imports to your [`pages/_app.js` file](https://nextjs.org/docs/advanced-features/custom-app).
To avoid conflicts, relocate all first-party Global CSS imports to your [`pages/_app.js` file](https://nextjs.org/docs/advanced-features/custom-app).
Or, [update your component to use local CSS (Component-Level CSS) via CSS Modules](https://nextjs.org/docs/basic-features/built-in-css-support#adding-component-level-css). This is the preferred approach.
#### Example
Consider the stylesheet named [`styles.css`](https://nextjs.org/docs/basic-features/built-in-css-support#adding-a-global-stylesheet)
```jsx
//styles.css
body {
font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', 'Helvetica',
'Arial', sans-serif;
padding: 20px 20px 60px;
max-width: 680px;
margin: 0 auto;
}
```
Create a [`pages/_app.js` file](https://nextjs.org/docs/advanced-features/custom-app) if not already present. Then [`import`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) the [`styles.css` file](https://nextjs.org/docs/basic-features/built-in-css-support#adding-a-global-stylesheet).
```jsx
// pages/_app.js
import '../styles.css'

View File

@@ -8,7 +8,7 @@ The `future.webpack5` option has been moved to `webpack5` in `next.config.js`.
If you had the value `true` you can remove the option as webpack 5 is now the default for all Next.js apps unless opted out.
If you had he value `false` you can update `next.config.js`:
If you had the value `false` you can update `next.config.js`:
Change `future.webpack5` to `webpack5`.

View File

@@ -0,0 +1,19 @@
# ESM packages need to be imported
#### Why This Error Occurred
Packages in node_modules that are published as EcmaScript Module, need to be `import`ed via `import ... from 'package'` or `import('package')`.
You get this error when using a different way to reference the package, e. g. `require()`.
#### Possible Ways to Fix It
1. Use `import` or `import()` to reference the package instead. (Recommended)
2. If you are already using `import`, make sure that this is not changed by a transpiler, e. g. TypeScript or Babel.
3. Switch to loose mode (`experimental.esmExternals: 'loose'`), which tries to automatically correct this error.
### Useful Links
- [Node.js ESM require docs](https://nodejs.org/dist/latest-v16.x/docs/api/esm.html#esm_require)

View File

@@ -2,11 +2,11 @@
#### Why This Error
In your `next.config.js` file you provided an invalid config for the `i18n` field.
In your `next.config.js` file you provided an invalid config for the `i18n` field. This could mean the limit for 100 locale items was exceeded.
#### Possible Ways to Fix It
Make sure your `i18n` field follows the allowed config shape and values:
Make sure your `i18n` field follows the allowed config shape, limits, and values:
```js
module.exports = {

View File

@@ -18,8 +18,12 @@ module.exports = {
// limit of 50 domains values
domains: [],
path: '/_next/image',
// loader can be 'default', 'imgix', 'cloudinary', or 'akamai'
// loader can be 'default', 'imgix', 'cloudinary', 'akamai', or 'custom'
loader: 'default',
// disable static imports for image files
disableStaticImages: false,
// minimumCacheTTL is in seconds, must be integer 0 or more
minimumCacheTTL: 60,
},
}
```

View File

@@ -13,6 +13,10 @@
"title": "amp-export-validation",
"path": "/errors/amp-export-validation.md"
},
{
"title": "api-routes-body-size-limit",
"path": "/errors/api-routes-body-size-limit.md"
},
{
"title": "api-routes-static-export",
"path": "/errors/api-routes-static-export.md"
@@ -245,6 +249,14 @@
"title": "next-head-count-missing",
"path": "/errors/next-head-count-missing.md"
},
{
"title": "next-image-missing-loader",
"path": "/errors/next-image-missing-loader.md"
},
{
"title": "next-image-missing-loader-width",
"path": "/errors/next-image-missing-loader-width.md"
},
{
"title": "next-image-unconfigured-host",
"path": "/errors/next-image-unconfigured-host.md"
@@ -267,6 +279,10 @@
"title": "no-document-viewport-meta",
"path": "/errors/no-document-viewport-meta.md"
},
{
"title": "no-duplicate-head",
"path": "/errors/no-duplicate-head.md"
},
{
"title": "no-head-import-in-document",
"path": "/errors/no-head-import-in-document.md"
@@ -394,6 +410,34 @@
{
"title": "placeholder-blur-data-url",
"path": "/errors/placeholder-blur-data-url.md"
},
{
"title": "import-esm-externals",
"path": "/errors/import-esm-externals.md"
},
{
"title": "max-custom-routes-reached",
"path": "max-custom-routes-reached.md"
},
{
"title": "static-page-generation-timeout",
"path": "/errors/static-page-generation-timeout.md"
},
{
"title": "page-data-collection-timeout",
"path": "/errors/page-data-collection-timeout.md"
},
{
"title": "sharp-missing-in-production",
"path": "/errors/sharp-missing-in-production.md"
},
{
"title": "max-custom-routes-reached",
"path": "/errors/max-custom-routes-reached.md"
},
{
"title": "module-not-found",
"path": "/errors/module-not-found.md"
}
]
}

View File

@@ -0,0 +1,17 @@
# Max Custom Routes Reached
#### Why This Error Occurred
The number of combined routes from `headers`, `redirects`, and `rewrites` exceeds 1000. This can impact performance because each request will iterate over all routes to check for a match in the worst case.
#### Possible Ways to Fix It
- Leverage dynamic routes inside of the `pages` folder to reduce the number of rewrites needed
- Combine headers routes into dynamic matches e.g. `/first-header-route` `/second-header-route` -> `/(first-header-route$|second-header-route$)`
### Useful Links
- [Dynamic Routes documentation](https://nextjs.org/docs/routing/dynamic-routes)
- [Rewrites documentation](https://nextjs.org/docs/api-reference/next.config.js/rewrites)
- [Redirects documentation](https://nextjs.org/docs/api-reference/next.config.js/redirects)
- [Headers documentation](https://nextjs.org/docs/api-reference/next.config.js/headers)

View File

@@ -0,0 +1,151 @@
# Module Not Found
#### Why This Error Occurred
A module not found error can occur for many different reasons:
- The module you're trying to import is not installed in your dependencies
- The module you're trying to import is in a different directory
- The module you're trying to import has a different casing
- The module you're trying to import uses Node.js specific modules, for example `dns`, outside of `getStaticProps` / `getStaticPaths` / `getServerSideProps`
#### Possible Ways to Fix It
##### The module you're trying to import is not installed in your dependencies
When importing a module from [npm](https://npmjs.com) this module has to be installed locally.
For example when importing the `swr` package:
```js
import useSWR from 'swr'
```
The `swr` module has to be installed using a package manager.
- When using `npm`: `npm install swr`
- When using `yarn`: `yarn add swr`
##### The module you're trying to import is in a different directory
Make sure that the path you're importing refers to the right directory and file.
##### The module you're trying to import has a different casing
Make sure the casing of the file is correct.
Example:
```js
// components/MyComponent.js
export default function MyComponent() {
return <h1>Hello</h1>
}
```
```js
// pages/index.js
// Note how `components/MyComponent` exists but `Mycomponent` without the capital `c` is imported
import MyComponent from '../components/Mycomponent'
```
Incorrect casing will lead to build failures on case-sensitive environments like most Linux-based continuous integration and can cause issues with Fast Refresh.
##### The module you're trying to import uses Node.js specific modules
`getStaticProps`, `getStaticPaths`, and `getServerSideProps` allow for using modules that can only run in the Node.js environment. This allows you to do direct database queries or reading data from Redis to name a few examples.
The tree shaking only runs on top level pages, so it can't be relied on in separate React components.
You can verify the tree shaking on [next-code-elimination.vercel.app](https://next-code-elimination.vercel.app/).
Example of correctly tree shaken code:
```js
// lib/redis.js
import Redis from 'ioredis'
const redis = new Redis(process.env.REDIS_URL)
export default redis
```
```js
// pages/index.js
import redis from '../lib/redis'
export async function getStaticProps() {
const message = await redis.get('message')
return {
message,
}
}
export default function Home({ message }) {
return <h1>{message}</h1>
}
```
Example of code that would break:
```js
// lib/redis.js
import Redis from 'ioredis'
const redis = new Redis(process.env.REDIS_URL)
export default redis
```
```js
// pages/index.js
// Redis is a Node.js specific library that can't run in the browser
// Trying to use it in code that runs on both Node.js and the browser will result in a module not found error for modules that ioredis relies on
// If you run into such an error it's recommended to move the code to `getStaticProps` or `getServerSideProps` as those methods guarantee that the code is only run in Node.js.
import redis from '../lib/redis'
import { useEffect, useState } from 'react'
export default function Home() {
const [message, setMessage] = useState()
useEffect(() => {
redis.get('message').then((result) => {
setMessage(result)
})
}, [])
return <h1>{message}</h1>
}
```
Example of code that would break:
```js
// lib/redis.js
import Redis from 'ioredis'
// Modules that hold Node.js-only code can't also export React components
// Tree shaking of getStaticProps/getStaticPaths/getServerSideProps is ran only on page files
const redis = new Redis(process.env.REDIS_URL)
export function MyComponent() {
return <h1>Hello</h1>
}
export default redis
```
```js
// pages/index.js
// In practice you'll want to refactor the `MyComponent` to be a separate file so that tree shaking ensures that specific import is not included for the browser compilation
import redis, { MyComponent } from '../lib/redis'
export async function getStaticProps() {
const message = await redis.get('message')
return {
message,
}
}
export default function Home() {
return <MyComponent />
}
```

View File

@@ -0,0 +1,17 @@
# Missing `width` in the URL Returned by the Loader Prop on `next/image`
#### Why This Error Occurred
The [`loader`](https://nextjs.org/docs/api-reference/next/image#loader) prop on the `next/image` component allows you to override the built-in URL resolution with a custom implementation in order to support any 3rd party cloud provider that can perform Image Optimization.
This error occurred because the provided `loader()` function did not use `width` in the returned URL string. This means that the image will likely not be resized and therefore degrade performance.
#### Possible Ways to Fix It
- Ensure your Image Optimization provider can resize images. Then use the `width` parameter from the [`loader()`](https://nextjs.org/docs/api-reference/next/image#loader) function to construct the correct URL string.
- Add the [`unoptimized`](https://nextjs.org/docs/api-reference/next/image#unoptimized) prop.
### Useful Links
- [Image Optimization Documentation](https://nextjs.org/docs/basic-features/image-optimization)
- [`next/image` Documentation](https://nextjs.org/docs/api-reference/next/image)

View File

@@ -0,0 +1,15 @@
# Missing `loader` Prop on `next/image`
#### Why This Error Occurred
When using the `next/image` component with [`loader="custom"`](https://nextjs.org/docs/basic-features/image-optimization#loader) in `next.config.js`, you must provide the [`loader`](https://nextjs.org/docs/api-reference/next/image#loader) prop to the component with your custom implementation.
#### Possible Ways to Fix It
- Add the [`loader`](https://nextjs.org/docs/api-reference/next/image#loader) prop to all usages of the `next/image` component.
- Change the [`loader`](https://nextjs.org/docs/basic-features/image-optimization#loader) configuration in `next.config.js`.
### Useful Links
- [Image Optimization Documentation](https://nextjs.org/docs/basic-features/image-optimization)
- [`next/image` Documentation](https://nextjs.org/docs/api-reference/next/image)

View File

@@ -2,11 +2,11 @@
#### Why This Error Occurred
On one of your pages that leverages the `next/image` component, you passed a `src` value that uses a `hostname` in the URL that isn't defined in the `images` config in `next.config.js`.
On one of your pages that leverages the `next/image` component, you passed a `src` value that uses a hostname in the URL that isn't defined in the `images.domains` config in `next.config.js`.
#### Possible Ways to Fix It
Add the `hostname` to your `images` config in `next.config.js`:
Add the hostname of your URL to the `images.domains` config in `next.config.js`:
```js
// next.config.js

View File

@@ -6,4 +6,4 @@ Next.js can only handle running a server when the `target` is set to `server` (t
#### Possible Ways to Fix It
Use a different handler than `next start` when testing a serverless **production** build, otherwise just use `next dev`.
Use a different handler than `next start` when testing a serverless **production** build, otherwise use `next dev`.

View File

@@ -81,7 +81,11 @@ Using GitHub's [actions/cache](https://github.com/actions/cache), add the follow
uses: actions/cache@v2
with:
path: ${{ github.workspace }}/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}
# Generate a new cache whenever packages or source files change.
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**.[jt]sx?') }}
# If source files changed but packages didn't, rebuild from a prior cache.
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
```
#### Bitbucket Pipelines

View File

@@ -0,0 +1,38 @@
# No Duplicate Head
### Why This Error Occurred
More than a single instance of the `<Head />` component was used in a single custom document. This can cause unexpected behavior in your application.
### Possible Ways to Fix It
Only use a single `<Head />` component in your custom document in `pages/_document.js`.
```jsx
// pages/_document.js
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx) {
//...
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
```
### Useful Links
- [Custom Document](https://nextjs.org/docs/advanced-features/custom-document)

View File

@@ -0,0 +1,18 @@
# Collecting page data timed out after multiple attempts
#### Why This Error Occurred
Next.js tries to restart the worker pool of the page data collection when no progress happens for a while, to avoid hanging builds.
When restarted it will retry all uncompleted jobs, but if a job was unsuccessfully attempted multiple times, this will lead to an error.
#### Possible Ways to Fix It
- Make sure that there is no infinite loop during execution.
- Make sure all Promises in `getStaticPaths` `resolve` or `reject` correctly.
- Avoid very long timeouts for network requests.
- Increase the timeout by changing the `experimental.pageDataCollectionTimeout` configuration option (default `60` in seconds).
### Useful Links
- [`getStaticPaths`](https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation)

View File

@@ -4,7 +4,7 @@
You are attempting use the `next/image` component with `placeholder=blur` property but no `blurDataURL` property.
The `blurDataURL` might be missing because your using a string for `src` instead of a static import.
The `blurDataURL` might be missing because you're using a string for `src` instead of a static import.
Or `blurDataURL` might be missing because the static import is an unsupported image format. Only jpg, png, and webp are supported at this time.

View File

@@ -18,4 +18,4 @@ These requests have low-priority and yield to fetch() or XHR requests. Next.js w
The prefetch attribute is no longer needed, when set to true, example: `prefetch={true}`, remove the property.
Prefetching can be disabled with `prefetch={false}`.
Prefetching can be turned off with `prefetch={false}`.

View File

@@ -0,0 +1,13 @@
# Sharp Missing In Production
#### Why This Error Occurred
The `next/image` component's default loader uses the ['squoosh'](https://www.npmjs.com/package/@squoosh/lib) library for image resizing and optimization. This library is quick to install and suitable for a dev server environment. For a production environment, it is strongly recommended that you install the optional [`sharp`](https://www.npmjs.com/package/sharp). This package was not detected when leveraging the Image Optimization in production mode (`next start`).
#### Possible Ways to Fix It
Install `sharp` by running `yarn add sharp` in your project directory.
### Useful Links
- [Image Optimization Documentation](https://nextjs.org/docs/basic-features/image-optimization)

View File

@@ -8,7 +8,7 @@ The reason we want to support a `public` directory instead is to not require the
#### Possible Ways to Fix It
You can move your `static` directory inside of the `public` directory and all URLs will remain the same as they were before.
You can move your `static` directory inside of the `public` directory and all URLs will stay the same as they were before.
**Before**

View File

@@ -0,0 +1,18 @@
# Static page generation timed out after multiple attempts
#### Why This Error Occurred
Next.js tries to restart the worker pool of the static page generation when no progress happens for a while, to avoid hanging builds.
When restarted it will retry all uncompleted jobs, but if a job was unsuccessfully attempted multiple times, this will lead to an error.
#### Possible Ways to Fix It
- Make sure that there is no infinite loop during execution.
- Make sure all Promises in `getStaticProps` `resolve` or `reject` correctly.
- Avoid very long timeouts for network requests.
- Increase the timeout by changing the `experimental.staticPageGenerationTimeout` configuration option (default `60` in seconds).
### Useful Links
- [`getStaticProps`](https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation)

13
nextjs/errors/template.md Normal file
View File

@@ -0,0 +1,13 @@
# <!-- INSERT TITLE HERE -->
#### Why This Error Occurred
<!-- Explain why the error occurred. Ensure the description makes it clear why the warning/error exists -->
#### Possible Ways to Fix It
<!-- Explain how to fix the warning/error, potentially by providing alternative approaches. Ensure this section is actionable by users -->
### Useful Links
<!-- Add links to relevant documentation -->

View File

@@ -12,5 +12,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "11.0.1"
"version": "11.1.0"
}

View File

@@ -6,6 +6,8 @@
"packages/*"
],
"scripts": {
"clean": "yarn lerna clean -y && yarn lerna bootstrap && yarn lerna exec 'rm -rf ./dist'",
"build": "yarn prepublish",
"lerna": "lerna",
"dev": "lerna run dev --stream --parallel",
"dev2": "while true; do yarn --check-files && yarn dev; done",
@@ -24,36 +26,43 @@
"lint-typescript": "lerna run typescript",
"lint-eslint": "eslint . --ext js,jsx,ts,tsx --max-warnings=0",
"lint-no-typescript": "run-p prettier-check lint-eslint",
"lint": "run-p lint-typescript prettier-check lint-eslint lint-language",
"lint": "run-p lint-typescript lint-eslint",
"lint-fix": "yarn prettier-fix && eslint . --ext js,jsx,ts,tsx --fix --max-warnings=0",
"lint-language": "alex .",
"prettier-check": "prettier --check .",
"prettier-fix": "prettier --write .",
"types": "lerna run types --stream",
"typescript": "lerna run typescript",
"prepublish": "lerna run prepublish",
"publish-canary": "lerna version prerelease --preid canary --force-publish && release --pre --skip-questions",
"publish-canary": "git checkout canary && git pull && lerna version prerelease --preid canary --force-publish && release --pre --skip-questions",
"publish-stable": "lerna version --force-publish",
"lint-staged": "lint-staged",
"next-with-deps": "./scripts/next-with-deps.sh",
"next": "node --trace-deprecation --enable-source-maps packages/next/dist/bin/next",
"debug": "node --inspect packages/next/dist/bin/next"
},
"pre-commit": "lint-staged",
"devDependencies": {
"@babel/eslint-parser": "7.13.14",
"@babel/plugin-proposal-object-rest-spread": "7.12.1",
"@babel/preset-flow": "7.12.1",
"@babel/preset-react": "7.12.10",
"@fullhuman/postcss-purgecss": "1.3.0",
"@mdx-js/loader": "0.18.0",
"@svgr/webpack": "5.5.0",
"@swc/core": "1.2.74",
"@testing-library/react": "11.2.5",
"@types/b64-lite": "1.3.0",
"@types/cheerio": "0.22.16",
"@types/cookie-session": "2.0.42",
"@types/fs-extra": "8.1.0",
"@types/http-proxy": "1.17.3",
"@types/jest": "26.0.20",
"@types/passport": "1.0.5",
"@types/sharp": "0.28.4",
"@types/string-hash": "1.1.1",
"@typescript-eslint/eslint-plugin": "4.17.0",
"@typescript-eslint/parser": "^4.20.0",
"@vercel/fetch": "6.1.1",
"@zeit/next-css": "1.0.2-canary.2",
"@zeit/next-sass": "1.0.2-canary.2",
"@zeit/next-typescript": "1.1.2-canary.0",
@@ -62,8 +71,8 @@
"amphtml-validator": "1.0.33",
"async-sema": "3.0.1",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "~10.1.0",
"babel-jest": "27.0.0-next.5",
"babel-plugin-tester": "10.0.0",
"browserslist": "4.16.6",
"browserstack-local": "1.4.0",
"cheerio": "0.22.0",
@@ -88,7 +97,7 @@
"firebase": "7.14.5",
"fs-extra": "^9.1.0",
"get-port": "5.1.1",
"glob": "7.1.6",
"glob": "7.1.7",
"gzip-size": "5.1.1",
"image-size": "1.0.0",
"is-animated": "2.0.0",
@@ -117,7 +126,9 @@
"pretty-bytes": "5.3.0",
"pretty-ms": "7.0.0",
"react": "0.0.0-experimental-6a589ad71",
"react-18": "npm:react@next",
"react-dom": "0.0.0-experimental-6a589ad71",
"react-dom-18": "npm:react-dom@next",
"react-ssr-prepass": "1.0.8",
"release": "6.3.0",
"request-promise-core": "1.1.2",

View File

@@ -89,7 +89,11 @@ export async function createApp({
console.error(
`Could not locate an example named ${chalk.red(
`"${example}"`
)}. Please check your spelling and try again.`
)}. It could be due to the following:\n`,
`1. Your spelling of example ${chalk.red(
`"${example}"`
)} might be incorrect.\n`,
`2. You might not be connected to the internet.`
)
process.exit(1)
}
@@ -252,7 +256,7 @@ export async function createApp({
rename: (name) => {
switch (name) {
case 'gitignore':
case 'eslintrc': {
case 'eslintrc.json': {
return '.'.concat(name)
}
// README.md is ignored by webpack-asset-relocator-loader used by ncc:

View File

@@ -1,7 +1,6 @@
{
"private": true,
"name": "create-next-app",
"version": "11.0.1",
"version": "11.1.0",
"keywords": [
"react",
"next",

View File

@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}

View File

@@ -14,7 +14,7 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the
You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.tsx`.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.

View File

@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}

View File

@@ -1,3 +1,4 @@
/** @type {import('next').NextConfig} */
module.exports = {
reactStrictMode: true,
}

View File

@@ -1,8 +1,9 @@
import type { NextPage } from 'next'
import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'
export default function Home() {
const Home: NextPage = () => {
return (
<div className={styles.container}>
<Head>
@@ -67,3 +68,5 @@ export default function Home() {
</div>
)
}
export default Home

View File

@@ -1,8 +1,3 @@
module.exports = {
extends: ['.'].map(require.resolve),
rules: {
'@next/next/no-sync-scripts': 2,
'@next/next/no-html-link-for-pages': 2,
'@next/next/no-img-element': 2,
},
extends: [require.resolve('.'), 'plugin:@next/next/core-web-vitals'],
}

View File

@@ -24,6 +24,11 @@ module.exports = {
img: ['Image'],
},
],
'jsx-a11y/aria-props': 'warn',
'jsx-a11y/aria-proptypes': 'warn',
'jsx-a11y/aria-unsupported-elements': 'warn',
'jsx-a11y/role-has-required-aria-props': 'warn',
'jsx-a11y/role-supports-aria-props': 'warn',
},
parser: './parser.js',
parserOptions: {
@@ -32,6 +37,10 @@ module.exports = {
allowImportExportEverywhere: true,
babelOptions: {
presets: ['next/babel'],
caller: {
// Eslint supports top level await when a parser for it is included. We enable the parser by default for Babel.
supportsTopLevelAwait: true,
},
},
},
overrides: [
@@ -63,4 +72,8 @@ module.exports = {
},
},
},
env: {
browser: true,
node: true,
},
}

View File

@@ -1,7 +1,6 @@
{
"name": "eslint-config-next",
"private": "true",
"version": "11.0.1",
"version": "11.1.0",
"description": "ESLint configuration used by NextJS.",
"main": "index.js",
"license": "MIT",
@@ -10,7 +9,7 @@
"directory": "packages/eslint-config-next"
},
"dependencies": {
"@next/eslint-plugin-next": "11.0.1",
"@next/eslint-plugin-next": "11.1.0",
"@rushstack/eslint-patch": "^1.0.6",
"@typescript-eslint/parser": "^4.20.0",
"eslint-import-resolver-node": "^0.3.4",

Some files were not shown because too many files have changed in this diff Show More