1
0
mirror of synced 2026-02-06 00:00:10 -05:00

Compare commits

..

2 Commits

Author SHA1 Message Date
Brandon Bayer
56c7933f3a Merge branch 'canary' into infinite-loop2 2021-04-23 16:11:14 -04:00
Brandon Bayer
7be9466b94 failing test 2021-04-23 16:05:02 -04:00
4391 changed files with 105304 additions and 43558 deletions

View File

@@ -181,8 +181,7 @@
"contributions": [
"code",
"maintenance",
"test",
"doc"
"test"
]
},
{
@@ -357,8 +356,7 @@
"contributions": [
"test",
"code",
"review",
"doc"
"review"
]
},
{
@@ -532,8 +530,7 @@
"avatar_url": "https://avatars1.githubusercontent.com/u/19371989?v=4",
"profile": "https://builtforfifty.com",
"contributions": [
"code",
"doc"
"code"
]
},
{
@@ -2335,8 +2332,7 @@
"avatar_url": "https://avatars.githubusercontent.com/u/1483597?v=4",
"profile": "https://github.com/ericvicenti",
"contributions": [
"doc",
"code"
"doc"
]
},
{
@@ -2375,8 +2371,7 @@
"avatar_url": "https://avatars.githubusercontent.com/u/1357323?v=4",
"profile": "http://twitter.com/_markeh",
"contributions": [
"code",
"doc"
"code"
]
},
{
@@ -2412,8 +2407,7 @@
"avatar_url": "https://avatars.githubusercontent.com/u/1384885?v=4",
"profile": "www.usertrack.net",
"contributions": [
"doc",
"code"
"doc"
]
},
{
@@ -2487,389 +2481,6 @@
"contributions": [
"code"
]
},
{
"login": "mubaidr",
"name": "Muhammad Ubaid Raza",
"avatar_url": "https://avatars.githubusercontent.com/u/2222702?v=4",
"profile": "https://mubaidr.github.io",
"contributions": [
"code",
"doc"
]
},
{
"login": "silicontwin",
"name": "Nick Warren",
"avatar_url": "https://avatars.githubusercontent.com/u/121665?v=4",
"profile": "https://github.com/silicontwin",
"contributions": [
"code"
]
},
{
"login": "mlabate",
"name": "mlabate",
"avatar_url": "https://avatars.githubusercontent.com/u/17139676?v=4",
"profile": "https://github.com/mlabate",
"contributions": [
"doc"
]
},
{
"login": "lumaxis",
"name": "Lukas Spieß",
"avatar_url": "https://avatars.githubusercontent.com/u/406937?v=4",
"profile": "https://github.com/lumaxis",
"contributions": [
"doc"
]
},
{
"login": "dawnofmidnight",
"name": "DawnOfMidnight",
"avatar_url": "https://avatars.githubusercontent.com/u/78233879?v=4",
"profile": "https://dawnofmidnight.vercel.app",
"contributions": [
"doc"
]
},
{
"login": "kirakik",
"name": "Kenza Iraki",
"avatar_url": "https://avatars.githubusercontent.com/u/17203119?v=4",
"profile": "https://www.linkedin.com/in/kenzairaki/",
"contributions": [
"test",
"code"
]
},
{
"login": "agustif",
"name": "Agusti Fernandez",
"avatar_url": "https://avatars.githubusercontent.com/u/6601142?v=4",
"profile": "https://github.com/agustif",
"contributions": [
"code"
]
},
{
"login": "Anjianto",
"name": "Anjianto",
"avatar_url": "https://avatars.githubusercontent.com/u/61521141?v=4",
"profile": "https://github.com/Anjianto",
"contributions": [
"code"
]
},
{
"login": "adblanc",
"name": "Blanc Adrien",
"avatar_url": "https://avatars.githubusercontent.com/u/41756894?v=4",
"profile": "https://adrienblanc.com",
"contributions": [
"code"
]
},
{
"login": "meepdeew",
"name": "meepdeew",
"avatar_url": "https://avatars.githubusercontent.com/u/43303008?v=4",
"profile": "https://github.com/meepdeew",
"contributions": [
"doc"
]
},
{
"login": "Hardik3296",
"name": "Hardik Gaur",
"avatar_url": "https://avatars.githubusercontent.com/u/20360325?v=4",
"profile": "https://github.com/Hardik3296",
"contributions": [
"doc"
]
},
{
"login": "acornellier",
"name": "acornellier",
"avatar_url": "https://avatars.githubusercontent.com/u/8725423?v=4",
"profile": "https://github.com/acornellier",
"contributions": [
"code"
]
},
{
"login": "craigglennie",
"name": "craigglennie",
"avatar_url": "https://avatars.githubusercontent.com/u/149281?v=4",
"profile": "https://github.com/craigglennie",
"contributions": [
"doc"
]
},
{
"login": "fernvilla",
"name": "Fernando Villasenor",
"avatar_url": "https://avatars.githubusercontent.com/u/5857808?v=4",
"profile": "http://www.fernvillasenor.com",
"contributions": [
"code"
]
},
{
"login": "swiftgaruda",
"name": "swiftgaruda",
"avatar_url": "https://avatars.githubusercontent.com/u/16741392?v=4",
"profile": "https://github.com/swiftgaruda",
"contributions": [
"doc"
]
},
{
"login": "Patil2099",
"name": "Pankaj Patil",
"avatar_url": "https://avatars.githubusercontent.com/u/35653876?v=4",
"profile": "https://pplife.home.blog",
"contributions": [
"doc"
]
},
{
"login": "mabadir",
"name": "Mina Abadir",
"avatar_url": "https://avatars.githubusercontent.com/u/3389914?v=4",
"profile": "minaabadir.ca",
"contributions": [
"code",
"doc",
"test"
]
},
{
"login": "frankiesardo",
"name": "Francesco Sardo",
"avatar_url": "https://avatars.githubusercontent.com/u/1476561?v=4",
"profile": "https://github.com/frankiesardo",
"contributions": [
"doc",
"code"
]
},
{
"login": "enemycnt",
"name": "Nikolay",
"avatar_url": "https://avatars.githubusercontent.com/u/320313?v=4",
"profile": "https://github.com/enemycnt",
"contributions": [
"doc"
]
},
{
"login": "Dipeshwagle",
"name": "Dipesh Wagle",
"avatar_url": "https://avatars.githubusercontent.com/u/4191022?v=4",
"profile": "https://dipeshwagle.com",
"contributions": [
"code"
]
},
{
"login": "benbender",
"name": "Benjamin Bender",
"avatar_url": "https://avatars.githubusercontent.com/u/462455?v=4",
"profile": "https://codepoet.de",
"contributions": [
"code"
]
},
{
"login": "nimashoghi",
"name": "Nima Shoghi",
"avatar_url": "https://avatars.githubusercontent.com/u/3728170?v=4",
"profile": "https://nima.sh",
"contributions": [
"code"
]
},
{
"login": "chronark",
"name": "Andreas Thomas",
"avatar_url": "https://avatars.githubusercontent.com/u/18246773?v=4",
"profile": "https://github.com/chronark",
"contributions": [
"doc"
]
},
{
"login": "guoqqqi",
"name": "guoqqqi",
"avatar_url": "https://avatars.githubusercontent.com/u/72343596?v=4",
"profile": "https://github.com/guoqqqi",
"contributions": [
"doc"
]
},
{
"login": "timbooker",
"name": "Tim",
"avatar_url": "https://avatars.githubusercontent.com/u/612681?v=4",
"profile": "https://github.com/timbooker",
"contributions": [
"code",
"test"
]
},
{
"login": "ormarek",
"name": "Marek Orłowski",
"avatar_url": "https://avatars.githubusercontent.com/u/16357457?v=4",
"profile": "http://orlowski.me/",
"contributions": [
"doc"
]
},
{
"login": "AntoineGuestin",
"name": "Antoine G",
"avatar_url": "https://avatars.githubusercontent.com/u/70888750?v=4",
"profile": "https://github.com/AntoineGuestin",
"contributions": [
"code"
]
},
{
"login": "swinner2",
"name": "Sean Winner",
"avatar_url": "https://avatars.githubusercontent.com/u/6707308?v=4",
"profile": "https://github.com/swinner2",
"contributions": [
"code",
"test",
"doc"
]
},
{
"login": "max-programming",
"name": "Max Programming",
"avatar_url": "https://avatars.githubusercontent.com/u/51731966?v=4",
"profile": "https://usman-s.me",
"contributions": [
"code"
]
},
{
"login": "sebastianhoitz",
"name": "Sebastian Hoitz",
"avatar_url": "https://avatars.githubusercontent.com/u/353768?v=4",
"profile": "https://makemake.sh",
"contributions": [
"test",
"code"
]
},
{
"login": "garnerp",
"name": "garnerp",
"avatar_url": "https://avatars.githubusercontent.com/u/737307?v=4",
"profile": "https://github.com/garnerp",
"contributions": [
"doc"
]
},
{
"login": "kivi",
"name": "kivi",
"avatar_url": "https://avatars.githubusercontent.com/u/366163?v=4",
"profile": "https://github.com/kivi",
"contributions": [
"code"
]
},
{
"login": "dangreaves",
"name": "Dan Greaves",
"avatar_url": "https://avatars.githubusercontent.com/u/1036142?v=4",
"profile": "http://dangreaves.com",
"contributions": [
"code"
]
},
{
"login": "lksnmnn",
"name": "Lukas Neumann",
"avatar_url": "https://avatars.githubusercontent.com/u/4983285?v=4",
"profile": "lksnmnn.com",
"contributions": [
"doc",
"code",
"test"
]
},
{
"login": "dbachrach",
"name": "Dustin Bachrach",
"avatar_url": "https://avatars.githubusercontent.com/u/45016?v=4",
"profile": "dbachrach.com",
"contributions": [
"code",
"doc"
]
},
{
"login": "ashikka",
"name": "Ashikka Gupta",
"avatar_url": "https://avatars.githubusercontent.com/u/58368421?v=4",
"profile": "https://github.com/ashikka",
"contributions": [
"code",
"test"
]
},
{
"login": "deini",
"name": "Daniel Almaguer",
"avatar_url": "https://avatars.githubusercontent.com/u/2752665?v=4",
"profile": "https://github.com/deini",
"contributions": [
"doc"
]
},
{
"login": "igeligel",
"name": "Kevin Peters",
"avatar_url": "https://avatars.githubusercontent.com/u/12736734?v=4",
"profile": "https://www.kevinpeters.net/about/",
"contributions": [
"doc"
]
},
{
"login": "prisis",
"name": "Daniel Bannert",
"avatar_url": "https://avatars.githubusercontent.com/u/2716058?v=4",
"profile": "http://anolilab.de",
"contributions": [
"code"
]
},
{
"login": "benjakugler96",
"name": "Benja Kugler",
"avatar_url": "https://avatars.githubusercontent.com/u/53273645?v=4",
"profile": "https://benjakugler96.github.io/",
"contributions": [
"code"
]
},
{
"login": "esemeniuc",
"name": "Eric Semeniuc",
"avatar_url": "https://avatars.githubusercontent.com/u/3838856?v=4",
"profile": "https://semeniuc.ml/",
"contributions": [
"test",
"code"
]
}
],
"contributorsPerLine": 7,

View File

@@ -27,16 +27,14 @@ eslint.config.*
/recipes/*/templates
/packages/generator/templates
/packages/cli/lib
/packages/babel-preset/src/fix-node-file-trace/tests/**
/test/integration/**/out/**
/nextjs/packages/create-next-app
// COPIED FROM nextjs/.eslintignore
/nextjs/**/.next/**
/nextjs/**/_next/**
/nextjs/**/dist/**
/nextjs/examples/**
/nextjs/examples/with-typescript-eslint-jest/**
/nextjs/examples/with-kea/**
/nextjs/packages/next/bundles/webpack/packages/*.runtime.js
/nextjs/packages/next/compiled/**/*
/nextjs/packages/react-refresh-utils/**/*.js
@@ -49,5 +47,4 @@ eslint.config.*
/nextjs/packages/next-codemod/**/*.d.ts
/nextjs/packages/next-env/**/*.d.ts
/nextjs/test/integration/async-modules/**
/nextjs/test/integration/eslint/**
/nextjs/test-timings.json

View File

@@ -80,19 +80,6 @@ module.exports = {
"@typescript-eslint/no-floating-promises": "off",
},
},
{
files: ["examples/**"],
plugins: ["cypress"],
parserOptions: {
project: null,
},
env: {
"cypress/globals": true,
},
rules: {
"simple-import-sort/imports": "off",
},
},
{
files: ["packages/cli/src/commands/**/*"],
rules: {

View File

@@ -1,13 +1,9 @@
name: Size Check
name: CI
on:
pull_request:
branches: [master, canary]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Compressed Size

View File

@@ -3,13 +3,11 @@
name: CI
on:
push:
branches: [canary]
pull_request:
types: [opened, synchronize]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
name: Lint
@@ -30,9 +28,9 @@ jobs:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
**/node_modules
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v6-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
${{ runner.os }}-${{ runner.node_version}}-yarn-v6-
- name: Install dependencies
run: yarn install --frozen-lockfile --silent
env:
@@ -41,10 +39,6 @@ jobs:
run: yarn manypkg check
env:
CI: true
- name: Build next.js
run: yarn build:nextjs
env:
CI: true
- name: yarn lint
run: yarn lint
env:
@@ -76,9 +70,9 @@ jobs:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
**/node_modules
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v6-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
${{ runner.os }}-${{ runner.node_version}}-yarn-v6-
- run: yarn install --frozen-lockfile --check-files
- name: Build Packages
run: yarn build
@@ -144,9 +138,9 @@ jobs:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
**/node_modules
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v6-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
${{ runner.os }}-${{ runner.node_version}}-yarn-v6-
- run: yarn install --frozen-lockfile --check-files
# - run: yarn cpy node_modules/.blitz packages/core/node_modules/.blitz
# if: matrix.os == 'windows-latest'
@@ -160,7 +154,7 @@ jobs:
if: matrix.os == 'ubuntu-latest'
run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
- name: Test examples
run: yarn testonly:examples
run: yarn testonly:examples || yarn testonly:examples
env:
CI: true
@@ -245,7 +239,7 @@ jobs:
strategy:
fail-fast: false
matrix:
group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
steps:
- run: echo ${{needs.build.outputs.docsChange}}
working-directory: ./
@@ -260,7 +254,7 @@ jobs:
- run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
- run: xvfb-run node run-tests.js --timings -g ${{ matrix.group }}/20 -c 3
- run: xvfb-run node run-tests.js --timings -g ${{ matrix.group }}/10 -c 3
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testElectron:
@@ -287,8 +281,9 @@ jobs:
- run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
- run: cd test/integration/with-electron/app && yarn
- run: yarn add -W --dev spectron@7.0.0 electron@5.0.0
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
working-directory: ./
- run: xvfb-run node run-tests.js test/integration/with-electron/test/index.test.js
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
@@ -308,6 +303,127 @@ jobs:
steps:
- run: exit 0
testFutureDependencies:
name: Nextjs - Webpack 5 (Basic, Production, Acceptance)
runs-on: ubuntu-latest
env:
NEXT_TELEMETRY_DISABLED: 1
NEXT_TEST_JOB: 1
HEADLESS: true
NEXT_PRIVATE_TEST_WEBPACK5_MODE: 1
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 25
- run: echo ::set-output name=DOCS_CHANGE::$(node skip-docs-change.js echo 'not-docs-only-change')
id: docs-change
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- name: Use Node.js
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
uses: actions/setup-node@v2
with:
node-version: "14"
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- name: Get yarn cache directory path
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Cache node_modules
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
id: yarn-cache
uses: actions/cache@v2
with:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
**/node_modules
/home/runner/.cache/Cypress
C:\Users\runneradmin\AppData\Local\Cypress\Cache
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v6-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v6-
- run: yarn install --check-files
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: yarn build:nextjs
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: xvfb-run node run-tests.js test/integration/{fallback-modules,link-ref,production,basic,async-modules,font-optimization,ssr-ctx}/test/index.test.js test/acceptance/*.test.js
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
working-directory: nextjs
testLegacyReact:
name: Nextjs - React 16 + Webpack 4 (Basic, Production, Acceptance)
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./
env:
NEXT_TELEMETRY_DISABLED: 1
NEXT_TEST_JOB: 1
HEADLESS: true
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 25
- run: echo ::set-output name=DOCS_CHANGE::$(node skip-docs-change.js echo 'not-docs-only-change')
id: docs-change
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: cat package.json | jq '.resolutions.react = "^16.14.0"' > package.json.tmp && mv package.json.tmp package.json
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: cat package.json | jq '.resolutions."react-dom" = "^16.14.0"' > package.json.tmp && mv package.json.tmp package.json
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- name: Use Node.js
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
uses: actions/setup-node@v2
with:
node-version: "14"
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- name: Get yarn cache directory path
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Cache node_modules
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
id: yarn-cache
uses: actions/cache@v2
with:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
**/node_modules
/home/runner/.cache/Cypress
C:\Users\runneradmin\AppData\Local\Cypress\Cache
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v6-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v6-
- run: yarn install --check-files
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: yarn list react react-dom
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: yarn build:nextjs
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: xvfb-run node run-tests.js test/integration/{link-ref,production,basic,async-modules,font-optimization,ssr-ctx,worker-loader}/test/index.test.js test/acceptance/*.test.js
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
working-directory: nextjs
testFirefox:
name: Nextjs - Test Firefox (production)
defaults:
@@ -317,7 +433,7 @@ jobs:
needs: build
env:
HEADLESS: true
BROWSER_NAME: "firefox"
BROWSERNAME: "firefox"
NEXT_TELEMETRY_DISABLED: 1
steps:
- uses: actions/cache@v2
@@ -326,7 +442,7 @@ jobs:
with:
path: ./*
key: ${{ github.sha }}
- run: node run-tests.js -c 1 test/integration/production/test/index.test.js
- run: node run-tests.js test/integration/production/test/index.test.js
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testSafari:
@@ -338,7 +454,7 @@ jobs:
needs: build
env:
BROWSERSTACK: true
BROWSER_NAME: "safari"
BROWSERNAME: "safari"
NEXT_TELEMETRY_DISABLED: 1
SKIP_LOCAL_SELENIUM_SERVER: true
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
@@ -350,7 +466,7 @@ jobs:
with:
path: ./*
key: ${{ github.sha }}
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js -c 1 test/integration/production/test/index.test.js'
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js test/integration/production/test/index.test.js'
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testSafariOld:

2
.gitignore vendored
View File

@@ -29,5 +29,3 @@ examples/auth2
.ultra.cache.json
db.sqlite-journal
test/integration/**/db.json
test/**/*/out
.blitz**

View File

@@ -20,6 +20,3 @@ bin
packages/generator/templates/**
.github/ISSUE_TEMPLATE/bug_report.md
nextjs/packages/next/compiled/**
// Because file from nextjs upstream isn't formatted properly
nextjs/packages/next/build/webpack-config.ts

View File

@@ -1,35 +1,3 @@
# Contributing
[Read the Contributing Guide at Blitzjs.com](https://blitzjs.com/docs/contributing)
## Notes For Core Team
### Syncing Next.js Fork
1. Run `yarn push-nextjs`
- If it fails with an error of `git-subrepo: Can't commit: 'subrepo/nextjs' doesn't contain upstream HEAD:`, then run `yarn push-nextjs --force` (see https://github.com/ingydotnet/git-subrepo/issues/530)
2. Create new git branch for the upgrade
3. In the forked repo (https://github.com/blitz-js/next.js), run:
1. `git pull`
2. `git fetch --all`
3. `git merge v10.2.0` (change the version to be the version you are updating to)
4. Run `rm -rf examples && git add examples`
5. To resolve conflict with their version for a path, like docs, run this:
- `git checkout --theirs docs && git add docs`
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`
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
8. Run `yarn build:nextjs`
9. Run `yarn lint` - fix any issues
10. Run `yarn build` - fix any issues
11. Run `yarn test:nextjs-size` and update tests if there are any failures
12. Open PR and fix any failing tests
13. Update any references to nextjs in new code including imports like `next/image`, etc.
14. Any doc updates needed?
15. Merge PR
16. `yarn push-nextjs`

View File

@@ -1,3 +0,0 @@
# Contributor over time
[![Contributor over time](https://contributor-graph-api.apiseven.com/contributors-svg?chart=contributorOverTime&repo=blitz-js/blitz)](https://www.apiseven.com/en/contributor-graph?chart=contributorOverTime&repo=blitz-js/blitz)

View File

@@ -6,7 +6,7 @@
<img alt="" src="https://img.shields.io/badge/Join%20our%20community-6700EB.svg?style=for-the-badge&labelColor=000000&logoWidth=20&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAQ9SURBVHgB7d3dVdtAEIbhcSpICUoH0IEogQqSVBBSAU4FSSpIOoAORAfQgSghHXzZ1U/YcMD4R9rZmf2ec3y448LyiNf27iLiGIAmPLrweC9Un3DhrzG6EarLNP09nlwJ1SOZ/lQr5N80/S/p2QMVCBf5N17XCfm1Y/rBHqjAG9PPHvBsz+mf9WAP+HLA9M/YA14cOP2payH7jpj+VCtk1wnTP+vj7xCy6cTpn7EHLMLp059iD1iD8eveJbVCNsSLheX1YA/YgOWnf8YeKB3Wmf7Ud6Fy4f/FHmtpxbl3YlC4MJ/Cj0bWdwPnPbARg+L0S54XQHS32WwuxClzd4CM0z9rPfeAuTtA5ulPXYQ7wZ04Y+oOoDD9KZc9YOoOoDj9s4dwFzgXR6w1wIPoOvPWA9buAHEJ173o3gWiy3AnuBUHLEbgmYwvAk1/wuM8vAgexThzbwPDkx7/DHwVXfFOxP2GmsKd4Ab6zPeAyU8CI7AHFmH2BRCBPXAyk18GzUrqAXCTiR4ssyj0VFw/oCU8+e+RZ33AWz6KMaYbIIWxB+JSLs1bsbkeMN0AqakHvoku9oA2sAfqBvbAQdw0QArsgb25aYBUQT3QgT2gB+yBuqGcHij2UCqXDZACe2Anlw2QYg/QAOyBuoE98CL3DZDCuK4/rh/Q7oGL6U+TOvcNkJoijN8X1C48+T+g75eQDrAH/qmqAVJgDwyqaoAUe4AGYA/UDZX3QLUNkEIZPRCd5+6BahsgVUgPROwBTSijB7jpVAvGHriHvmw9wAZ4BpX1ABvgmakHtPcbRuwBTWAPULgAV9D/jKDY9YRvwvgEaurD44uQHvAol7qBW7WKluVtIHiUS7GyvA0s6CiXDnxrpQfsgbqBS7GKk/2jYHCrVlGyfxTMrVo0ALdq1Q3sgSKofh0M9oA61a+D2QM0AHugbmAPqClmSRjK2apVVQ8UsySsoK1aHdgDesCtWnUDeyCrIpeFg1u3sylyWTi3btMA7IG6gT2wuuK3hoE9sKrit4YVslWLPaAN7IG6ocKt2zmY2h4O9sDiTG0PZw/QANy6XTewBxZj9ogYVHy025LMHhEz9cBn0We6B0yfERReBLfhx0/R1YQHPx/QBPbA0VwcEwf2wNFcHBPHHjiem3MC2QPHcXdSaJjA+KfgTPQ8hhfjBzHC40mhlzJ+Xq9lK4a4PCs43AVaGTed5mZq+iOXZwWHi3AnOj2wFWNcnxYe7gTxLtBKHuamP/J+Wnh8a5irB7ZC5Yk9gPX1QuXC+usHWqGyhYvUYR0a7zboUOFCNVhnk0krZAOW7wFOvzXhom2xnEbIHizTA1wEYhWW6YFGyC6c1gOcfg9wfA80Qj7g8B7g9HuCww+haIR8wf49wOn3Cvv9k8tGyC/s7gFOv3fY3QONkH+v9MBWqB7PeqDn9FcIT//kcitUn6kHOu/T/xfWzlQy3dEHhwAAAABJRU5ErkJggg==">
</a>
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
<a aria-label="All Contributors" href="#contributors-"><img alt="" src="https://img.shields.io/badge/all_contributors-304-17BB8A.svg?style=for-the-badge&labelColor=000000"></a>
<a aria-label="All Contributors" href="#contributors-"><img alt="" src="https://img.shields.io/badge/all_contributors-263-17BB8A.svg?style=for-the-badge&labelColor=000000"></a>
<!-- ALL-CONTRIBUTORS-BADGE:END -->
<a aria-label="License" href="https://github.com/blitz-js/blitz/blob/canary/LICENSE">
<img alt="" src="https://img.shields.io/npm/l/blitz.svg?style=for-the-badge&labelColor=000000&color=blue">
@@ -120,10 +120,9 @@ Your financial contributions help ensure Blitz continues to be developed and mai
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/digsas.svg" width="40px"/>
</a></td>
<td><a aria-label="userTrack" href="https://www.usertrack.net/?ref=blitzjs">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/usertrack.png" width="40px"/>
<img alt="" src="https://i.imgur.com/UDBeazC.png" width="40px"/>
</a></td>
</tr>
</table>
</tr></table>
### 🥉 Bronze Sponsors
@@ -136,7 +135,7 @@ Your financial contributions help ensure Blitz continues to be developed and mai
<td><a aria-label="RIT" href="https://rit-inc.co.jp/?utm_source=BlitzJS&utm_medium=sponsorship&utm_campaign=BlitzJS_Sponsorship_2021">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/rit_logo.png" width="200px">
</a></td>
</tr>
</tr>
</table>
@@ -221,14 +220,6 @@ _Issue triage, pull request triage, community encouragement and moderation, etc_
</sub>
</a>
</td>
<td align="center">
<a href="https://mina.ca">
<img src="https://avatars.githubusercontent.com/mabadir" width="100px;" alt="Mina Abadir avatar" /><br />
<sub>
<b>Mina Abadir</b>
</sub>
</a>
</td>
</tr>
</table>
<!-- markdownlint-enable -->
@@ -265,7 +256,7 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
</tr>
<tr>
<td align="center"><a href="http://gielcobben.com"><img src="https://avatars0.githubusercontent.com/u/2663212?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Giel</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=gielcobben" title="Code">💻</a></td>
<td align="center"><a href="http://jeremyliberman.com/"><img src="https://avatars3.githubusercontent.com/u/2754163?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jeremy Liberman</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=MrLeebo" title="Code">💻</a> <a href="#maintenance-MrLeebo" title="Maintenance">🚧</a> <a href="https://github.com/blitz-js/blitz/commits?author=MrLeebo" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=MrLeebo" title="Documentation">📖</a></td>
<td align="center"><a href="http://jeremyliberman.com/"><img src="https://avatars3.githubusercontent.com/u/2754163?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jeremy Liberman</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=MrLeebo" title="Code">💻</a> <a href="#maintenance-MrLeebo" title="Maintenance">🚧</a> <a href="https://github.com/blitz-js/blitz/commits?author=MrLeebo" title="Tests">⚠️</a></td>
<td align="center"><a href="https://jimthedev.com"><img src="https://avatars0.githubusercontent.com/u/108938?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jim Cummins</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jimthedev" title="Code">💻</a></td>
<td align="center"><a href="http://kristinamatuska.com/"><img src="https://media-exp1.licdn.com/dms/image/C5603AQHVPAjV21gw9g/profile-displayphoto-shrink_200_200/0?e=1591228800&v=beta&t=0MlbmiYhNvGv1xjLD_fOhOFjVDZ7ltNwfGNeJ4DHedQ?s=100" width="100px;" alt=""/><br /><sub><b>Kristina Matuška</b></sub></a><br /><a href="#design" title="Design">🎨</a></td>
<td align="center"><a href="https://github.com/jasonblalock"><img src="https://avatars0.githubusercontent.com/u/5899929?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jason Blalock</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jasonblalock" title="Code">💻</a></td>
@@ -288,7 +279,7 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<td align="center"><a href="https://mikeattara.com"><img src="https://avatars1.githubusercontent.com/u/31483629?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mike Perry Y Attara</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=mikeattara" title="Documentation">📖</a></td>
<td align="center"><a href="https://devanthe.dev"><img src="https://avatars0.githubusercontent.com/u/354652?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Devan</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=DevanB" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/jclancy93"><img src="https://avatars2.githubusercontent.com/u/7850202?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jack Clancy</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jclancy93" title="Code">💻</a> <a href="#maintenance-jclancy93" title="Maintenance">🚧</a></td>
<td align="center"><a href="https://github.com/ntgussoni"><img src="https://avatars0.githubusercontent.com/u/10161067?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nicolas Torres</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ntgussoni" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=ntgussoni" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/pulls?q=is%3Apr+reviewed-by%3Antgussoni" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/blitz-js/blitz/commits?author=ntgussoni" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/ntgussoni"><img src="https://avatars0.githubusercontent.com/u/10161067?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nicolas Torres</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ntgussoni" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=ntgussoni" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/pulls?q=is%3Apr+reviewed-by%3Antgussoni" title="Reviewed Pull Requests">👀</a></td>
</tr>
<tr>
<td align="center"><a href="http://simonknott.de"><img src="https://avatars1.githubusercontent.com/u/14912729?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Simon Knott</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Skn0tt" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=Skn0tt" title="Tests">⚠️</a> <a href="#maintenance-Skn0tt" title="Maintenance">🚧</a> <a href="https://github.com/blitz-js/blitz/commits?author=Skn0tt" title="Documentation">📖</a></td>
@@ -312,7 +303,7 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<td align="center"><a href="https://www.dwightwatson.com"><img src="https://avatars3.githubusercontent.com/u/1100408?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dwight Watson</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=dwightwatson" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=dwightwatson" title="Documentation">📖</a></td>
<td align="center"><a href="http://is2ei.com/"><img src="https://avatars3.githubusercontent.com/u/3948353?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Horie Issei</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=is2ei" title="Code">💻</a></td>
<td align="center"><a href="https://twitter.com/lednhatkhanh"><img src="https://avatars2.githubusercontent.com/u/9303093?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nhat Khanh</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=lednhatkhanh" title="Code">💻</a></td>
<td align="center"><a href="https://builtforfifty.com"><img src="https://avatars1.githubusercontent.com/u/19371989?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Abu Uzayr</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=abuuzayr" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=abuuzayr" title="Documentation">📖</a></td>
<td align="center"><a href="https://builtforfifty.com"><img src="https://avatars1.githubusercontent.com/u/19371989?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Abu Uzayr</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=abuuzayr" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/nabi009"><img src="https://avatars0.githubusercontent.com/u/3170831?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nabiullah elham</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=nabi009" title="Code">💻</a></td>
<td align="center"><a href="https://lachlanjc.com"><img src="https://avatars1.githubusercontent.com/u/5074763?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lachlan Campbell</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=lachlanjc" title="Code">💻</a></td>
<td align="center"><a href="http://enzoferey.com"><img src="https://avatars1.githubusercontent.com/u/10673347?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Enzo Ferey</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=enzoferey" title="Code">💻</a></td>
@@ -562,17 +553,17 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
</tr>
<tr>
<td align="center"><a href="https://github.com/FarazPatankar"><img src="https://avatars.githubusercontent.com/u/10681116?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Faraz Patankar</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=FarazPatankar" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/ericvicenti"><img src="https://avatars.githubusercontent.com/u/1483597?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Eric Vicenti</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ericvicenti" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=ericvicenti" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/ericvicenti"><img src="https://avatars.githubusercontent.com/u/1483597?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Eric Vicenti</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ericvicenti" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/amdolan"><img src="https://avatars.githubusercontent.com/u/2552275?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alex Dolan</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=amdolan" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=amdolan" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=amdolan" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/Maastrich"><img src="https://avatars.githubusercontent.com/u/58431775?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mathis Pinsault</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Maastrich" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/gstranger"><img src="https://avatars.githubusercontent.com/u/36181416?v=4?s=100" width="100px;" alt=""/><br /><sub><b>gstranger</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=gstranger" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=gstranger" title="Documentation">📖</a></td>
<td align="center"><a href="http://twitter.com/_markeh"><img src="https://avatars.githubusercontent.com/u/1357323?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mark Hughes</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=markhughes" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=markhughes" title="Documentation">📖</a></td>
<td align="center"><a href="http://twitter.com/_markeh"><img src="https://avatars.githubusercontent.com/u/1357323?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mark Hughes</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=markhughes" title="Code">💻</a></td>
<td align="center"><a href="www.andrearizzello.work"><img src="https://avatars.githubusercontent.com/u/10348930?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrea Rizzello</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=andrearizzello" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="jahred.com.au"><img src="https://avatars.githubusercontent.com/u/13903378?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jahred Hope</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jahredhope" title="Documentation">📖</a></td>
<td align="center"><a href="simonelnahas.github.io/"><img src="https://avatars.githubusercontent.com/u/29279201?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Simon El Nahas</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=simonelnahas" title="Documentation">📖</a></td>
<td align="center"><a href="www.usertrack.net"><img src="https://avatars.githubusercontent.com/u/1384885?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Buleandra Cristian</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Cristy94" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=Cristy94" title="Code">💻</a></td>
<td align="center"><a href="www.usertrack.net"><img src="https://avatars.githubusercontent.com/u/1384885?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Buleandra Cristian</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Cristy94" title="Documentation">📖</a></td>
<td align="center"><a href="http://palauisaac.me/"><img src="https://avatars.githubusercontent.com/u/12257885?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pedro Enrique Palau Isaac</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=peterpalau" title="Code">💻</a></td>
<td align="center"><a href="www.seanbrydon.me"><img src="https://avatars.githubusercontent.com/u/55134778?v=4?s=100" width="100px;" alt=""/><br /><sub><b>sean-brydon</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=sean-brydon" title="Documentation">📖</a></td>
<td align="center"><a href="buonerba.dev"><img src="https://avatars.githubusercontent.com/u/28837891?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alessandro</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Dieman89" title="Documentation">📖</a></td>
@@ -583,59 +574,6 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<td align="center"><a href="antonykamp.de"><img src="https://avatars.githubusercontent.com/u/45163503?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Antony</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=antonykamp" title="Documentation">📖</a></td>
<td align="center"><a href="https://blog.6nok.org"><img src="https://avatars.githubusercontent.com/u/868283?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fatih Altinok</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=frontsideair" title="Documentation">📖</a></td>
<td align="center"><a href="https://mokshitjain.co/"><img src="https://avatars.githubusercontent.com/u/50412128?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mokshit Jain</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Mokshit06" title="Code">💻</a></td>
<td align="center"><a href="https://mubaidr.github.io"><img src="https://avatars.githubusercontent.com/u/2222702?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Muhammad Ubaid Raza</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=mubaidr" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=mubaidr" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/silicontwin"><img src="https://avatars.githubusercontent.com/u/121665?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nick Warren</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=silicontwin" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/mlabate"><img src="https://avatars.githubusercontent.com/u/17139676?v=4?s=100" width="100px;" alt=""/><br /><sub><b>mlabate</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=mlabate" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/lumaxis"><img src="https://avatars.githubusercontent.com/u/406937?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lukas Spieß</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=lumaxis" title="Documentation">📖</a></td>
<td align="center"><a href="https://dawnofmidnight.vercel.app"><img src="https://avatars.githubusercontent.com/u/78233879?v=4?s=100" width="100px;" alt=""/><br /><sub><b>DawnOfMidnight</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=dawnofmidnight" title="Documentation">📖</a></td>
<td align="center"><a href="https://www.linkedin.com/in/kenzairaki/"><img src="https://avatars.githubusercontent.com/u/17203119?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kenza Iraki</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=kirakik" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=kirakik" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/agustif"><img src="https://avatars.githubusercontent.com/u/6601142?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Agusti Fernandez</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=agustif" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/Anjianto"><img src="https://avatars.githubusercontent.com/u/61521141?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Anjianto</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Anjianto" title="Code">💻</a></td>
<td align="center"><a href="https://adrienblanc.com"><img src="https://avatars.githubusercontent.com/u/41756894?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Blanc Adrien</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=adblanc" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/meepdeew"><img src="https://avatars.githubusercontent.com/u/43303008?v=4?s=100" width="100px;" alt=""/><br /><sub><b>meepdeew</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=meepdeew" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/Hardik3296"><img src="https://avatars.githubusercontent.com/u/20360325?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hardik Gaur</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Hardik3296" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/acornellier"><img src="https://avatars.githubusercontent.com/u/8725423?v=4?s=100" width="100px;" alt=""/><br /><sub><b>acornellier</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=acornellier" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/craigglennie"><img src="https://avatars.githubusercontent.com/u/149281?v=4?s=100" width="100px;" alt=""/><br /><sub><b>craigglennie</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=craigglennie" title="Documentation">📖</a></td>
<td align="center"><a href="http://www.fernvillasenor.com"><img src="https://avatars.githubusercontent.com/u/5857808?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fernando Villasenor</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=fernvilla" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/swiftgaruda"><img src="https://avatars.githubusercontent.com/u/16741392?v=4?s=100" width="100px;" alt=""/><br /><sub><b>swiftgaruda</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=swiftgaruda" title="Documentation">📖</a></td>
<td align="center"><a href="https://pplife.home.blog"><img src="https://avatars.githubusercontent.com/u/35653876?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pankaj Patil</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Patil2099" title="Documentation">📖</a></td>
<td align="center"><a href="minaabadir.ca"><img src="https://avatars.githubusercontent.com/u/3389914?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mina Abadir</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=mabadir" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=mabadir" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=mabadir" title="Tests">⚠️</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/frankiesardo"><img src="https://avatars.githubusercontent.com/u/1476561?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Francesco Sardo</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=frankiesardo" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=frankiesardo" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/enemycnt"><img src="https://avatars.githubusercontent.com/u/320313?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nikolay</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=enemycnt" title="Documentation">📖</a></td>
<td align="center"><a href="https://dipeshwagle.com"><img src="https://avatars.githubusercontent.com/u/4191022?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dipesh Wagle</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Dipeshwagle" title="Code">💻</a></td>
<td align="center"><a href="https://codepoet.de"><img src="https://avatars.githubusercontent.com/u/462455?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Benjamin Bender</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=benbender" title="Code">💻</a></td>
<td align="center"><a href="https://nima.sh"><img src="https://avatars.githubusercontent.com/u/3728170?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nima Shoghi</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=nimashoghi" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/chronark"><img src="https://avatars.githubusercontent.com/u/18246773?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andreas Thomas</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=chronark" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/guoqqqi"><img src="https://avatars.githubusercontent.com/u/72343596?v=4?s=100" width="100px;" alt=""/><br /><sub><b>guoqqqi</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=guoqqqi" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/timbooker"><img src="https://avatars.githubusercontent.com/u/612681?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tim</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=timbooker" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=timbooker" title="Tests">⚠️</a></td>
<td align="center"><a href="http://orlowski.me/"><img src="https://avatars.githubusercontent.com/u/16357457?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Marek Orłowski</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ormarek" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/AntoineGuestin"><img src="https://avatars.githubusercontent.com/u/70888750?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Antoine G</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=AntoineGuestin" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/swinner2"><img src="https://avatars.githubusercontent.com/u/6707308?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sean Winner</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=swinner2" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=swinner2" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=swinner2" title="Documentation">📖</a></td>
<td align="center"><a href="https://usman-s.me"><img src="https://avatars.githubusercontent.com/u/51731966?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Max Programming</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=max-programming" title="Code">💻</a></td>
<td align="center"><a href="https://makemake.sh"><img src="https://avatars.githubusercontent.com/u/353768?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sebastian Hoitz</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=sebastianhoitz" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=sebastianhoitz" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/garnerp"><img src="https://avatars.githubusercontent.com/u/737307?v=4?s=100" width="100px;" alt=""/><br /><sub><b>garnerp</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=garnerp" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/kivi"><img src="https://avatars.githubusercontent.com/u/366163?v=4?s=100" width="100px;" alt=""/><br /><sub><b>kivi</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=kivi" title="Code">💻</a></td>
<td align="center"><a href="http://dangreaves.com"><img src="https://avatars.githubusercontent.com/u/1036142?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dan Greaves</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=dangreaves" title="Code">💻</a></td>
<td align="center"><a href="lksnmnn.com"><img src="https://avatars.githubusercontent.com/u/4983285?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lukas Neumann</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=lksnmnn" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=lksnmnn" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=lksnmnn" title="Tests">⚠️</a></td>
<td align="center"><a href="dbachrach.com"><img src="https://avatars.githubusercontent.com/u/45016?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dustin Bachrach</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=dbachrach" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=dbachrach" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/ashikka"><img src="https://avatars.githubusercontent.com/u/58368421?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ashikka Gupta</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ashikka" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=ashikka" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/deini"><img src="https://avatars.githubusercontent.com/u/2752665?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Daniel Almaguer</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=deini" title="Documentation">📖</a></td>
<td align="center"><a href="https://www.kevinpeters.net/about/"><img src="https://avatars.githubusercontent.com/u/12736734?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kevin Peters</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=igeligel" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="http://anolilab.de"><img src="https://avatars.githubusercontent.com/u/2716058?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Daniel Bannert</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=prisis" title="Code">💻</a></td>
<td align="center"><a href="https://benjakugler96.github.io/"><img src="https://avatars.githubusercontent.com/u/53273645?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Benja Kugler</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=benjakugler96" title="Code">💻</a></td>
<td align="center"><a href="https://semeniuc.ml/"><img src="https://avatars.githubusercontent.com/u/3838856?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Eric Semeniuc</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=esemeniuc" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=esemeniuc" title="Code">💻</a></td>
</tr>
</table>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -27,11 +27,3 @@ export default resolver.pipe(resolver.zod(Login), async ({email, password}, ctx)
return user
})
export const config = {
api: {
bodyParser: {
sizeLimit: "2mb",
},
},
}

View File

@@ -1,4 +1,4 @@
import {z} from "zod"
import * as z from "zod"
const password = z.string().min(10).max(100)

View File

@@ -1,7 +1,6 @@
import React, {ReactNode, PropsWithoutRef} from "react"
import {Form as FinalForm, FormProps as FinalFormProps} from "react-final-form"
import {z} from "zod"
import {validateZodSchema} from "blitz"
import * as z from "zod"
export {FORM_ERROR} from "final-form"
export interface FormProps<S extends z.ZodType<any, any>>
@@ -26,7 +25,14 @@ export function Form<S extends z.ZodType<any, any>>({
return (
<FinalForm
initialValues={initialValues}
validate={validateZodSchema(schema)}
validate={(values) => {
if (!schema) return
try {
schema.parse(values)
} catch (error) {
return error.formErrors.fieldErrors
}
}}
onSubmit={onSubmit}
render={({handleSubmit, submitting, submitError}) => (
<form onSubmit={handleSubmit} className="form" {...props}>

View File

@@ -1,22 +1,28 @@
import {
AppProps,
ErrorBoundary,
ErrorComponent,
useRouter,
AuthenticationError,
AuthorizationError,
ErrorFallbackProps,
useQueryErrorResetBoundary,
} from "blitz"
import {ErrorBoundary} from "react-error-boundary"
import LoginForm from "app/auth/components/LoginForm"
import {ReactQueryDevtools} from "react-query/devtools"
export default function App({Component, pageProps}: AppProps) {
const getLayout = Component.getLayout || ((page) => page)
const router = useRouter()
const {reset} = useQueryErrorResetBoundary()
return (
<>
<ErrorBoundary FallbackComponent={RootErrorFallback} onReset={reset}>
<ErrorBoundary
FallbackComponent={RootErrorFallback}
resetKeys={[router.asPath]}
onReset={reset}
>
{getLayout(<Component {...pageProps} />)}
</ErrorBoundary>
<ReactQueryDevtools />

View File

@@ -10,14 +10,7 @@ import {Routes} from ".blitz"
export const EditProject = () => {
const router = useRouter()
const projectId = useParam("projectId", "number")
const [project, {setQueryData}] = useQuery(
getProject,
{id: projectId},
{
// This ensures the query never refreshes and overwrites the form data while the user is editing.
staleTime: Infinity,
},
)
const [project, {setQueryData}] = useQuery(getProject, {id: projectId})
const [updateProjectMutation] = useMutation(updateProject)
return (

View File

@@ -23,7 +23,7 @@ const NewProjectPage: BlitzPage = () => {
onSubmit={async (values) => {
try {
const project = await createProjectMutation(values)
router.push(Routes.ShowProjectPage({projectId: project.id}))
router.push(`/projects/${project.id}`)
} catch (error) {
console.error(error)
return {

View File

@@ -12,8 +12,16 @@ import {
} from "blitz"
import getUser from "app/users/queries/getUser"
import logout from "app/auth/mutations/logout"
import path from "path"
export const getServerSideProps: GetServerSideProps = async ({req, res}) => {
// Ensure these files are not eliminated by trace-based tree-shaking (like Vercel)
// https://github.com/blitz-js/blitz/issues/794
path.resolve("next.config.js")
path.resolve("blitz.config.js")
path.resolve(".next/blitz/db.js")
// End anti-tree-shaking
const session = await getSession(req, res)
console.log("Session id:", session.userId)
try {

View File

@@ -1,9 +1,9 @@
import {Form, FormProps} from "app/core/components/Form"
import {LabeledTextField} from "app/core/components/LabeledTextField"
import {ZodType} from "zod"
import * as z from "zod"
export {FORM_ERROR} from "app/core/components/Form"
export function ProjectForm<S extends ZodType<any, any>>(props: FormProps<S>) {
export function ProjectForm<S extends z.ZodType<any, any>>(props: FormProps<S>) {
return (
<Form<S> {...props}>
<LabeledTextField name="name" label="Name" placeholder="Name" />

View File

@@ -1,10 +1,12 @@
import {resolver} from "blitz"
import db from "db"
import {z} from "zod"
import * as z from "zod"
const CreateProject = z.object({
name: z.string(),
})
const CreateProject = z
.object({
name: z.string(),
})
.nonstrict()
export default resolver.pipe(resolver.zod(CreateProject), resolver.authorize(), async (input) => {
// TODO: in multi-tenant app, you must add validation to ensure correct tenant

View File

@@ -1,10 +1,12 @@
import {resolver} from "blitz"
import db from "db"
import {z} from "zod"
import * as z from "zod"
const DeleteProject = z.object({
id: z.number(),
})
const DeleteProject = z
.object({
id: z.number(),
})
.nonstrict()
export default resolver.pipe(resolver.zod(DeleteProject), resolver.authorize(), async ({id}) => {
// TODO: in multi-tenant app, you must add validation to ensure correct tenant

View File

@@ -1,11 +1,13 @@
import {resolver} from "blitz"
import db from "db"
import {z} from "zod"
import * as z from "zod"
const UpdateProject = z.object({
id: z.number(),
name: z.string(),
})
const UpdateProject = z
.object({
id: z.number(),
name: z.string(),
})
.nonstrict()
export default resolver.pipe(
resolver.zod(UpdateProject),

View File

@@ -1,6 +1,6 @@
import {resolver, NotFoundError} from "blitz"
import db from "db"
import {z} from "zod"
import * as z from "zod"
const GetProject = z.object({
// This accepts type of undefined, but is required at runtime

View File

@@ -0,0 +1,37 @@
const {sessionMiddleware, simpleRolesIsAuthorized} = require("blitz")
const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
})
module.exports = withBundleAnalyzer({
middleware: [
sessionMiddleware({
isAuthorized: simpleRolesIsAuthorized,
// sessionExpiryMinutes: 4,
}),
],
cli: {
clearConsoleOnBlitzDev: false,
},
log: {
// level: "trace",
},
experimental: {
initServer() {
console.log("Hello world from initServer")
},
},
/*
webpack: (config, {buildId, dev, isServer, defaultLoaders, webpack}) => {
// Note: we provide webpack above so you should not `require` it
// Perform customizations to webpack config
// Important: return the modified config
return config
},
webpackDevMiddleware: (config) => {
// Perform customizations to webpack dev middleware config
// Important: return the modified config
return config
},
*/
})

View File

@@ -1,40 +0,0 @@
import {sessionMiddleware, simpleRolesIsAuthorized} from "blitz"
import db from "db"
const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
})
module.exports = withBundleAnalyzer({
middleware: [
sessionMiddleware({
cookiePrefix: "blitz-auth-example",
isAuthorized: simpleRolesIsAuthorized,
// sessionExpiryMinutes: 4,
getSession: (handle) => db.session.findFirst({where: {handle}}),
}),
],
cli: {
clearConsoleOnBlitzDev: false,
},
log: {
// level: "trace",
},
experimental: {
initServer() {
console.log("Hello world from initServer")
},
},
/*
webpack: (config, {buildId, dev, isServer, defaultLoaders, webpack}) => {
// Note: we provide webpack above so you should not `require` it
// Perform customizations to webpack config
// Important: return the modified config
return config
},
webpackDevMiddleware: (config) => {
// Perform customizations to webpack dev middleware config
// Important: return the modified config
return config
},
*/
})

View File

@@ -28,16 +28,18 @@
"trailingComma": "all"
},
"dependencies": {
"@prisma/client": "2.24.1",
"blitz": "0.38.3-canary.1",
"@prisma/client": "2.19.0",
"blitz": "0.35.0-canary.0",
"final-form": "4.20.1",
"passport-auth0": "1.4.0",
"passport-github2": "0.1.12",
"passport-twitter": "1.0.4",
"prisma": "2.24.1",
"react": "18.0.0-alpha-ed6c091fe-20210701",
"react-dom": "18.0.0-alpha-ed6c091fe-20210701",
"react-final-form": "6.5.2"
"prisma": "2.19.0",
"react": "0.0.0-experimental-6a589ad71",
"react-dom": "0.0.0-experimental-6a589ad71",
"react-error-boundary": "3.1.1",
"react-final-form": "6.5.2",
"zod": "1.11.11"
},
"devDependencies": {
"@cypress/skip-test": "2.6.0",
@@ -48,7 +50,7 @@
"@types/passport-github2": "1.2.4",
"@types/passport-twitter": "1.0.36",
"@types/preview-email": "2.0.0",
"@types/react": "17.0.13",
"@types/react": "17.0.2",
"cross-env": "7.0.3",
"cypress": "6.2.1",
"eslint": "7.21.0",
@@ -57,7 +59,8 @@
"prettier": "2.2.1",
"pretty-quick": "3.1.0",
"preview-email": "3.0.3",
"start-server-and-test": "1.11.7"
"start-server-and-test": "1.11.7",
"typescript": "4.1.5"
},
"private": true
}

View File

@@ -1,4 +1,4 @@
import {z} from "zod"
import * as z from "zod"
export const SignupInput = z.object({
email: z.string().email(),

View File

@@ -1,7 +1,6 @@
import React, {ReactNode, PropsWithoutRef} from "react"
import {Form as FinalForm, FormProps as FinalFormProps} from "react-final-form"
import {z} from "zod"
import {validateZodSchema} from "blitz"
import * as z from "zod"
export {FORM_ERROR} from "final-form"
type FormProps<S extends z.ZodType<any, any>> = {
@@ -25,7 +24,14 @@ export function Form<S extends z.ZodType<any, any>>({
return (
<FinalForm
initialValues={initialValues}
validate={validateZodSchema(schema)}
validate={(values) => {
if (!schema) return
try {
schema.parse(values)
} catch (error) {
return error.formErrors.fieldErrors
}
}}
onSubmit={onSubmit}
render={({handleSubmit, submitting, submitError}) => (
<form onSubmit={handleSubmit} className="form" {...props}>

View File

@@ -1,26 +1,31 @@
import {
AppProps,
ErrorBoundary,
ErrorFallbackProps,
ErrorComponent,
useRouter,
AuthenticationError,
AuthorizationError,
useQueryErrorResetBoundary,
} from "blitz"
import {ErrorBoundary, FallbackProps} from "react-error-boundary"
import LoginForm from "app/auth/components/LoginForm"
export default function App({Component, pageProps}: AppProps) {
const getLayout = Component.getLayout || ((page) => page)
const router = useRouter()
const {reset} = useQueryErrorResetBoundary()
return (
<ErrorBoundary FallbackComponent={RootErrorFallback} onReset={reset}>
<ErrorBoundary
FallbackComponent={RootErrorFallback}
resetKeys={[router.asPath]}
onReset={reset}
>
{getLayout(<Component {...pageProps} />)}
</ErrorBoundary>
)
}
function RootErrorFallback({error, resetErrorBoundary}: ErrorFallbackProps) {
function RootErrorFallback({error, resetErrorBoundary}: FallbackProps) {
if (error instanceof AuthenticationError) {
return <LoginForm onSuccess={resetErrorBoundary} />
} else if (error instanceof AuthorizationError) {

View File

@@ -3,7 +3,6 @@ const {sessionMiddleware, simpleRolesIsAuthorized} = require("blitz")
module.exports = {
middleware: [
sessionMiddleware({
cookiePrefix: "blitz-custom-server-example",
isAuthorized: simpleRolesIsAuthorized,
}),
],

View File

@@ -30,13 +30,11 @@ describe("index page", () => {
cy.signup(user)
cy.contains("button", "Logout").click()
cy.wait(500)
cy.contains("a", /login/i).click()
cy.contains("Email").find("input").type(user.email)
cy.contains("Password").find("input").type(user.password)
cy.contains("button", /login/i).click()
cy.wait(500)
cy.location("pathname").should("equal", "/")
cy.contains("button", "Logout")

View File

@@ -13,8 +13,7 @@
"test:migrate": "prisma generate && blitz prisma migrate deploy",
"test:jest": "jest --passWithNoTests",
"test-server": "blitz build && blitz start",
"test-run-e2e": "cross-env NODE_ENV=test PORT=3099 start-server-and-test test-server http://localhost:3099 cy-run",
"test:e2e": "yarn test-run-e2e || yarn test-run-e2e",
"test:e2e": "cross-env NODE_ENV=test PORT=3099 start-server-and-test test-server http://localhost:3099 cy-run",
"test": "run-s test:*"
},
"browserslist": [
@@ -30,20 +29,23 @@
"trailingComma": "all"
},
"dependencies": {
"@prisma/client": "2.24.1",
"blitz": "0.38.3-canary.1",
"@prisma/client": "2.19.0",
"blitz": "0.35.0-canary.0",
"final-form": "4.20.1",
"prisma": "2.24.1",
"react": "18.0.0-alpha-ed6c091fe-20210701",
"react-dom": "18.0.0-alpha-ed6c091fe-20210701",
"prisma": "2.19.0",
"react": "0.0.0-experimental-6a589ad71",
"react-dom": "0.0.0-experimental-6a589ad71",
"react-error-boundary": "3.1.1",
"react-final-form": "6.5.2",
"secure-password": "4.0.0"
"secure-password": "4.0.0",
"typescript": "4.1.5",
"zod": "1.11.11"
},
"devDependencies": {
"@cypress/skip-test": "2.6.0",
"@testing-library/react": "11.2.5",
"@testing-library/react-hooks": "^4.0.1",
"@types/react": "17.0.13",
"@types/react": "17.0.2",
"@types/secure-password": "3.1.0",
"cypress": "6.2.1",
"eslint": "7.21.0",

View File

@@ -1,4 +1,4 @@
import { z } from "zod"
import * as z from "zod"
export const SignupInput = z.object({
email: z.string().email(),

View File

@@ -1,7 +1,6 @@
import { ReactNode, PropsWithoutRef } from "react"
import { Form as FinalForm, FormProps as FinalFormProps } from "react-final-form"
import { z } from "zod"
import { validateZodSchema } from "blitz"
import * as z from "zod"
export { FORM_ERROR } from "final-form"
type FormProps<S extends z.ZodType<any, any>> = {
@@ -25,7 +24,14 @@ export function Form<S extends z.ZodType<any, any>>({
return (
<FinalForm
initialValues={initialValues}
validate={validateZodSchema(schema)}
validate={(values) => {
if (!schema) return
try {
schema.parse(values)
} catch (error) {
return error.formErrors.fieldErrors
}
}}
onSubmit={onSubmit}
render={({ handleSubmit, submitting, submitError }) => (
<form onSubmit={handleSubmit} className="form" {...props}>

View File

@@ -1,24 +1,24 @@
import {
AppProps,
ErrorBoundary,
ErrorFallbackProps,
ErrorComponent,
useQueryErrorResetBoundary,
} from "blitz"
import { AppProps, ErrorComponent, useRouter, useQueryErrorResetBoundary } from "blitz"
import { ErrorBoundary, FallbackProps } from "react-error-boundary"
import LoginForm from "app/auth/components/LoginForm"
export default function App({ Component, pageProps }: AppProps) {
const getLayout = Component.getLayout || ((page) => page)
const router = useRouter()
const { reset } = useQueryErrorResetBoundary()
return (
<ErrorBoundary FallbackComponent={RootErrorFallback} onReset={reset}>
<ErrorBoundary
FallbackComponent={RootErrorFallback}
resetKeys={[router.asPath]}
onReset={reset}
>
{getLayout(<Component {...pageProps} />)}
</ErrorBoundary>
)
}
function RootErrorFallback({ error, resetErrorBoundary }: ErrorFallbackProps) {
function RootErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
if (error?.name === "AuthenticationError") {
return <LoginForm onSuccess={resetErrorBoundary} />
} else if (error?.name === "AuthorizationError") {

View File

@@ -20,7 +20,6 @@ const normalizeSession = (faunaSession) => {
module.exports = {
middleware: [
sessionMiddleware({
cookiePrefix: "blitz-fauna-example",
isAuthorized: simpleRolesIsAuthorized,
getSession: async (handle) => {
const { findSessionByHandle: session } = await graphQLClient.request(

View File

@@ -28,29 +28,33 @@
]
},
"dependencies": {
"blitz": "0.38.3-canary.1",
"blitz": "0.35.0-canary.0",
"final-form": "4.20.1",
"graphql": "15.5.0",
"graphql-request": "3.4.0",
"react": "18.0.0-alpha-ed6c091fe-20210701",
"react-dom": "18.0.0-alpha-ed6c091fe-20210701",
"react-final-form": "6.5.2"
"react": "0.0.0-experimental-6a589ad71",
"react-dom": "0.0.0-experimental-6a589ad71",
"react-error-boundary": "3.1.1",
"react-final-form": "6.5.2",
"secure-password": "4.0.0",
"zod": "1.11.11"
},
"devDependencies": {
"@testing-library/react": "11.2.5",
"@testing-library/react-hooks": "^4.0.1",
"@types/react": "17.0.13",
"@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",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.23.1",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-import": "~2.22.1",
"eslint-plugin-jsx-a11y": "~6.4.1",
"eslint-plugin-react": "~7.22.0",
"eslint-plugin-react-hooks": "~4.2.0",
"husky": "5.1.2",
"start-server-and-test": "1.11.7"
"start-server-and-test": "1.11.7",
"typescript": "4.1.5"
},
"private": true
}

View File

@@ -26,26 +26,27 @@
]
},
"dependencies": {
"blitz": "0.38.3-canary.1",
"blitz": "0.35.0-canary.0",
"knex": "0.21.16",
"react": "18.0.0-alpha-ed6c091fe-20210701",
"react-dom": "18.0.0-alpha-ed6c091fe-20210701",
"sqlite3": "5.0.2"
"react": "0.0.0-experimental-6a589ad71",
"react-dom": "0.0.0-experimental-6a589ad71",
"sqlite3": "5.0.0"
},
"devDependencies": {
"@types/react": "17.0.13",
"@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",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.23.1",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-import": "~2.22.1",
"eslint-plugin-jsx-a11y": "~6.4.1",
"eslint-plugin-react": "~7.22.0",
"eslint-plugin-react-hooks": "~4.2.0",
"husky": "5.1.2",
"lint-staged": "10.5.4",
"prettier": "2.2.1",
"pretty-quick": "3.1.0"
"pretty-quick": "3.1.0",
"typescript": "4.1.5"
},
"private": true
}

View File

@@ -32,25 +32,26 @@
]
},
"dependencies": {
"@prisma/client": "2.24.1",
"blitz": "0.38.3-canary.1",
"prisma": "2.24.1",
"react": "18.0.0-alpha-ed6c091fe-20210701",
"react-dom": "18.0.0-alpha-ed6c091fe-20210701"
"@prisma/client": "2.19.0",
"blitz": "0.35.0-canary.0",
"prisma": "2.19.0",
"react": "0.0.0-experimental-6a589ad71",
"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",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.23.1",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-import": "~2.22.1",
"eslint-plugin-jsx-a11y": "~6.4.1",
"eslint-plugin-react": "~7.22.0",
"eslint-plugin-react-hooks": "~4.2.0",
"husky": "5.1.2",
"lint-staged": "10.5.4",
"prettier": "2.2.1",
"pretty-quick": "3.1.0"
"pretty-quick": "3.1.0",
"typescript": "4.1.5"
},
"private": true
}

View File

@@ -1,17 +1,23 @@
import {
AppProps,
ErrorBoundary,
ErrorComponent,
useRouter,
ErrorFallbackProps,
useQueryErrorResetBoundary,
} from "blitz"
import { ErrorBoundary } from "react-error-boundary"
export default function App({ Component, pageProps }: AppProps) {
const getLayout = Component.getLayout || ((page) => page)
const router = useRouter()
const { reset } = useQueryErrorResetBoundary()
return (
<ErrorBoundary FallbackComponent={RootErrorFallback} onReset={reset}>
<ErrorBoundary
FallbackComponent={RootErrorFallback}
resetKeys={[router.asPath]}
onReset={reset}
>
{getLayout(<Component {...pageProps} />)}
</ErrorBoundary>
)

View File

@@ -32,17 +32,20 @@
]
},
"dependencies": {
"@prisma/client": "2.24.1",
"blitz": "0.38.3-canary.1",
"@prisma/client": "2.19.0",
"blitz": "0.35.0-canary.0",
"final-form": "4.20.1",
"prisma": "2.24.1",
"react": "18.0.0-alpha-ed6c091fe-20210701",
"react-dom": "18.0.0-alpha-ed6c091fe-20210701",
"react-final-form": "6.5.2"
"prisma": "2.19.0",
"react": "0.0.0-experimental-6a589ad71",
"react-dom": "0.0.0-experimental-6a589ad71",
"react-error-boundary": "3.1.1",
"react-final-form": "6.5.2",
"typescript": "4.1.5",
"zod": "1.11.11"
},
"devDependencies": {
"@types/preview-email": "2.0.0",
"@types/react": "17.0.13",
"@types/react": "17.0.2",
"eslint": "7.21.0",
"husky": "5.1.2",
"lint-staged": "10.5.4",

View File

@@ -0,0 +1,3 @@
module.exports = {
extends: ["blitz"],
}

View File

@@ -1,5 +1,13 @@
import db from "db"
import db, {Product} from "db"
import {BlitzApiRequest, BlitzApiResponse} from "blitz"
import {mean} from "lodash"
// this is here mainly as an integration test for
// importing from api/
export function meanPrice(products: Product[]) {
const prices = products.map((p) => p.price).filter((p) => !!p) as number[]
return mean(prices)
}
export default async function users(_req: BlitzApiRequest, res: BlitzApiResponse) {
const products = await db.product.findMany()

View File

@@ -1,15 +1,7 @@
import {Suspense, useState} from "react"
import {useQuery, Link, useRouterQuery, invalidateQuery, setQueryData} from "blitz"
import getProducts from "app/products/queries/getProducts"
import {mean} from "lodash"
import {Product} from "@prisma/client"
// this is here mainly as an integration test for
// importing from api/
export function meanPrice(products: Product[]) {
const prices = products.map((p) => p.price).filter((p) => !!p) as number[]
return mean(prices)
}
import {meanPrice} from "app/admin/api/users"
function reversedProductList(productsList) {
return {...productsList, products: [...productsList.products].reverse()}

View File

@@ -1,4 +1,5 @@
import {AppProps, ErrorBoundary, ErrorComponent, useQueryErrorResetBoundary} from "blitz"
import {AppProps, ErrorComponent, useQueryErrorResetBoundary} from "blitz"
import {ErrorBoundary} from "react-error-boundary"
if (typeof window !== "undefined") {
window["DEBUG_BLITZ"] = 1

View File

@@ -1,17 +1,10 @@
import {Link, BlitzPage, InferGetStaticPropsType} from "blitz"
import getProducts from "../../queries/getProducts"
import {sum} from "lodash"
import {Product} from "@prisma/client"
import getProducts, {averagePrice} from "../../queries/getProducts"
// regression test for #1646
import {getMeSomeQualityHumor} from "../../api"
console.log("Attention! Must read: " + getMeSomeQualityHumor())
export function averagePrice(products: Product[]) {
const prices = products.map((p) => p.price ?? 0)
return sum(prices) / prices.length
}
export const getStaticProps = async () => {
const {products} = await getProducts({orderBy: {id: "desc"}})
return {

View File

@@ -1,5 +1,11 @@
import {Middleware, paginate} from "blitz"
import db, {Prisma} from "db"
import db, {Prisma, Product} from "db"
import {sum} from "lodash"
export function averagePrice(products: Product[]) {
const prices = products.map((p) => p.price ?? 0)
return sum(prices) / prices.length
}
type GetProductsInput = {
where?: Prisma.ProductFindManyArgs["where"]

View File

@@ -20,17 +20,20 @@
"trailingComma": "all"
},
"dependencies": {
"@prisma/client": "2.24.1",
"blitz": "0.38.3-canary.1",
"@prisma/client": "2.19.0",
"blitz": "0.35.0-canary.0",
"final-form": "4.20.1",
"prisma": "2.24.1",
"react": "18.0.0-alpha-ed6c091fe-20210701",
"react-dom": "18.0.0-alpha-ed6c091fe-20210701",
"react-final-form": "6.5.2"
"prisma": "2.19.0",
"react": "0.0.0-experimental-6a589ad71",
"react-dom": "0.0.0-experimental-6a589ad71",
"react-error-boundary": "3.1.1",
"react-final-form": "6.5.2",
"typescript": "4.1.5"
},
"devDependencies": {
"@types/react": "17.0.13",
"@types/react": "17.0.2",
"cypress": "6.2.1",
"eslint-plugin-cypress": "~2.11.2",
"start-server-and-test": "1.11.7"
}
}

View File

@@ -1,5 +1,5 @@
{
"version": "0.38.3-canary.1",
"version": "0.35.0-canary.0",
"packages": ["packages/*"],
"npmClient": "yarn",
"useWorkspaces": true,

View File

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

View File

@@ -2,8 +2,6 @@ node_modules
**/.next/**
**/_next/**
**/dist/**
e2e-tests/**
examples/with-eslint/**
examples/with-typescript-eslint-jest/**
examples/with-kea/**
packages/next/bundles/webpack/packages/*.runtime.js
@@ -17,7 +15,5 @@ packages/next-codemod/transforms/__tests__/**/*
packages/next-codemod/**/*.js
packages/next-codemod/**/*.d.ts
packages/next-env/**/*.d.ts
packages/create-next-app/templates/**
test/integration/async-modules/**
test/integration/eslint/**
test-timings.json
test-timings.json

View File

@@ -27,10 +27,7 @@
"extends": ["plugin:jest/recommended"],
"rules": {
"jest/expect-expect": "off",
"jest/no-disabled-tests": "off",
"jest/no-conditional-expect": "off",
"jest/valid-title": "off",
"jest/no-interpolation-in-snapshots": "off"
"jest/no-disabled-tests": "off"
}
},
{ "files": ["**/__tests__/**"], "env": { "jest": true } },
@@ -120,7 +117,7 @@
"rules": {
"no-shadow": ["warn", { "builtinGlobals": false }],
"import/no-extraneous-dependencies": [
"off",
"error",
{ "devDependencies": false }
]
}

View File

@@ -1,6 +1,8 @@
name: Bug Report
description: Create a bug report for the Next.js core
about: Create a bug report for the Next.js core
title: ''
labels: 'template: bug'
issue_body: true
body:
- type: markdown
attributes:

View File

@@ -1,6 +1,8 @@
name: Example Bug Report
description: Create a bug report for the examples
about: Create a bug report for the examples
title: ''
labels: 'type: example,template: bug'
issue_body: true
body:
- type: markdown
attributes:

View File

@@ -1,6 +1,8 @@
name: Feature Request
description: Create a feature request for the Next.js core
about: Create a feature request for the Next.js core
title: ''
labels: 'template: story'
issue_body: true
body:
- type: markdown
attributes:

View File

@@ -1,8 +1,8 @@
FROM node:14-buster
FROM node:10-buster
LABEL com.github.actions.name="Next.js PR Stats"
LABEL com.github.actions.description="Compares stats of a PR with the main branch"
LABEL repository="https://github.com/vercel/next-stats-action"
LABEL repository="https://github.com/zeit/next-stats-action"
COPY . /next-stats

View File

@@ -83,7 +83,7 @@ module.exports = async function addComment(
else if (!isGzipItem && !groupKey.match(gzipIgnoreRegex)) return
if (
!itemKey.startsWith('buildDuration') ||
itemKey !== 'buildDuration' ||
(isBenchmark && itemKey.match(/req\/sec/))
) {
if (typeof mainItemVal === 'number') mainRepoTotal += mainItemVal

View File

@@ -26,7 +26,6 @@ async function runConfigs(
let curStats = {
General: {
buildDuration: null,
buildDurationCached: null,
nodeModulesSize: null,
},
}
@@ -56,25 +55,20 @@ async function runConfigs(
)
}
const buildStart = Date.now()
const buildStart = new Date().getTime()
await exec(`cd ${statsAppDir} && ${statsConfig.appBuildCommand}`, false, {
env: yarnEnvValues,
})
curStats.General.buildDuration = Date.now() - buildStart
curStats.General.buildDuration = new Date().getTime() - buildStart
// apply renames to get deterministic output names
for (const rename of config.renames) {
const results = await glob(rename.srcGlob, { cwd: statsAppDir })
for (const result of results) {
let dest = rename.removeHash
? result.replace(/(\.|-)[0-9a-f]{20}(\.|-)/g, '$1HASH$2')
: rename.dest
if (result === dest) continue
await fs.move(
path.join(statsAppDir, result),
path.join(statsAppDir, dest)
)
}
if (results.length === 0 || results[0] === rename.dest) continue
await fs.move(
path.join(statsAppDir, results[0]),
path.join(statsAppDir, rename.dest)
)
}
const collectedStats = await collectStats(config, statsConfig)
@@ -86,17 +80,19 @@ async function runConfigs(
const applyRenames = (renames, stats) => {
if (renames) {
for (const rename of renames) {
let { cur, prev } = rename
cur = path.basename(cur)
prev = path.basename(prev)
Object.keys(stats).forEach((group) => {
if (stats[group][cur]) {
stats[group][prev] = stats[group][cur]
stats[group][prev + ' gzip'] = stats[group][cur + ' gzip']
delete stats[group][cur]
delete stats[group][cur + ' gzip']
}
Object.keys(stats[group]).forEach((item) => {
let { cur, prev } = rename
cur = path.basename(cur)
prev = path.basename(prev)
if (cur === item) {
stats[group][prev] = stats[group][item]
stats[group][prev + ' gzip'] = stats[group][item + ' gzip']
delete stats[group][item]
delete stats[group][item + ' gzip']
}
})
})
}
}
@@ -150,12 +146,6 @@ async function runConfigs(
/* eslint-disable-next-line */
mainRepoStats = curStats
}
const secondBuildStart = Date.now()
await exec(`cd ${statsAppDir} && ${statsConfig.appBuildCommand}`, false, {
env: yarnEnvValues,
})
curStats.General.buildDurationCached = Date.now() - secondBuildStart
}
logger(`Finished running: ${config.title}`)

View File

@@ -8,14 +8,6 @@
"packages/react-dev-overlay/**",
"packages/react-refresh-utils/**",
"packages/next-codemod/**"
],
"type: chrome": [
{ "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" }
]
}
}

View File

@@ -126,7 +126,7 @@ jobs:
- run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
- run: cd test/integration/with-electron/app && yarn
- run: yarn add -W --dev spectron@7.0.0 electron@5.0.0
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
- run: xvfb-run node run-tests.js test/integration/with-electron/test/index.test.js
@@ -134,20 +134,22 @@ jobs:
testYarnPnP:
runs-on: ubuntu-latest
needs: build
env:
NODE_OPTIONS: '--unhandled-rejections=strict'
YARN_COMPRESSION_LEVEL: '0'
steps:
- uses: actions/cache@v2
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
id: restore-build
- uses: actions/checkout@v2
with:
path: ./*
key: ${{ github.sha }}
fetch-depth: 25
- run: echo ::set-output name=DOCS_CHANGE::$(node skip-docs-change.js echo 'not-docs-only-change')
id: docs-change
- run: yarn install --frozen-lockfile --check-files
if: ${{steps.docs-change.outputs.DOCS_CHANGE != 'docs only change'}}
- run: bash ./test-pnp.sh
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
if: ${{steps.docs-change.outputs.DOCS_CHANGE != 'docs only change'}}
testsPass:
name: thank you, next
@@ -156,26 +158,65 @@ jobs:
steps:
- run: exit 0
testLegacyWebpack:
name: Webpack 4 (Basic, Production, Acceptance)
testFutureDependencies:
name: Webpack 5 (Basic, Production, Acceptance)
runs-on: ubuntu-latest
needs: build
env:
NEXT_TELEMETRY_DISABLED: 1
NEXT_TEST_JOB: 1
HEADLESS: true
NEXT_PRIVATE_TEST_WEBPACK4_MODE: 1
NEXT_PRIVATE_TEST_WEBPACK5_MODE: 1
steps:
- uses: actions/cache@v2
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
id: restore-build
- uses: actions/checkout@v2
with:
path: ./*
key: ${{ github.sha }}
fetch-depth: 25
- run: xvfb-run node run-tests.js test/integration/{basic,fallback-modules,link-ref,production,async-modules,font-optimization,ssr-ctx}/test/index.test.js test/acceptance/*.test.js
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
- run: echo ::set-output name=DOCS_CHANGE::$(node skip-docs-change.js echo 'not-docs-only-change')
id: docs-change
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: yarn install --check-files
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: xvfb-run node run-tests.js test/integration/{fallback-modules,link-ref,production,basic,async-modules,font-optimization,ssr-ctx}/test/index.test.js test/acceptance/*.test.js
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
testLegacyReact:
name: React 16 + Webpack 4 (Basic, Production, Acceptance)
runs-on: ubuntu-latest
env:
NEXT_TELEMETRY_DISABLED: 1
NEXT_TEST_JOB: 1
HEADLESS: true
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 25
- run: echo ::set-output name=DOCS_CHANGE::$(node skip-docs-change.js echo 'not-docs-only-change')
id: docs-change
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: cat package.json | jq '.resolutions.react = "^16.14.0"' > package.json.tmp && mv package.json.tmp package.json
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: cat package.json | jq '.resolutions."react-dom" = "^16.14.0"' > package.json.tmp && mv package.json.tmp package.json
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: yarn install --check-files
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: yarn list react react-dom
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
- run: xvfb-run node run-tests.js test/integration/{link-ref,production,basic,async-modules,font-optimization,ssr-ctx,worker-loader}/test/index.test.js test/acceptance/*.test.js
if: ${{ steps.docs-change.outputs.DOCS_CHANGE != 'docs only change' }}
testFirefox:
name: Test Firefox (production)
@@ -183,7 +224,7 @@ jobs:
needs: build
env:
HEADLESS: true
BROWSER_NAME: 'firefox'
BROWSERNAME: 'firefox'
NEXT_TELEMETRY_DISABLED: 1
steps:
- uses: actions/cache@v2
@@ -192,7 +233,7 @@ jobs:
with:
path: ./*
key: ${{ github.sha }}
- run: node run-tests.js -c 1 test/integration/production/test/index.test.js
- run: node run-tests.js test/integration/production/test/index.test.js
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testSafari:
@@ -201,7 +242,7 @@ jobs:
needs: build
env:
BROWSERSTACK: true
BROWSER_NAME: 'safari'
BROWSERNAME: 'safari'
NEXT_TELEMETRY_DISABLED: 1
SKIP_LOCAL_SELENIUM_SERVER: true
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
@@ -213,7 +254,7 @@ jobs:
with:
path: ./*
key: ${{ github.sha }}
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js -c 1 test/integration/production/test/index.test.js'
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js test/integration/production/test/index.test.js'
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testSafariOld:
@@ -223,7 +264,7 @@ jobs:
env:
BROWSERSTACK: true
LEGACY_SAFARI: true
BROWSER_NAME: 'safari'
BROWSERNAME: 'safari'
NEXT_TELEMETRY_DISABLED: 1
SKIP_LOCAL_SELENIUM_SERVER: true
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
@@ -235,7 +276,7 @@ jobs:
with:
path: ./*
key: ${{ github.sha }}
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js -c 1 test/integration/production-nav/test/index.test.js'
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js test/integration/production-nav/test/index.test.js'
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
publishRelease:

View File

@@ -1,3 +1,8 @@
on:
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '0 0,12 * * *'
name: Test react@next
jobs:
@@ -25,8 +30,6 @@ jobs:
env:
NEXT_TELEMETRY_DISABLED: 1
HEADLESS: true
NEXT_PRIVATE_SKIP_SIZE_TESTS: true
NEXT_PRIVATE_REACT_ROOT: 1
strategy:
fail-fast: false
matrix:

View File

@@ -6,7 +6,7 @@
[subrepo]
remote = git@github.com:blitz-js/next.js.git
branch = canary
commit = 4be32b7a54fa68dfcf66d4a5cc7744409c409c7f
parent = 194a3720ce56aa3fabace4b07c5faeac1121b8d6
commit = 6335b669d4b26fad6814edc939896b072429534c
parent = 6df0db9b8714faa5518303989735f4bca1086da1
method = merge
cmdver = 0.4.3

View File

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

View File

@@ -12,7 +12,6 @@
"runtimeExecutable": "yarn",
"runtimeArgs": ["run", "debug", "dev", "test/integration/basic"],
"skipFiles": ["<node_internals>/**"],
"outFiles": ["${workspaceFolder}/packages/next/dist/**/*"],
"port": 9229
},
{

View File

@@ -34,7 +34,7 @@ pr:
variables:
YARN_CACHE_FOLDER: $(Pipeline.Workspace)/.yarn
NEXT_TELEMETRY_DISABLED: '1'
node_version: ^12.0.0
node_version: ^10.10.0
stages:
- stage: Build
@@ -69,7 +69,7 @@ stages:
- stage: Test
dependsOn: Build
jobs:
- job: test_ie11
- job: test_ie11_production
pool:
vmImage: 'windows-2019'
steps:
@@ -86,7 +86,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/
yarn testie --forceExit test/integration/production/
displayName: 'Run tests'
- job: test_unit
@@ -117,13 +117,13 @@ stages:
vmImage: 'windows-2019'
strategy:
matrix:
nodejs-1:
node-10-1:
group: 1/4
nodejs-2:
node-10-2:
group: 2/4
nodejs-3:
node-10-3:
group: 3/4
nodejs-4:
node-10-4:
group: 4/4
steps:
- checkout: none

View File

@@ -1,5 +1,5 @@
import { createServer } from 'http'
import { writeFileSync } from 'fs'
const http = require('http')
const fs = require('fs')
const PORT = 9411
const HOST = '0.0.0.0'
@@ -53,11 +53,11 @@ const main = () => {
process.on('SIGINT', () => {
console.log(`\nSaving to ${outFile}...`)
writeFileSync(outFile, JSON.stringify(traces, null, 2))
fs.writeFileSync(outFile, JSON.stringify(traces, null, 2))
process.exit()
})
const server = createServer(onRequest)
const server = http.createServer(onRequest)
server.listen(PORT, HOST, onReady)
}

View File

@@ -8,7 +8,7 @@
"bench:recursive-copy": "node recursive-copy/run"
},
"dependencies": {
"fs-extra": "10.0.0",
"recursive-copy": "2.0.11"
"fs-extra": "7.0.1",
"recursive-copy": "2.0.10"
}
}

View File

@@ -1,7 +1,6 @@
import { join } from 'path'
import { promisify } from 'util'
import globMod from 'glob'
const { join } = require('path')
const { promisify } = require('util')
const globMod = require('glob')
const glob = promisify(globMod)
const resolveDataDir = join(__dirname, 'fixtures', '**/*')

View File

@@ -1,5 +1,5 @@
import { join } from 'path'
import { recursiveReadDir } from 'next/dist/lib/recursive-readdir'
const { join } = require('path')
const { recursiveReadDir } = require('next/dist/lib/recursive-readdir')
const resolveDataDir = join(__dirname, 'fixtures')
async function test() {

View File

@@ -1,14 +1,18 @@
import { join } from 'path'
import { ensureDir, outputFile, remove } from 'fs-extra'
import recursiveCopyNpm from 'recursive-copy'
import { recursiveCopy as recursiveCopyCustom } from 'next/dist/lib/recursive-copy'
const { join } = require('path')
const fs = require('fs-extra')
const recursiveCopyNpm = require('recursive-copy')
const {
recursiveCopy: recursiveCopyCustom,
} = require('next/dist/lib/recursive-copy')
const fixturesDir = join(__dirname, 'fixtures')
const srcDir = join(fixturesDir, 'src')
const destDir = join(fixturesDir, 'dest')
const createSrcFolder = async () => {
await ensureDir(srcDir)
await fs.ensureDir(srcDir)
const files = new Array(100)
.fill(undefined)
@@ -16,7 +20,7 @@ const createSrcFolder = async () => {
join(srcDir, `folder${i % 5}`, `folder${i + (1 % 5)}`, `file${i}`)
)
await Promise.all(files.map((file) => outputFile(file, 'hello')))
await Promise.all(files.map((file) => fs.outputFile(file, 'hello')))
}
async function run(fn) {
@@ -34,7 +38,7 @@ async function run(fn) {
for (let i = 0; i < 10; i++) {
const t = await test()
await remove(destDir)
await fs.remove(destDir)
ts.push(t)
}
@@ -53,7 +57,7 @@ async function main() {
console.log('test recursive-copy custom implementation')
await run(recursiveCopyCustom)
await remove(fixturesDir)
await fs.remove(fixturesDir)
}
main()

View File

@@ -1,5 +1,5 @@
import { join } from 'path'
import { recursiveDelete } from 'next/dist/lib/recursive-delete'
const { join } = require('path')
const { recursiveDelete } = require('next/dist/lib/recursive-delete')
const resolveDataDir = join(__dirname, `fixtures-${process.argv[2]}`)
async function test() {

View File

@@ -1,9 +1,8 @@
import { join } from 'path'
import { promisify } from 'util'
import rimrafMod from 'rimraf'
const rimraf = promisify(rimrafMod)
const { join } = require('path')
const { promisify } = require('util')
const rimrafMod = require('rimraf')
const resolveDataDir = join(__dirname, `fixtures-${process.argv[2]}`, '**/*')
const rimraf = promisify(rimrafMod)
async function test() {
const time = process.hrtime()

View File

@@ -1,6 +1,6 @@
# Contributing to Next.js
Read about our [Commitment to Open Source](https://vercel.com/oss).
Our Commitment to Open Source can be found [here](https://vercel.com/oss).
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device.
2. Create a new branch: `git checkout -b MY_BRANCH_NAME`
@@ -46,7 +46,7 @@ Running a specific test suite inside of the `test/integration` directory:
yarn testonly --testPathPattern "production"
```
Running one test in the `production` test suite:
Running just one test in the `production` test suite:
```sh
yarn testonly --testPathPattern "production" -t "should allow etag header support"
@@ -124,19 +124,12 @@ When you add an example to the [examples](examples) directory, dont forget to
- To add additional installation instructions, please add it where appropriate.
- To add additional notes, add `## Notes` section at the end.
- Remove the `Deploy your own` section if your example cant be immediately deployed to Vercel.
- Remove the `Preview` section if the example doesn't work on [StackBlitz](http://stackblitz.com/) and file an issue [here](https://github.com/stackblitz/webcontainer-core).
````markdown
# Example Name
Description
## Preview
Preview the example live on [StackBlitz](http://stackblitz.com/):
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/DIRECTORY_NAME)
## Deploy your own
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):

View File

@@ -6,4 +6,4 @@ description: Using AMP with TypeScript? Extend your typings to allow AMP compone
AMP currently doesn't have built-in types for TypeScript, but it's in their roadmap ([#13791](https://github.com/ampproject/amphtml/issues/13791)).
As a workaround you can manually create a file called `amp.d.ts` inside your project and add these [custom types](https://stackoverflow.com/a/50601125).
As a workaround you can manually create a file called `amp.d.ts` inside your project and add the custom types described [here](https://stackoverflow.com/a/50601125).

View File

@@ -17,14 +17,6 @@ Codemods are transformations that run on your codebase programmatically. This al
- `--dry` Do a dry-run, no code will be edited
- `--print` Prints the changed output for comparison
## Next.js 11
### `cra-to-next` (experimental)
Migrates a Create React App project to Next.js; creating a pages directory and necessary config to match behavior. Client-side only rendering is leveraged initially to prevent breaking compatibility due to `window` usage during SSR and can be enabled seamlessly to allow gradual adoption of Next.js specific features.
Please share any feedback related to this transform [in this discussion](https://github.com/vercel/next.js/discussions/25858).
## Next.js 10
### `add-missing-react-import`

View File

@@ -44,7 +44,6 @@ The `Component` prop is the active `page`, so whenever you navigate between rout
- 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.
- 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).
### TypeScript

View File

@@ -71,7 +71,7 @@ export default Home
`DynamicComponent` will be the default component returned by `../components/hello`. It works like a regular React Component, and you can pass props to it as you normally would.
> **Note**: In `import('path/to/component')`, the path must be explicitly written. It can't be a template string nor a variable. Furthermore the `import()` has to be inside the `dynamic()` call for Next.js to be able to match webpack bundles / module ids to the specific `dynamic()` call and preload them before rendering. `dynamic()` can't be used inside of React rendering as it needs to be marked in the top level of the module for preloading to work, similar to `React.lazy`.
> **Note**: `import()` needs to be explicitly written without template strings. Furthermore the `import()` has to be inside the `dynamic()` call for Next.js to be able to match webpack bundles / module ids to the specific `dynamic()` call and preload them before rendering. `dynamic()` can't be used inside of React rendering as it needs to be marked in the top level of the module for preloading to work, similar to `React.lazy`.
## With named exports

View File

@@ -13,7 +13,7 @@ description: Next.js has built-in support for internationalized routing and lang
Next.js has built-in support for internationalized ([i18n](https://en.wikipedia.org/wiki/Internationalization_and_localization#Naming)) routing since `v10.0.0`. You can provide a list of locales, the default locale, and domain-specific locales and Next.js will automatically handle the routing.
The i18n routing support is currently meant to complement existing i18n library solutions like [`react-intl`](https://formatjs.io/docs/getting-started/installation), [`react-i18next`](https://react.i18next.com/), [`lingui`](https://lingui.js.org/), [`rosetta`](https://github.com/lukeed/rosetta), [`next-intl`](https://github.com/amannn/next-intl) and others by streamlining the routes and locale parsing.
The i18n routing support is currently meant to complement existing i18n library solutions like `react-intl`, `react-i18next`, `lingui`, `rosetta`, and others by streamlining the routes and locale parsing.
## Getting started
@@ -52,9 +52,6 @@ module.exports = {
{
domain: 'example.fr',
defaultLocale: 'fr',
// an optional http field can also be used to test
// locale domains locally with http instead of https
http: true,
},
],
},

View File

@@ -175,7 +175,7 @@ export function reportWebVitals(metric) {
> }
> ```
>
> Read more about [sending results to Google Analytics](https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics).
> Read more about sending results to Google Analytics [here](https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics).
## TypeScript

View File

@@ -9,19 +9,19 @@ description: Next.js has the preview mode for statically generated pages. You ca
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-wordpress">WordPress Example</a> (<a href="https://next-blog-wordpress.vercel.app">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-datocms">DatoCMS Example</a> (<a href="https://next-blog-datocms.vercel.app/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-takeshape">TakeShape Example</a> (<a href="https://next-blog-takeshape.vercel.app/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-sanity">Sanity Example</a> (<a href="https://next-blog-sanity.vercel.app/">Demo</a>)</li>
<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-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>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-storyblok">Storyblok Example</a> (<a href="https://next-blog-storyblok.vercel.app/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-graphcms">GraphCMS Example</a> (<a href="https://next-blog-graphcms.vercel.app/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-wordpress">WordPress Example</a> (<a href="https://next-blog-wordpress.now.sh">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-datocms">DatoCMS Example</a> (<a href="https://next-blog-datocms.now.sh/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-takeshape">TakeShape Example</a> (<a href="https://next-blog-takeshape.now.sh/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-sanity">Sanity Example</a> (<a href="https://next-blog-sanity.now.sh/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-prismic">Prismic Example</a> (<a href="https://next-blog-prismic.now.sh/">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.now.sh/">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.now.sh/">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.now.sh/">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.now.sh/">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.now.sh/">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.now.sh/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-storyblok">Storyblok Example</a> (<a href="https://next-blog-storyblok.now.sh/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-graphcms">GraphCMS Example</a> (<a href="https://next-blog-graphcms.now.sh/">Demo</a>)</li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-kontent">Kontent Example</a> (<a href="https://next-blog-kontent.vercel.app//">Demo</a>)</li>
</ul>
</details>
@@ -222,8 +222,6 @@ export default function myApiRoute(req, res) {
Both the bypass cookie value and the private key for encrypting the `previewData` change when `next build` is completed.
This ensures that the bypass cookie cant be guessed.
> **Note:** To test Preview Mode locally over HTTP your browser will need to allow third-party cookies and local storage access.
## Learn more
The following pages might also be useful.

View File

@@ -1,139 +0,0 @@
---
description: Improve the security of your Next.js application by adding HTTP response headers.
---
# Security Headers
To improve the security of your application, you can use [`headers`](/docs/api-reference/next.config.js/headers.md) in `next.config.js` to apply HTTP response headers to all routes in your application.
```jsx
// next.config.js
// You can choose which headers to add to the list
// after learning more below.
const securityHeaders = []
module.exports = {
async headers() {
return [
{
// Apply these headers to all routes in your application.
source: '/(.*)',
headers: securityHeaders,
},
]
},
}
```
## Options
### [X-DNS-Prefetch-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control)
This header controls DNS prefetching, allowing browsers to proactively perform domain name resolution on external links, images, CSS, JavaScript, and more. This prefetching is performed in the background, so the [DNS](https://developer.mozilla.org/en-US/docs/Glossary/DNS) is more likely to be resolved by the time the referenced items are needed. This reduces latency when the user clicks a link.
```jsx
{
key: 'X-DNS-Prefetch-Control',
value: 'on'
}
```
### [Strict-Transport-Security](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security)
This header informs browsers it should only be accessed using HTTPS, instead of using HTTP. Using the configuration below, all present and future subdomains will use HTTPS for a `max-age` of 2 years. This blocks access to pages or subdomains that can only be served over HTTP.
If you're deploying to [Vercel](https://vercel.com/docs/edge-network/headers#strict-transport-security), this header is not necessary as it's automatically added to all deployments.
```jsx
{
key: 'Strict-Transport-Security',
value: 'max-age=31536000; includeSubDomains; preload'
}
```
### [X-XSS-Protection](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection)
This header stops pages from loading when they detect reflected cross-site scripting (XSS) attacks. Although this protection is not necessary when sites implement a strong [`Content-Security-Policy`](#content-security-policy) disabling the use of inline JavaScript (`'unsafe-inline'`), it can still provide protection for older web browsers that don't support CSP.
```jsx
{
key: 'X-XSS-Protection',
value: '1; mode=block'
}
```
### [X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options)
This header indicates whether the site should be allowed to be displayed within an `iframe`. This can prevent against clickjacking attacks. This header has been superseded by CSP's `frame-ancestors` option, which has better support in modern browsers.
```jsx
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN'
}
```
### [Permissions-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy)
This header allows you to control which features and APIs can be used in the browser. It was previously named `Feature-Policy`. You can view the full list of permission options [here](https://www.w3.org/TR/permissions-policy-1/).
```jsx
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=(), interest-cohort=()'
}
```
### [X-Content-Type-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options)
This header prevents the browser from attempting to guess the type of content if the `Content-Type` header is not explicitly set. This can prevent XSS exploits for websites that allow users to upload and share files. For example, a user trying to download an image, but having it treated as a different `Content-Type` like an executable, which could be malicious. This header also applies to downloading browser extensions. The only valid value for this header is `nosniff`.
```jsx
{
key: 'X-Content-Type-Options',
value: 'nosniff'
}
```
### [Referrer-Policy](https://scotthelme.co.uk/a-new-security-header-referrer-policy/)
This header controls how much information the browser includes when navigating from the current website (origin) to another. You can read about the different options [here](https://scotthelme.co.uk/a-new-security-header-referrer-policy/).
```jsx
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin'
}
```
### [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)
This header helps prevent cross-site scripting (XSS), clickjacking and other code injection attacks. Content Security Policy (CSP) can specify allowed origins for content including scripts, stylesheets, images, fonts, objects, media (audio, video), iframes, and more.
You can read about the many different CSP options [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP).
```jsx
{
key: 'Content-Security-Policy',
value: // Your CSP Policy
}
```
### References
- [MDN](https://developer.mozilla.org)
- [Varun Naik](https://blog.vnaik.com/posts/web-attacks.html)
- [Scott Helme](https://scotthelme.co.uk)
- [Mozilla Observatory](https://observatory.mozilla.org/)
## Related
For more information, we recommend the following sections:
<div class="card">
<a href="/docs/api-reference/next.config.js/headers.md">
<b>Headers:</b>
<small>Add custom HTTP headers to your Next.js app.</small>
</a>
</div>

View File

@@ -21,7 +21,7 @@ Usage
$ next <command>
Available commands
build, start, export, dev, lint, telemetry
build, start, export, dev, telemetry
Options
--version, -v Version number
@@ -74,20 +74,6 @@ The application will start at `http://localhost:3000` by default. The default po
npx next dev -p 4000
```
Or using the `PORT` environment variable:
```bash
PORT=4000 npx next dev
```
> Note: `PORT` can not be set in `.env` as booting up the HTTP server happens before any other code is initialized.
You can also set the hostname to be different from the default of `0.0.0.0`, this can be useful for making the application available for other devices on the network. The default hostname can be changed with `-H`, like so:
```bash
npx next dev -H 192.168.1.2
```
## Production
`next start` starts the application in production mode. The application should be compiled with [`next build`](#build) first.
@@ -98,27 +84,6 @@ The application will start at `http://localhost:3000` by default. The default po
npx next start -p 4000
```
Or using the `PORT` environment variable:
```bash
PORT=4000 npx next start
```
> Note: `PORT` can not be set in `.env` as booting up the HTTP server happens before any other code is initialized.
## Lint
`next lint` runs ESLint for all files in the `pages`, `components`, and `lib` directories. It also
provides a guided setup to install any required dependencies if ESLint is not already configured in
your application.
If you have other directories that you would like to lint, you can specify them using the `--dir`
flag:
```bash
next lint --dir utils
```
## Telemetry
Next.js collects **completely anonymous** telemetry data about general usage.

View File

@@ -12,22 +12,13 @@ npx create-next-app
yarn create next-app
```
You can create a [TypeScript project](https://github.com/vercel/next.js/blob/canary/docs/basic-features/typescript.md) with the `--ts, --typescript` flag:
```bash
npx create-next-app --ts
# or
yarn create next-app --typescript
```
### Options
`create-next-app` comes with the following options:
- **--ts, --typescript** - Initialize as a TypeScript project.
- **-e, --example [name]|[github-url]** - An example to bootstrap the app with. You can use an example name from the [Next.js repo](https://github.com/vercel/next.js/tree/master/examples) or a GitHub URL. The URL can use any branch and/or subdirectory.
- **--example-path [path-to-example]** - In a rare case, your GitHub URL might contain a branch name with a slash (e.g. bug/fix-1) and the path to the example (e.g. foo/bar). In this case, you must specify the path to the example separately: `--example-path foo/bar`
- **--use-npm** - Explicitly tell the CLI to bootstrap the app using npm. To bootstrap using yarn we recommend running `yarn create next-app`
- **--use-npm** - Explicitly tell the CLI to bootstrap the app using npm. Yarn will be used by default if it's installed
### Why use Create Next App?

View File

@@ -4,14 +4,7 @@ description: Learn more about setting a base path in Next.js
# Base Path
<details>
<summary><b>Version History</b></summary>
| Version | Changes |
| -------- | ---------------- |
| `v9.5.0` | Base Path added. |
</details>
> This feature was introduced in [Next.js 9.5](https://nextjs.org/blog/next-9-5) and up. If youre using older versions of Next.js, please upgrade before trying it out.
To deploy a Next.js application under a sub-path of a domain you can use the `basePath` config option.

View File

@@ -24,21 +24,9 @@ module.exports = {
}
```
Next.js will automatically use your asset prefix for the JavaScript and CSS files it loads from the `/_next/` path (`.next/static/` folder). For example, with the above configuration, the following request for a JS chunk:
Next.js will automatically use your asset prefix for the JavaScript and CSS files it loads from the `/_next/` path (`.next/static/` folder).
```
/_next/static/chunks/4b9b41aaa062cbbfeff4add70f256968c51ece5d.4d708494b3aed70c04f0.js
```
Would instead become:
```
https://cdn.mydomain.com/_next/static/chunks/4b9b41aaa062cbbfeff4add70f256968c51ece5d.4d708494b3aed70c04f0.js
```
The exact configuration for uploading your files to a given CDN will depend on your CDN of choice. The only folder you need to host on your CDN is the contents of `.next/static/`, which should be uploaded as `_next/static/` as the above URL request indicates. **Do not upload the rest of your `.next/` folder**, as you should not expose your server code and other configuration to the public.
While `assetPrefix` covers requests to `_next/static`, it does not influence the following paths:
Asset prefix support does not influence the following paths:
- Files in the [public](/docs/basic-features/static-file-serving.md) folder; if you want to serve those assets over a CDN, you'll have to introduce the prefix yourself
- `/_next/data/` requests for `getServerSideProps` pages. These requests will always be made against the main domain since they're not static.

View File

@@ -15,6 +15,7 @@ Before continuing to add custom webpack configuration to your application make s
Some commonly asked for features are available as plugins:
- [@zeit/next-less](https://github.com/vercel/next-plugins/tree/master/packages/next-less)
- [@next/mdx](https://github.com/vercel/next.js/tree/canary/packages/next-mdx)
- [@next/bundle-analyzer](https://github.com/vercel/next.js/tree/canary/packages/next-bundle-analyzer)
@@ -23,6 +24,10 @@ In order to extend our usage of `webpack`, you can define a function that extend
```js
module.exports = {
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
// Note: we provide webpack above so you should not `require` it
// Perform customizations to webpack config
config.plugins.push(new webpack.IgnorePlugin(/\/__tests__\//))
// Important: return the modified config
return config
},

View File

@@ -40,8 +40,6 @@ module.exports = {
}
```
Note: the `query` field in `exportPathMap` can not be used with [automatically statically optimized pages](/docs/advanced-features/automatic-static-optimization) or [`getStaticProps` pages](https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation) as they are rendered to HTML files at build-time and additional query information can not be provided during `next export`.
The pages will then be exported as HTML files, for example, `/about` will become `/about.html`.
`exportPathMap` is an `async` function that receives 2 arguments: the first one is `defaultPathMap`, which is the default map used by Next.js. The second argument is an object with:

View File

@@ -4,6 +4,8 @@ description: Add custom HTTP headers to your Next.js app.
# Headers
> This feature was introduced in [Next.js 9.5](https://nextjs.org/blog/next-9-5) and up. If youre using older versions of Next.js, please upgrade before trying it out.
<details open>
<summary><b>Examples</b></summary>
<ul>
@@ -11,16 +13,6 @@ description: Add custom HTTP headers to your Next.js app.
</ul>
</details>
<details>
<summary><b>Version History</b></summary>
| Version | Changes |
| --------- | -------------- |
| `v10.2.0` | `has` added. |
| `v9.5.0` | Headers added. |
</details>
Headers allow you to set custom HTTP headers for an incoming request path.
To set custom HTTP headers you can use the `headers` key in `next.config.js`:
@@ -162,23 +154,6 @@ module.exports = {
}
```
The following characters `(`, `)`, `{`, `}`, `:`, `*`, `+`, `?` are used for regex path matching, so when used in the `source` as non-special values they must be escaped by adding `\\` before them:
```js
module.exports = {
async redirects() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
permanent: false,
},
]
},
}
```
## Header, Cookie, and Query Matching
To only apply a header when either header, cookie, or query values also match the `has` field can be used. Both the `source` and all `has` items must match for the header to be applied.
@@ -218,9 +193,6 @@ module.exports = {
{
type: 'query',
key: 'page',
// the page value will not be available in the
// header key/values since value is provided and
// doesn't use a named capture group e.g. (?<page>home)
value: 'home',
},
{
@@ -373,14 +345,3 @@ module.exports = {
### Cache-Control
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](https://nextjs.org/docs/basic-features/pages#static-generation-recommended), you can do so by setting `revalidate` in the page's [`getStaticProps`](https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation) function.
## Related
For more information, we recommend the following sections:
<div class="card">
<a href="/docs/advanced-features/security-headers.md">
<b>Security Headers:</b>
<small>Improve the security of your Next.js application by add HTTP response headers.</small>
</a>
</div>

View File

@@ -1,39 +0,0 @@
---
description: Next.js reports ESLint errors and warnings during builds by default. Learn how to opt-out of this behavior here.
---
# Ignoring ESLint
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).
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
// your project has ESLint errors.
ignoreDuringBuilds: true,
},
}
```
## 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>
<div class="card">
<a href="/docs/basic-features/eslint.md">
<b>ESLint:</b>
<small>Get started with ESLint in Next.js.</small>
</a>
</div>

View File

@@ -26,7 +26,7 @@ module.exports = (phase, { defaultConfig }) => {
}
```
`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 [here](https://github.com/vercel/next.js/blob/canary/packages/next/next-server/lib/constants.ts#L1-L4). Phases can be imported from `next/constants`:
```js
const { PHASE_DEVELOPMENT_SERVER } = require('next/constants')
@@ -44,7 +44,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 [here](https://github.com/vercel/next.js/blob/canary/packages/next/next-server/server/config-shared.ts#L33).
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

@@ -4,6 +4,8 @@ description: Add redirects to your Next.js app.
# Redirects
> This feature was introduced in [Next.js 9.5](https://nextjs.org/blog/next-9-5) and up. If youre using older versions of Next.js, please upgrade before trying it out.
<details open>
<summary><b>Examples</b></summary>
<ul>
@@ -11,16 +13,6 @@ description: Add redirects to your Next.js app.
</ul>
</details>
<details>
<summary><b>Version History</b></summary>
| Version | Changes |
| --------- | ---------------- |
| `v10.2.0` | `has` added. |
| `v9.5.0` | Redirects added. |
</details>
Redirects allow you to redirect an incoming request path to a different destination path.
Redirects are only available on the Node.js environment and do not affect client-side routing.
@@ -90,7 +82,7 @@ module.exports = {
### Regex Path Matching
To match a regex path you can wrap the regex in parentheses after a parameter, for example `/post/:slug(\\d{1,})` will match `/post/123` but not `/post/abc`:
To match a regex path you can wrap the regex in parenthesis after a parameter, for example `/post/:slug(\\d{1,})` will match `/post/123` but not `/post/abc`:
```js
module.exports = {
@@ -106,23 +98,6 @@ module.exports = {
}
```
The following characters `(`, `)`, `{`, `}`, `:`, `*`, `+`, `?` are used for regex path matching, so when used in the `source` as non-special values they must be escaped by adding `\\` before them:
```js
module.exports = {
async redirects() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
permanent: false,
},
]
},
}
```
## Header, Cookie, and Query Matching
To only match a redirect when header, cookie, or query values also match the `has` field can be used. Both the `source` and all `has` items must match for the redirect to be applied.
@@ -140,7 +115,7 @@ module.exports = {
// if the header `x-redirect-me` is present,
// this redirect will be applied
{
source: '/:path((?!another-page$).*)',
source: '/:path*',
has: [
{
type: 'header',
@@ -158,9 +133,6 @@ module.exports = {
{
type: 'query',
key: 'page',
// the page value will not be available in the
// destination since value is provided and doesn't
// use a named capture group e.g. (?<page>home)
value: 'home',
},
{
@@ -170,12 +142,12 @@ module.exports = {
},
],
permanent: false,
destination: '/another/:path*',
destination: '/:path*/:page',
},
// if the header `x-authorized` is present and
// contains a matching value, this redirect will be applied
{
source: '/',
source: '/:path*',
has: [
{
type: 'header',
@@ -189,7 +161,7 @@ module.exports = {
// if the host is `example.com`,
// this redirect will be applied
{
source: '/:path((?!another-page$).*)',,
source: '/:path*',
has: [
{
type: 'host',

View File

@@ -4,6 +4,8 @@ description: Add rewrites to your Next.js app.
# Rewrites
> This feature was introduced in [Next.js 9.5](https://nextjs.org/blog/next-9-5) and up. If youre using older versions of Next.js, please upgrade before trying it out.
<details open>
<summary><b>Examples</b></summary>
<ul>
@@ -11,19 +13,9 @@ description: Add rewrites to your Next.js app.
</ul>
</details>
<details>
<summary><b>Version History</b></summary>
| Version | Changes |
| --------- | --------------- |
| `v10.2.0` | `has` added. |
| `v9.5.0` | Rewrites added. |
</details>
Rewrites allow you to map an incoming request path to a different destination path.
Rewrites act as a URL proxy and mask the destination path, making it appear the user hasn't changed their location on the site. In contrast, [redirects](/docs/api-reference/next.config.js/redirects.md) will reroute to a new page and show the URL changes.
Rewrites are only available on the Node.js environment and do not affect client-side routing.
To use rewrites you can use the `rewrites` key in `next.config.js`:
@@ -40,8 +32,6 @@ module.exports = {
}
```
Rewrites are applied to client-side routing, a `<Link href="/about">` will have the rewrite applied in the above example.
`rewrites` is an async function that expects an array to be returned holding objects with `source` and `destination` properties:
- `source`: `String` - is the incoming request path pattern.
@@ -50,7 +40,7 @@ Rewrites are applied to client-side routing, a `<Link href="/about">` will have
- `locale`: `false` or `undefined` - whether the locale should not be included when matching.
- `has` is an array of [has objects](#header-cookie-and-query-matching) with the `type`, `key` and `value` properties.
Rewrites are applied after checking the filesystem (pages and `/public` files) and before dynamic routes by default. This behavior can be changed by instead returning an object instead of an array from the `rewrites` function since `v10.1` of Next.js:
Rewrites are applied after checking the filesystem (pages and `/public` files) and before dynamic routes by default. This behavior can be changed by instead returning an object instead of an array from the `rewrites` function:
```js
module.exports = {
@@ -58,8 +48,8 @@ module.exports = {
return {
beforeFiles: [
// These rewrites are checked after headers/redirects
// and before all files including _next/public files which
// allows overriding page files
// and before pages/public files which allows overriding
// page files
{
source: '/some-page',
destination: '/somewhere-else',
@@ -79,7 +69,7 @@ module.exports = {
// and dynamic routes are checked
{
source: '/:path*',
destination: `https://my-old-site.com/:path*`,
destination: 'https://my-old-site.com',
},
],
}
@@ -188,23 +178,6 @@ module.exports = {
}
```
The following characters `(`, `)`, `{`, `}`, `:`, `*`, `+`, `?` are used for regex path matching, so when used in the `source` as non-special values they must be escaped by adding `\\` before them:
```js
module.exports = {
async redirects() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
permanent: false,
},
]
},
}
```
## Header, Cookie, and Query Matching
To only match a rewrite when header, cookie, or query values also match the `has` field can be used. Both the `source` and all `has` items must match for the rewrite to be applied.
@@ -239,9 +212,6 @@ module.exports = {
{
type: 'query',
key: 'page',
// the page value will not be available in the
// destination since value is provided and doesn't
// use a named capture group e.g. (?<page>home)
value: 'home',
},
{
@@ -250,7 +220,7 @@ module.exports = {
value: 'true',
},
],
destination: '/:path*/home',
destination: '/:path*/:page',
},
// if the header `x-authorized` is present and
// contains a matching value, this rewrite will be applied
@@ -308,27 +278,29 @@ module.exports = {
### Incremental adoption of Next.js
You can also have Next.js fall back to proxying to an existing website after checking all Next.js routes.
You can also make Next.js check the application routes before falling back to proxying to the previous website.
This way you don't have to change the rewrites configuration when migrating more pages to Next.js
```js
module.exports = {
async rewrites() {
return {
fallback: [
{
source: '/:path*',
destination: `https://custom-routes-proxying-endpoint.vercel.app/:path*`,
},
],
}
return [
// we need to define a no-op rewrite to trigger checking
// all pages/static files before we attempt proxying
{
source: '/:path*',
destination: '/:path*',
},
{
source: '/:path*',
destination: `https://custom-routes-proxying-endpoint.vercel.app/:path*`,
},
]
},
}
```
See additional information on incremental adoption [in the docs here](/docs/migrating/incremental-adoption.md).
### Rewrites with basePath support
When leveraging [`basePath` support](/docs/api-reference/next.config.js/basepath.md) with rewrites each `source` and `destination` is automatically prefixed with the `basePath` unless you add `basePath: false` to the rewrite:

View File

@@ -4,14 +4,7 @@ description: Configure Next.js pages to resolve with or without a trailing slash
# Trailing Slash
<details>
<summary><b>Version History</b></summary>
| Version | Changes |
| -------- | --------------------- |
| `v9.5.0` | Trailing Slash added. |
</details>
> This feature was introduced in [Next.js 9.5](https://nextjs.org/blog/next-9-5) and up. If youre using older versions of Next.js, please upgrade before trying it out.
By default Next.js will redirect urls with trailing slashes to their counterpart without a trailing slash. For example `/about/` will redirect to `/about`. You can configure this behavior to act the opposite way, where urls without trailing slashes are redirected to their counterparts with trailing slashes.

View File

@@ -11,7 +11,7 @@ description: Enable AMP in a page, and control the way Next.js adds AMP to the p
</ul>
</details>
> AMP support is one of our advanced features, you can [read more about AMP here](/docs/advanced-features/amp-support/introduction.md).
> AMP support is one of our advanced features, you can read more about it [here](/docs/advanced-features/amp-support/introduction.md).
To enable AMP, add the following config to your page:

View File

@@ -14,12 +14,11 @@ description: Enable Image Optimization with the built-in Image component.
<details>
<summary><b>Version History</b></summary>
| Version | Changes |
| --------- | ------------------------------------------------------------------------------------------------- |
| `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. |
| `v10.0.0` | `next/image` introduced. |
| Version | Changes |
| --------- | ------------------------ |
| `v10.0.5` | `loader` prop added. |
| `v10.0.1` | `layout` prop added. |
| `v10.0.0` | `next/image` introduced. |
</details>
@@ -40,13 +39,17 @@ We can serve an optimized image like so:
```jsx
import Image from 'next/image'
import profilePic from '../public/me.png'
function Home() {
return (
<>
<h1>My Homepage</h1>
<Image src={profilePic} alt="Picture of the author" />
<Image
src="/me.png"
alt="Picture of the author"
width={500}
height={500}
/>
<p>Welcome to my homepage!</p>
</>
)
@@ -61,11 +64,7 @@ The `<Image />` component requires the following properties.
### src
Required and must be one of the following:
1. A statically imported image file, as in the example code above, or
2. A path string. This can be either an absolute external URL,
or an internal path depending on the [loader](#loader).
The path or URL to the source image. This is required.
When using an external URL, you must add it to
[domains](/docs/basic-features/image-optimization.md#domains) in
@@ -75,13 +74,13 @@ When using an external URL, you must add it to
The width of the image, in pixels. Must be an integer without a unit.
Required, except for statically imported images, or those with [`layout="fill"`](#layout).
Required unless [`layout="fill"`](#layout).
### height
The height of the image, in pixels. Must be an integer without a unit.
Required, except for statically imported images, or those with [`layout="fill"`](#layout).
Required unless [`layout="fill"`](#layout).
## Optional Props
@@ -102,7 +101,8 @@ When `responsive`, the image will scale the dimensions down for smaller
viewports and scale up for larger viewports.
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, usually paired with
[object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit).
Try it out:
@@ -133,7 +133,7 @@ const MyImage = (props) => {
return (
<Image
loader={myLoader}
src="me.png"
src="/me.png"
alt="Picture of the author"
width={500}
height={500}
@@ -163,21 +163,6 @@ When true, the image will be considered high priority and
Should only be used when the image is visible above the fold. Defaults to
`false`.
### placeholder
A placeholder to use while the image is loading, possible values are `blur` or `empty`. Defaults to `empty`.
When `blur`, the [`blurDataURL`](#blurdataurl) property will be used as the placeholder. If `src` is an object from a static import and the imported image is jpg, png, or webp, then `blurDataURL` will automatically be populated.
For dynamic images, you must provide the [`blurDataURL`](#blurdataurl) property. Solutions such as [Plaiceholder](https://github.com/joe-bell/plaiceholder) can help with `base64` generation.
When `empty`, there will be no placeholder while the image is loading, only empty space.
Try it out:
- [Demo the `blur` placeholder](https://image-component.nextjs.gallery/placeholder)
- [Demo the shimmer effect with `blurDataURL` prop](https://image-component.nextjs.gallery/shimmer)
## Advanced Props
In some cases, you may need more advanced usage. The `<Image />` component
@@ -212,22 +197,6 @@ When `eager`, load the image immediately.
[Learn more](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading)
### blurDataURL
A [Data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) to
be used as a placeholder image before the `src` image successfully loads. Only takes effect when combined
with [`placeholder="blur"`](#placeholder).
Must be a base64-encoded image. It will be enlarged and blurred, so a very small image (10px or
less) is recommended. Including larger images as placeholders may harm your application performance.
Try it out:
- [Demo the default `blurDataURL` prop](https://image-component.nextjs.gallery/placeholder)
- [Demo the shimmer effect with `blurDataURL` prop](https://image-component.nextjs.gallery/shimmer)
You can also [generate a solid color Data URL](https://png-pixel.com) to match the image.
### unoptimized
When true, the source image will be served as-is instead of changing quality,

View File

@@ -57,7 +57,7 @@ export default Home
- `href` - The path or URL to navigate to. This is the only required prop
- `as` - Optional decorator for the path that will be shown in the browser URL bar. Before Next.js 9.5.3 this was used for dynamic routes, check our [previous docs](https://nextjs.org/docs/tag/v9.5.2/api-reference/next/link#dynamic-routes) to see how it worked
- [`passHref`](#if-the-child-is-a-custom-component-that-wraps-an-a-tag) - Forces `Link` to send the `href` property to its child. Defaults to `false`
- `prefetch` - Prefetch the page in the background. Defaults to `true`. Any `<Link />` that is in the viewport (initially or through scroll) will be preloaded. Prefetch can be disabled by passing `prefetch={false}`. When `prefetch` is set to `false`, prefetching will still occur on hover. Pages using [Static Generation](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) will preload `JSON` files with the data for faster page transitions. Prefetching is only enabled in production.
- `prefetch` - Prefetch the page in the background. Defaults to `true`. Any `<Link />` that is in the viewport (initially or through scroll) will be preloaded. Prefetch can be disabled by passing `prefetch={false}`. Pages using [Static Generation](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) will preload `JSON` files with the data for faster page transitions
- [`replace`](#replace-the-url-instead-of-push) - Replace the current `history` state instead of adding a new url into the stack. Defaults to `false`
- [`scroll`](#disable-scrolling-to-the-top-of-the-page) - Scroll to the top of the page after a navigation. Defaults to `true`
- [`shallow`](/docs/routing/shallow-routing.md) - Update the path of the current page without rerunning [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation), [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering) or [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md). Defaults to `false`

View File

@@ -41,7 +41,7 @@ export default ActiveLink
The following is the definition of the `router` object returned by both [`useRouter`](#useRouter) and [`withRouter`](#withRouter):
- `pathname`: `String` - Current route. That is the path of the page in `/pages`, the configured `basePath` or `locale` is not included.
- `pathname`: `String` - Current route. That is the path of the page in `/pages`
- `query`: `Object` - The query string parsed to an object. It will be an empty object during prerendering if the page doesn't have [data fetching requirements](/docs/basic-features/data-fetching.md). Defaults to `{}`
- `asPath`: `String` - The path (including the query) shown in the browser without the configured `basePath` or `locale`.
- `isFallback`: `boolean` - Whether the current page is in [fallback mode](/docs/basic-features/data-fetching.md#fallback-pages).
@@ -49,7 +49,6 @@ The following is the definition of the `router` object returned by both [`useRou
- `locale`: `String` - The active locale (if enabled).
- `locales`: `String[]` - All supported locales (if enabled).
- `defaultLocale`: `String` - The current default locale (if enabled).
- `domainLocales`: `Array<{domain, defaultLocale, locales}>` - Any configured domain locales.
- `isReady`: `boolean` - Whether the router fields are updated client-side and ready for use. Should only be used inside of `useEffect` methods and not for conditionally rendering on the server.
- `isPreview`: `boolean` - Whether the application is currently in [preview mode](/docs/advanced-features/preview-mode.md).
@@ -75,7 +74,6 @@ router.push(url, as, options)
- `options` - Optional object with the following configuration options:
- `scroll` - Optional boolean, controls scrolling to the top of the page after navigation. Defaults to `true`
- [`shallow`](/docs/routing/shallow-routing.md): Update the path of the current page without rerunning [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation), [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering) or [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md). Defaults to `false`
- `locale` - Optional string, indicates locale of the new page
> You don't need to use `router.push` for external URLs. [window.location](https://developer.mozilla.org/en-US/docs/Web/API/Window/location) is better suited for those cases.
@@ -89,11 +87,7 @@ import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/about')}>
Click me
</button>
)
return <span onClick={() => router.push('/about')}>Click me</span>
}
```
@@ -105,16 +99,10 @@ import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/post/abc')}>
Click me
</button>
)
return <button onClick={() => router.push('/post/abc')}>Click me</button>
}
```
> **Note:** When navigating to the same page in Next.js, the page's state **will not** be reset by default, as the top-level React component is the same. You can manually ensure the state is updated using `useEffect`.
Redirecting the user to `pages/login.js`, useful for pages behind [authentication](/docs/authentication):
```jsx
@@ -150,7 +138,6 @@ export default function ReadMore({ post }) {
return (
<button
type="button"
onClick={() => {
router.push({
pathname: '/post/[pid]',
@@ -184,11 +171,7 @@ import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.replace('/home')}>
Click me
</button>
)
return <button onClick={() => router.replace('/home')}>Click me</button>
}
```
@@ -299,11 +282,7 @@ import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.back()}>
Click here to go back
</button>
)
return <button onClick={() => router.back()}>Click here to go back</button>
}
```
@@ -319,11 +298,7 @@ import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.reload()}>
Click here to reload
</button>
)
return <button onClick={() => router.reload()}>Click here to reload</button>
}
```
@@ -430,7 +405,7 @@ function Page({ router }) {
export default withRouter(Page)
```
### TypeScript
### Typescript
To use class components with `withRouter`, the component needs to accept a router prop:

View File

@@ -29,8 +29,8 @@ export default function handler(req, res) {
For an API route to work, you need to export a function as default (a.k.a **request handler**), which then receives the following parameters:
- `req`: An instance of [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage), plus some [pre-built middlewares](/docs/api-routes/api-middlewares.md)
- `res`: An instance of [http.ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse), plus some [helper functions](/docs/api-routes/response-helpers.md)
- `req`: An instance of [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage), plus some pre-built middlewares you can see [here](/docs/api-routes/api-middlewares.md)
- `res`: An instance of [http.ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse), plus some helper functions you can see [here](/docs/api-routes/response-helpers.md)
To handle different HTTP methods in an API route, you can use `req.method` in your request handler, like so:

View File

@@ -23,7 +23,7 @@ export default function handler(req, res) {
The included helpers are:
- `res.status(code)` - A function to set the status code. `code` must be a valid [HTTP status code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
- `res.json(body)` - Sends a JSON response. `body` must be a [serialiazable object](https://developer.mozilla.org/en-US/docs/Glossary/Serialization)
- `res.json(json)` - Sends a JSON response. `json` must be a valid JSON object
- `res.send(body)` - Sends the HTTP response. `body` can be a `string`, an `object` or a `Buffer`
- `res.redirect([status,] path)` - Redirects to a specified path or URL. `status` must be a valid [HTTP status code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes). If not specified, `status` defaults to "307" "Temporary redirect".

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