1
0
mirror of synced 2026-02-09 00:00:11 -05:00

Compare commits

...

141 Commits

Author SHA1 Message Date
Brandon Bayer
4068b4493e upgrade monorepo react to v18 alpha 2021-07-05 16:37:39 -04:00
Brandon Bayer
0448535ef0 Add test for Page.redirectAuthenticatedTo (#2531)
(meta)
2021-07-05 16:21:00 -04:00
Brandon Bayer
0df6aef3a3 fix broken api routes in canary release (#2545)
(patch)
2021-07-05 12:50:56 -04:00
Brandon Bayer
5ba2989592 fix cli npm build
(ignore)
2021-07-05 12:45:24 -04:00
Blitz.js Bot
9240d86ed6 (meta) added @esemeniuc as contributor 2021-07-05 12:09:51 -04:00
Eric Semeniuc
27e0dacdaf Route manifest replace nbsp with normal space (#2482)
Co-authored-by: Brandon Bayer <b@bayer.ws> (patch)
2021-07-05 12:09:46 -04:00
Brandon Bayer
8dc1cd3ca8 Fix CSRF error when using session.$setPublicData (#2541)
(patch)
2021-07-05 11:03:16 -04:00
Brandon Bayer
413bc01676 bump recipe/example versions (ignore) 2021-06-24 21:11:02 -06:00
Brandon Bayer
7c025e9bd7 v0.38.3-canary.1 2021-06-24 21:09:13 -06:00
Brandon Bayer
24e51c7ae5 Next.js Fork Migration: Move blitz.config.(js|ts) support into nextjs core (patch) (#2532) 2021-06-24 23:06:55 -04:00
Brandon Bayer
b2f84f1224 bump recipe/example versions (ignore) 2021-06-24 11:40:33 -06:00
Brandon Bayer
8df18f24ad v0.38.3-canary.0 2021-06-24 11:39:25 -06:00
Brandon Bayer
d480d84e46 Move multiple pages folders support plus pages+api sibling into nextjs core (#2502)
(patch)
2021-06-24 13:37:34 -04:00
Brandon Bayer
f0a9fbeb14 bump recipe/example versions (ignore) 2021-06-24 10:00:19 -06:00
Brandon Bayer
fe8179b595 v0.38.2 2021-06-24 09:59:06 -06:00
Brandon Bayer
6eaed7a3b2 tweak internal tsconfig
(ignore)
2021-06-24 09:57:59 -06:00
Brandon Bayer
69e97017b1 Fix built in errors like RedirectError and AuthenticationError to not log as "uncaught" in browser console (#2522)
(patch)
2021-06-24 11:45:58 -04:00
Brandon Bayer
1aa2d79ef4 git subrepo push --force nextjs
subrepo:
  subdir:   "nextjs"
  merged:   "4be32b7a5"
upstream:
  origin:   "git@github.com:blitz-js/next.js.git"
  branch:   "canary"
  commit:   "4be32b7a5"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "2f68596"
2021-06-23 18:54:24 -06:00
Brandon Bayer
194a3720ce build script (ignore) 2021-06-23 18:52:11 -06:00
Brandon Bayer
e21b22d672 git subrepo push nextjs
subrepo:
  subdir:   "nextjs"
  merged:   "018261ad9"
upstream:
  origin:   "git@github.com:blitz-js/next.js.git"
  branch:   "canary"
  commit:   "018261ad9"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "2f68596"
2021-06-23 18:48:33 -06:00
Brandon Bayer
b634fe9587 Upgrade to Next.js 11.0.1 (#2526)
(patch)
2021-06-23 20:34:58 -04:00
t.kuriyama
9b35fcd018 Fix blitz db seed to print stack traces for any errors (#2528)
(patch)
2021-06-23 19:49:36 -04:00
Simon Knott
d16ed02a50 Fix prefetched dehydrated state to support Dates, Maps, etc (patch) (#2512)
Co-authored-by: Brandon Bayer <b@bayer.ws>
2021-06-21 13:23:26 -04:00
Blitz.js Bot
bdec5cffbf (meta) updated @Cristy94 contributions 2021-06-21 13:17:37 -04:00
Buleandra Cristian
be430e093d Update userTrack logo (sponsor) (#2517)
(meta)
2021-06-21 13:17:32 -04:00
Brandon Bayer
3deb0045f4 bump recipe/example versions (ignore) 2021-06-19 17:28:04 -06:00
Brandon Bayer
c19e71624e v0.38.1 2021-06-19 17:25:42 -06:00
Blitz.js Bot
b6fcba1c01 (meta) added @benjakugler96 as contributor 2021-06-19 18:11:54 -04:00
Benja Kugler
dbdb6a4199 Fix browser error when using prisma.$use() (#2514)
Co-authored-by: benjamin.kugler <benjamin.kugler@elliemae.com> (patch)
2021-06-19 18:11:49 -04:00
Brandon Bayer
c151b3571e fix lint warning, unused path in generated api routes (patch) (#2513) 2021-06-19 15:20:55 -04:00
Blitz.js Bot
6198025ce5 (meta) added @prisis as contributor 2021-06-19 14:19:34 -04:00
Daniel Bannert
c9dba04f56 Fix so that npm scripts don't run on blitz install recipes (#2498)
Co-authored-by: danielb <daniel.bannert@limango.de> (patch)
2021-06-19 14:19:29 -04:00
Blitz.js Bot
a2c6c9ce23 (meta) updated @ntgussoni contributions 2021-06-19 14:01:48 -04:00
Nicolas Torres
b09c188113 Add support for custom messages and icons in recipes (#2510)
Adds ability to customize the success message icon in recipes (patch)

Co-authored-by: Nicolas <ntorres.dev@gmail.com>
2021-06-19 14:01:22 -04:00
Dustin Bachrach
cdd71af1cf Fix blitz generate to regenerate the Routes manifest (#2504)
(patch)
2021-06-19 13:58:55 -04:00
Brandon Bayer
54647d0054 fix validateZodSchema() to pass if schema undefined (#2511)
(patch)
2021-06-19 13:57:47 -04:00
Blitz.js Bot
1e39604ae1 (meta) added @igeligel as contributor 2021-06-18 12:22:31 -04:00
Dustin Bachrach
2f890b72ca Fix blitz generate /new page does not use Routes (#2501)
(patch)
2021-06-18 12:03:42 -04:00
Brandon Bayer
2a9125def5 bump recipe/example versions (ignore) 2021-06-17 09:32:09 -04:00
Brandon Bayer
2111ca6fae v0.38.0 2021-06-17 09:30:01 -04:00
Brandon Bayer
a640b1112f fix build
(ignore)
2021-06-16 19:33:31 -04:00
Brandon Bayer
0243df5b6a fix formatZodError to work with arrays
(fix)
2021-06-16 19:29:58 -04:00
Brandon Bayer
4256f48fa6 add formatZodError() utility (#2494)
(minor)
2021-06-16 18:30:12 -04:00
Brandon Bayer
1c256c9c11 (newapp) Upgrade react@alpha react-dom@alpha 2021-06-16 18:02:02 -04:00
Brandon Bayer
e392a37985 fix a couple next.config.js string
(ignore)
2021-06-16 16:53:50 -04:00
Brandon Bayer
e2b6dd2779 git subrepo push --force nextjs
subrepo:
  subdir:   "nextjs"
  merged:   "8d1a527b8"
upstream:
  origin:   "git@github.com:blitz-js/next.js.git"
  branch:   "canary"
  commit:   "8d1a527b8"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "2f68596"
2021-06-16 16:19:29 -04:00
Brandon Bayer
e4e3e757bc remove all nextjs/examples (meta) 2021-06-16 16:17:23 -04:00
Brandon Bayer
18438fb45c Upgrade to Next.js 11 (#2489)
(minor)
2021-06-16 16:11:23 -04:00
Blitz.js Bot
b80cf675b6 (meta) added @deini as contributor 2021-06-15 21:41:38 -04:00
Brandon Bayer
4db0f32156 improve sync script (ignore) 2021-06-15 11:57:25 -04:00
Brandon Bayer
a63e234ca4 git subrepo push nextjs
subrepo:
  subdir:   "nextjs"
  merged:   "3fafd4eeb"
upstream:
  origin:   "git@github.com:blitz-js/next.js.git"
  branch:   "canary"
  commit:   "3fafd4eeb"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "2f68596"
2021-06-15 11:55:42 -04:00
Blitz.js Bot
5f2bf3ae55 (meta) added @ashikka as contributor 2021-06-15 11:53:58 -04:00
Ashikka Gupta
da39eca564 Change all user facing references of next.js to blitz.js (#2438)
* fix: Change all user facing references of next.js to blitz.js

* fix: fixed instances of next.js in unit test files

* fix: fixed instances of next.js in integration test files

* fix: next.js regex in test integration 9

* fixes

* fix

* fix a test

* fix dynamicrouting test

* more test fix

* bump

Co-authored-by: Brandon Bayer <b@bayer.ws> (patch)
2021-06-15 11:53:53 -04:00
Mina Abadir
9fc358b0df Fix bug with <Image> and SSR for configured domains (#2474)
Co-authored-by: Brandon Bayer <b@bayer.ws> (patch)
2021-06-15 11:09:20 -04:00
Blitz.js Bot
6e7111397f (meta) updated @dbachrach contributions 2021-06-15 07:04:08 -04:00
Blitz.js Bot
fc66d61f0c (meta) added @dbachrach as contributor 2021-06-14 22:09:28 -04:00
Dustin Bachrach
026d3d84a1 Fix edit page generated by blitz generate to not have buggy behavior (#2487)
(patch)
2021-06-14 22:09:24 -04:00
Brandon Bayer
bd43af1ba5 more fix CI
(ignore)
2021-06-14 21:33:21 -04:00
Brandon Bayer
86be2c122e fix CI by upgrading browserslist (#2488)
* fix CI by upgrading browserslist

* fix (ignore)
2021-06-14 20:07:46 -04:00
Brandon Bayer
e2a54b5904 fix Page.authenticate = {redirect: '/login'} not working correctly on logout AND add RedirectError (patch) (#2483) 2021-06-14 12:08:56 -04:00
Blitz.js Bot
2c3afcf407 (meta) updated @lksnmnn contributions 2021-06-14 11:41:05 -04:00
Lukas Neumann
f478f83e9d Add setPublicDataForUser() — useful for updating the role of another user (#2473)
Co-authored-by: Lukas Neumann <l.neumann@layer9.berlin>
Co-authored-by: Brandon Bayer <b@bayer.ws> (minor)
2021-06-14 11:41:00 -04:00
Brandon Bayer
4e9968a2db Add <ErrorBoundary> component (major) (#2480) 2021-06-11 17:20:50 -04:00
Blitz.js Bot
5d0998ab84 (meta) added @lksnmnn as contributor 2021-06-11 15:00:20 -04:00
Blitz.js Bot
b3f1598212 (meta) updated @swinner2 contributions 2021-06-11 14:49:31 -04:00
Brandon Bayer
503ec19c66 fix broken vercel deployments (patch) (#2479) 2021-06-11 14:35:49 -04:00
Blitz.js Bot
f20d7cf8ec (meta) updated @swinner2 contributions 2021-06-11 14:31:31 -04:00
Sean Winner
81118cd6a0 Add validateZodSchema() API for better form errors (#2441)
Co-authored-by: Brandon Bayer <b@bayer.ws> (minor)
2021-06-11 14:31:26 -04:00
Brandon Bayer
768562945e Rename DISABLE_CSRF_PROTECTION to DANGEROUSLY_DISABLE_CSRF_PROTECTION (patch) 2021-06-11 11:24:40 -04:00
Brandon Bayer
cac31cd1e6 fix pages to never render if Page.authenticate=true and logged out (patch) (#2476) 2021-06-10 17:35:57 -04:00
Brandon Bayer
3138fc5f6e fix GH actions to cancel existing actions on new push (meta) 2021-06-10 16:14:02 -04:00
Blitz.js Bot
2fa862ebf8 (meta) added @dangreaves as contributor 2021-06-10 12:32:36 -04:00
Dan Greaves
218bc15bd3 fix BlitzConfig type to allow extra fields (patch) (#2471) 2021-06-10 12:32:32 -04:00
Blitz.js Bot
be9f70850c (meta) added @kivi as contributor 2021-06-10 12:25:17 -04:00
kivi
ef6a6dbcc7 (newapp) move dev dependencies to devDependencies in package.json (better for Docker) (#2475) 2021-06-10 12:25:12 -04:00
Brandon Bayer
afa6792b66 bump recipe/example versions (ignore) 2021-06-08 14:32:26 -04:00
Brandon Bayer
7d5f437c7b v0.37.0 2021-06-08 14:31:05 -04:00
Brandon Bayer
a81f4518ae fix postinstall
(ignore)
2021-06-08 14:25:36 -04:00
Brandon Bayer
1407ddd7ad Fix one part of pnp issues (patch) (#2464) 2021-06-08 14:22:36 -04:00
Brandon Bayer
a510bd079b Fix webpack 5 support (Webpack 5 now used by default) (patch) (#2453)
Co-authored-by: Kristoffer K. <merceyz@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2021-06-08 13:31:52 -04:00
Blitz.js Bot
ff85cf1c17 (meta) updated @mabadir contributions 2021-06-08 13:03:39 -04:00
Mina Abadir
1ef378bff0 Fix to not build custom server during blitz start (#2408)
(patch)
2021-06-08 13:03:34 -04:00
Blitz.js Bot
22a845e13a (meta) added @garnerp as contributor 2021-06-08 11:57:50 -04:00
Brandon Bayer
8eb1509b9a Fix auth & middleware not working on Vercel (No longer need the path.resolve workaround) (patch) (#2463) 2021-06-07 20:26:59 -04:00
Brandon Bayer
c46decbbe7 (newapp) Update Prisma and React dependencies (#2462) 2021-06-07 15:59:09 -04:00
Blitz.js Bot
577206a404 (meta) updated @frankiesardo contributions 2021-06-07 15:12:15 -04:00
Francesco Sardo
8b245bef9a Fix Routes manifest for pages with parent & child relationships (patch) (#2424)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: Brandon Bayer <b@bayer.ws>
2021-06-07 15:12:09 -04:00
Blitz.js Bot
f2d41eff35 (meta) updated @markhughes contributions 2021-06-04 15:49:08 -04:00
Blitz.js Bot
f8ce548f4a (meta) added @sebastianhoitz as contributor 2021-06-04 14:11:52 -04:00
Sebastian Hoitz
d8aeb6b18f Fix CSRF 401 errors for HEAD requests (patch) (#2443) 2021-06-04 14:11:48 -04:00
Mark Hughes
f1de531124 Add ability to disable custom server hot reloading (#2447)
(minor)
2021-06-04 14:11:23 -04:00
Blitz.js Bot
9c54361cd6 (meta) added @max-programming as contributor 2021-06-04 14:08:53 -04:00
Max Programming
ee939ac7b8 Remove unneeded cd message during blitz install in some cases (#2451)
(patch)
2021-06-04 14:08:50 -04:00
Jeremy Liberman
3cf7d399cd Fix Prisma @@map in Enums break the model generator (#2445)
(patch)
2021-06-04 14:07:04 -04:00
Brandon Bayer
e4b788321b bump recipe/example versions (ignore) 2021-06-02 13:22:30 -04:00
Brandon Bayer
59272f7334 v0.36.4 2021-06-02 13:21:09 -04:00
Brandon Bayer
3416e097d8 Add helpful error when trying blitz export with blitz auth (patch) (#2435) 2021-06-02 13:11:22 -04:00
Brandon Bayer
49e7abbdfe add couple missing dependencies to @blitzjs/cli package (patch) (#2439) 2021-06-02 13:09:51 -04:00
Blitz.js Bot
a00f162bca (meta) added @swinner2 as contributor 2021-06-01 17:25:53 -04:00
Sean Winner
31498e2d46 Fix so blitz new always generates valid cookiePrefix (#2427)
Co-authored-by: Brandon Bayer <b@bayer.ws>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> (patch)
2021-06-01 17:25:49 -04:00
Blitz.js Bot
6b463fcdd1 (meta) added @AntoineGuestin as contributor 2021-06-01 16:05:35 -04:00
Antoine G
e1785f97a9 add debug to blitz package (#2426)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2021-06-01 20:05:30 +00:00
Brandon Bayer
d4dc932bc3 remove CI from canary branch
(meta)
2021-06-01 15:33:03 -04:00
Brandon Bayer
750ba2e429 add to nextjs fork instructions
(ignore)
2021-06-01 14:43:00 -04:00
Brandon Bayer
a4e4cb2f64 git subrepo push --force nextjs
subrepo:
  subdir:   "nextjs"
  merged:   "9d5938e8f"
upstream:
  origin:   "git@github.com:blitz-js/next.js.git"
  branch:   "canary"
  commit:   "9d5938e8f"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "2f68596"
2021-06-01 14:41:43 -04:00
Brandon Bayer
c5b461c641 fix nextjs subrepo
(ignore)
2021-06-01 10:26:46 -04:00
Brandon Bayer
174bf32c84 remove nextjs experimental react github action
(ignore)
2021-06-01 10:22:24 -04:00
Blitz.js Bot
cb432b6276 (meta) added @ormarek as contributor 2021-05-29 20:17:25 -04:00
Brandon Bayer
1ff0f00715 bump recipe/example versions (ignore) 2021-05-29 18:48:21 -04:00
Brandon Bayer
a3cf482e8f v0.36.3 2021-05-29 18:47:06 -04:00
Brandon Bayer
684b3f34c8 Fix broken Vercel deployments from version 0.35+ (patch) (#2419) 2021-05-29 18:45:14 -04:00
Brandon Bayer
f547f311f7 Fix third-party recipes not working (patch) (#2418) 2021-05-29 18:44:51 -04:00
Brandon Bayer
e7dc1b8352 Fix caught authentication errors showing as uncaught in Firefox (patch) (#2417) 2021-05-29 18:18:18 -04:00
Brandon Bayer
8fb8608e49 (newapp) Fix zod bug on /reset-password page
closes: #2414
2021-05-29 17:23:05 -04:00
Brandon Bayer
63e200e173 bump recipe/example versions (ignore) 2021-05-28 17:16:00 -04:00
Brandon Bayer
53bb153df8 v0.36.2 2021-05-28 17:14:14 -04:00
Brandon Bayer
3727385cd6 yet another fix
(ignore)
2021-05-28 17:11:44 -04:00
Brandon Bayer
1de36fd8dd v0.36.1 2021-05-28 17:10:05 -04:00
Brandon Bayer
5e2dafe519 another build fix
(ignore)
2021-05-28 17:07:12 -04:00
Brandon Bayer
8f08f38d80 fix build (ignore) 2021-05-28 17:06:02 -04:00
Brandon Bayer
61b8c95be8 v0.36.0 2021-05-28 17:03:39 -04:00
Brandon Bayer
a429013360 fix inability to install recipes for npm users (patch) (#2404) 2021-05-28 17:01:38 -04:00
Brandon Bayer
01c609be9e Add BlitzConfig type and add it to newapp template (#2411)
(minor)
2021-05-28 17:01:04 -04:00
Brandon Bayer
7e333955aa Upgrade nextjs to 10.2.3 (#2409)
(patch)
2021-05-28 16:18:58 -04:00
Brandon Bayer
0bfa5fdb7a add cross-spawn to blitz package (#2410)
(ignore)
2021-05-28 16:18:41 -04:00
JuanM04
27336d423a Upgrade templates to work with Zod v3 (#2375)
(minor)
2021-05-28 16:16:47 -04:00
Brandon Bayer
fa82ac913f git subrepo push nextjs
subrepo:
  subdir:   "nextjs"
  merged:   "17f3f0f88"
upstream:
  origin:   "git@github.com:blitz-js/next.js.git"
  branch:   "canary"
  commit:   "17f3f0f88"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "2f68596"
2021-05-28 15:08:01 -04:00
Blitz.js Bot
65405b6f43 (meta) added @timbooker as contributor 2021-05-28 12:35:36 -04:00
Tim
ada67b5aed Fix queries & mutations to work with trailing slash config (patch) (#2392)
* Added trailingslash support for API endpoints.

* Accidentally RM'd actual condition it was meant to be based upon.

* simplify integration test

Co-authored-by: Brandon Bayer <b@bayer.ws>
2021-05-28 16:35:31 +00:00
Blitz.js Bot
3dcc885186 (meta) added @guoqqqi as contributor 2021-05-28 11:12:22 -04:00
guoqqqi
0ce552c90e add contributor over time graph to CONTRIBUTOR_STATS (#2397)
(meta)
2021-05-28 11:12:17 -04:00
Mark Hughes
ec3930ca46 add support for nonce and crossOrigin in BlitzScript (#2377)
(minor)
2021-05-28 11:11:25 -04:00
Brandon Bayer
e3a5420cea Upgrade react-query and Fix CancelledError when clicking Logout (patch) (#2406) 2021-05-27 18:41:55 -04:00
Brandon Bayer
4156368b75 fix bug: cannot find module next/constants (patch) (#2402)
* fix bug of cannot find module `next/constants` (patch)

* fix

* fix

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2021-05-27 20:45:47 +00:00
Brandon Bayer
632df97342 bump recipe/example versions (ignore) 2021-05-26 17:39:24 -04:00
Brandon Bayer
eae332b0c7 v0.35.2 2021-05-26 17:38:14 -04:00
Brandon Bayer
7fdd07e598 (newapp) Fix typescript issue in forgotPassword.test.ts
closes: #2378
2021-05-26 17:34:50 -04:00
Blitz.js Bot
a328b6c19c (meta) updated @mabadir contributions 2021-05-26 17:30:25 -04:00
Mina Abadir
7e22f61079 Add Mina as L1 maintainer (#2391)
(meta)
2021-05-26 17:30:20 -04:00
Brandon Bayer
719d867eea remove debug log from cli (patch) 2021-05-26 17:29:23 -04:00
Brandon Bayer
3501f29521 bump recipe/example versions (ignore) 2021-05-26 17:15:57 -04:00
4233 changed files with 30607 additions and 104012 deletions

View File

@@ -357,7 +357,8 @@
"contributions": [
"test",
"code",
"review"
"review",
"doc"
]
},
{
@@ -2374,7 +2375,8 @@
"avatar_url": "https://avatars.githubusercontent.com/u/1357323?v=4",
"profile": "http://twitter.com/_markeh",
"contributions": [
"code"
"code",
"doc"
]
},
{
@@ -2410,7 +2412,8 @@
"avatar_url": "https://avatars.githubusercontent.com/u/1384885?v=4",
"profile": "www.usertrack.net",
"contributions": [
"doc"
"doc",
"code"
]
},
{
@@ -2637,7 +2640,9 @@
"avatar_url": "https://avatars.githubusercontent.com/u/3389914?v=4",
"profile": "minaabadir.ca",
"contributions": [
"code"
"code",
"doc",
"test"
]
},
{
@@ -2646,7 +2651,8 @@
"avatar_url": "https://avatars.githubusercontent.com/u/1476561?v=4",
"profile": "https://github.com/frankiesardo",
"contributions": [
"doc"
"doc",
"code"
]
},
{
@@ -2693,6 +2699,177 @@
"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,14 +27,16 @@ 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/with-typescript-eslint-jest/**
/nextjs/examples/with-kea/**
/nextjs/examples/**
/nextjs/packages/next/bundles/webpack/packages/*.runtime.js
/nextjs/packages/next/compiled/**/*
/nextjs/packages/react-refresh-utils/**/*.js
@@ -47,4 +49,5 @@ 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,6 +80,19 @@ 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,9 +1,13 @@
name: CI
name: Size Check
on:
pull_request:
branches: [master, canary]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Compressed Size

View File

@@ -3,11 +3,13 @@
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
@@ -28,9 +30,9 @@ jobs:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
**/node_modules
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v8-${{ hashFiles('yarn.lock') }}
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v8-
${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
- name: Install dependencies
run: yarn install --frozen-lockfile --silent
env:
@@ -39,6 +41,10 @@ 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:
@@ -70,9 +76,9 @@ jobs:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
**/node_modules
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v8-${{ hashFiles('yarn.lock') }}
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v8-
${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
- run: yarn install --frozen-lockfile --check-files
- name: Build Packages
run: yarn build
@@ -138,9 +144,9 @@ jobs:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
**/node_modules
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v8-${{ hashFiles('yarn.lock') }}
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v8-
${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
- run: yarn install --frozen-lockfile --check-files
# - run: yarn cpy node_modules/.blitz packages/core/node_modules/.blitz
# if: matrix.os == 'windows-latest'
@@ -239,7 +245,7 @@ jobs:
strategy:
fail-fast: false
matrix:
group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
steps:
- run: echo ${{needs.build.outputs.docsChange}}
working-directory: ./
@@ -254,7 +260,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 }}/10 -c 3
- run: xvfb-run node run-tests.js --timings -g ${{ matrix.group }}/20 -c 3
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testElectron:
@@ -302,94 +308,6 @@ jobs:
steps:
- run: exit 0
testFutureDependencies:
name: Nextjs - 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_WEBPACK5_MODE: 1
steps:
- uses: actions/cache@v2
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
id: restore-build
with:
path: ./*
key: ${{ github.sha }}
- 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: ${{needs.build.outputs.docsChange != '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-v8-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v8-
- 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:
@@ -399,7 +317,7 @@ jobs:
needs: build
env:
HEADLESS: true
BROWSERNAME: "firefox"
BROWSER_NAME: "firefox"
NEXT_TELEMETRY_DISABLED: 1
steps:
- uses: actions/cache@v2
@@ -408,7 +326,7 @@ jobs:
with:
path: ./*
key: ${{ github.sha }}
- run: node run-tests.js test/integration/production/test/index.test.js
- run: node run-tests.js -c 1 test/integration/production/test/index.test.js
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testSafari:
@@ -420,7 +338,7 @@ jobs:
needs: build
env:
BROWSERSTACK: true
BROWSERNAME: "safari"
BROWSER_NAME: "safari"
NEXT_TELEMETRY_DISABLED: 1
SKIP_LOCAL_SELENIUM_SERVER: true
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
@@ -432,7 +350,7 @@ jobs:
with:
path: ./*
key: ${{ github.sha }}
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js test/integration/production/test/index.test.js'
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js -c 1 test/integration/production/test/index.test.js'
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testSafariOld:

2
.gitignore vendored
View File

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

View File

@@ -20,3 +20,6 @@ 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

@@ -7,20 +7,29 @@
### 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. Resolve all merge conflicts and complete merge
5. `git push`
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`
- If it fails, run `git subrepo clean nextjs` and try again
5. Run `yarn`
6. Run `yarn manypkg check` and optionally `yarn manypkg fix` to fix any issues
7. Run `yarn lint` - fix any issues
8. Run `yarn build` - fix any issues
9. Under `nextjs/`, run `./check-pre-compiled.sh` and commit the changes
10. Run `yarn test:nextjs-size` and update tests if there are any failures
11. Open PR and fix any failing tests
12. Any doc updates?
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`

3
CONTRIBUTOR_STATS.md Normal file
View File

@@ -0,0 +1,3 @@
# 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-286-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-304-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">
@@ -221,6 +221,14 @@ _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 -->
@@ -280,7 +288,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></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>
</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>
@@ -558,13 +566,13 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<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></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="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></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="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>
@@ -595,15 +603,39 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<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></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></td>
<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: 12 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

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

View File

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

View File

@@ -1,28 +1,22 @@
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}
resetKeys={[router.asPath]}
onReset={reset}
>
<ErrorBoundary FallbackComponent={RootErrorFallback} onReset={reset}>
{getLayout(<Component {...pageProps} />)}
</ErrorBoundary>
<ReactQueryDevtools />

View File

@@ -10,7 +10,14 @@ import {Routes} from ".blitz"
export const EditProject = () => {
const router = useRouter()
const projectId = useParam("projectId", "number")
const [project, {setQueryData}] = useQuery(getProject, {id: projectId})
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 [updateProjectMutation] = useMutation(updateProject)
return (

View File

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

View File

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

View File

@@ -1,12 +1,10 @@
import {resolver} from "blitz"
import db from "db"
import * as z from "zod"
import {z} from "zod"
const CreateProject = z
.object({
name: z.string(),
})
.nonstrict()
const CreateProject = z.object({
name: z.string(),
})
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,12 +1,10 @@
import {resolver} from "blitz"
import db from "db"
import * as z from "zod"
import {z} from "zod"
const DeleteProject = z
.object({
id: z.number(),
})
.nonstrict()
const DeleteProject = z.object({
id: z.number(),
})
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,13 +1,11 @@
import {resolver} from "blitz"
import db from "db"
import * as z from "zod"
import {z} from "zod"
const UpdateProject = z
.object({
id: z.number(),
name: z.string(),
})
.nonstrict()
const UpdateProject = z.object({
id: z.number(),
name: z.string(),
})
export default resolver.pipe(
resolver.zod(UpdateProject),

View File

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

View File

@@ -28,18 +28,16 @@
"trailingComma": "all"
},
"dependencies": {
"@prisma/client": "2.19.0",
"blitz": "0.35.0",
"@prisma/client": "2.24.1",
"blitz": "0.38.3-canary.1",
"final-form": "4.20.1",
"passport-auth0": "1.4.0",
"passport-github2": "0.1.12",
"passport-twitter": "1.0.4",
"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"
"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"
},
"devDependencies": {
"@cypress/skip-test": "2.6.0",
@@ -50,7 +48,7 @@
"@types/passport-github2": "1.2.4",
"@types/passport-twitter": "1.0.36",
"@types/preview-email": "2.0.0",
"@types/react": "17.0.2",
"@types/react": "17.0.13",
"cross-env": "7.0.3",
"cypress": "6.2.1",
"eslint": "7.21.0",
@@ -59,8 +57,7 @@
"prettier": "2.2.1",
"pretty-quick": "3.1.0",
"preview-email": "3.0.3",
"start-server-and-test": "1.11.7",
"typescript": "4.1.5"
"start-server-and-test": "1.11.7"
},
"private": true
}

View File

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

View File

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

View File

@@ -1,31 +1,26 @@
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}
resetKeys={[router.asPath]}
onReset={reset}
>
<ErrorBoundary FallbackComponent={RootErrorFallback} onReset={reset}>
{getLayout(<Component {...pageProps} />)}
</ErrorBoundary>
)
}
function RootErrorFallback({error, resetErrorBoundary}: FallbackProps) {
function RootErrorFallback({error, resetErrorBoundary}: ErrorFallbackProps) {
if (error instanceof AuthenticationError) {
return <LoginForm onSuccess={resetErrorBoundary} />
} else if (error instanceof AuthorizationError) {

View File

@@ -30,23 +30,20 @@
"trailingComma": "all"
},
"dependencies": {
"@prisma/client": "2.19.0",
"blitz": "0.35.0",
"@prisma/client": "2.24.1",
"blitz": "0.38.3-canary.1",
"final-form": "4.20.1",
"prisma": "2.19.0",
"react": "0.0.0-experimental-6a589ad71",
"react-dom": "0.0.0-experimental-6a589ad71",
"react-error-boundary": "3.1.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",
"secure-password": "4.0.0",
"typescript": "4.1.5",
"zod": "1.11.11"
"secure-password": "4.0.0"
},
"devDependencies": {
"@cypress/skip-test": "2.6.0",
"@testing-library/react": "11.2.5",
"@testing-library/react-hooks": "^4.0.1",
"@types/react": "17.0.2",
"@types/react": "17.0.13",
"@types/secure-password": "3.1.0",
"cypress": "6.2.1",
"eslint": "7.21.0",

View File

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

View File

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

View File

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

View File

@@ -28,33 +28,29 @@
]
},
"dependencies": {
"blitz": "0.35.0",
"blitz": "0.38.3-canary.1",
"final-form": "4.20.1",
"graphql": "15.5.0",
"graphql-request": "3.4.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",
"zod": "1.11.11"
"react": "18.0.0-alpha-ed6c091fe-20210701",
"react-dom": "18.0.0-alpha-ed6c091fe-20210701",
"react-final-form": "6.5.2"
},
"devDependencies": {
"@testing-library/react": "11.2.5",
"@testing-library/react-hooks": "^4.0.1",
"@types/react": "17.0.2",
"@types/react": "17.0.13",
"@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.22.0",
"eslint-plugin-react-hooks": "~4.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",
"husky": "5.1.2",
"start-server-and-test": "1.11.7",
"typescript": "4.1.5"
"start-server-and-test": "1.11.7"
},
"private": true
}

View File

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

View File

@@ -32,26 +32,25 @@
]
},
"dependencies": {
"@prisma/client": "2.19.0",
"blitz": "0.35.0",
"prisma": "2.19.0",
"react": "0.0.0-experimental-6a589ad71",
"react-dom": "0.0.0-experimental-6a589ad71"
"@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"
},
"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.22.0",
"eslint-plugin-react-hooks": "~4.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",
"husky": "5.1.2",
"lint-staged": "10.5.4",
"prettier": "2.2.1",
"pretty-quick": "3.1.0",
"typescript": "4.1.5"
"pretty-quick": "3.1.0"
},
"private": true
}

View File

@@ -1,23 +1,17 @@
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}
resetKeys={[router.asPath]}
onReset={reset}
>
<ErrorBoundary FallbackComponent={RootErrorFallback} onReset={reset}>
{getLayout(<Component {...pageProps} />)}
</ErrorBoundary>
)

View File

@@ -32,20 +32,17 @@
]
},
"dependencies": {
"@prisma/client": "2.19.0",
"blitz": "0.35.0",
"@prisma/client": "2.24.1",
"blitz": "0.38.3-canary.1",
"final-form": "4.20.1",
"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"
"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"
},
"devDependencies": {
"@types/preview-email": "2.0.0",
"@types/react": "17.0.2",
"@types/react": "17.0.13",
"eslint": "7.21.0",
"husky": "5.1.2",
"lint-staged": "10.5.4",

View File

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

View File

@@ -1,13 +1,5 @@
import db, {Product} from "db"
import db 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,7 +1,15 @@
import {Suspense, useState} from "react"
import {useQuery, Link, useRouterQuery, invalidateQuery, setQueryData} from "blitz"
import getProducts from "app/products/queries/getProducts"
import {meanPrice} from "app/admin/api/users"
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)
}
function reversedProductList(productsList) {
return {...productsList, products: [...productsList.products].reverse()}

View File

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

View File

@@ -1,10 +1,17 @@
import {Link, BlitzPage, InferGetStaticPropsType} from "blitz"
import getProducts, {averagePrice} from "../../queries/getProducts"
import getProducts from "../../queries/getProducts"
import {sum} from "lodash"
import {Product} from "@prisma/client"
// 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,11 +1,5 @@
import {Middleware, paginate} from "blitz"
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
}
import db, {Prisma} from "db"
type GetProductsInput = {
where?: Prisma.ProductFindManyArgs["where"]

View File

@@ -20,20 +20,17 @@
"trailingComma": "all"
},
"dependencies": {
"@prisma/client": "2.19.0",
"blitz": "0.35.0",
"@prisma/client": "2.24.1",
"blitz": "0.38.3-canary.1",
"final-form": "4.20.1",
"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"
"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"
},
"devDependencies": {
"@types/react": "17.0.2",
"@types/react": "17.0.13",
"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.35.1",
"version": "0.38.3-canary.1",
"packages": ["packages/*"],
"npmClient": "yarn",
"useWorkspaces": true,

4
nextjs/.alexignore Normal file
View File

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

View File

@@ -2,6 +2,8 @@ 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
@@ -15,6 +17,7 @@ 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
packages/next/lib/regexr/**/*

View File

@@ -120,7 +120,7 @@
"rules": {
"no-shadow": ["warn", { "builtinGlobals": false }],
"import/no-extraneous-dependencies": [
"error",
"off",
{ "devDependencies": false }
]
}

View File

@@ -1,8 +1,8 @@
FROM node:10-buster
FROM node:14-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/zeit/next-stats-action"
LABEL repository="https://github.com/vercel/next-stats-action"
COPY . /next-stats

View File

@@ -8,6 +8,14 @@
"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

@@ -156,15 +156,15 @@ jobs:
steps:
- run: exit 0
testFutureDependencies:
name: Webpack 5 (Basic, Production, Acceptance)
testLegacyWebpack:
name: Webpack 4 (Basic, Production, Acceptance)
runs-on: ubuntu-latest
needs: build
env:
NEXT_TELEMETRY_DISABLED: 1
NEXT_TEST_JOB: 1
HEADLESS: true
NEXT_PRIVATE_TEST_WEBPACK5_MODE: 1
NEXT_PRIVATE_TEST_WEBPACK4_MODE: 1
steps:
- uses: actions/cache@v2
@@ -174,50 +174,16 @@ jobs:
path: ./*
key: ${{ github.sha }}
- 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
- 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'}}
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)
runs-on: ubuntu-latest
needs: build
env:
HEADLESS: true
BROWSERNAME: 'firefox'
BROWSER_NAME: 'firefox'
NEXT_TELEMETRY_DISABLED: 1
steps:
- uses: actions/cache@v2
@@ -226,7 +192,7 @@ jobs:
with:
path: ./*
key: ${{ github.sha }}
- run: node run-tests.js test/integration/production/test/index.test.js
- run: node run-tests.js -c 1 test/integration/production/test/index.test.js
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testSafari:
@@ -235,7 +201,7 @@ jobs:
needs: build
env:
BROWSERSTACK: true
BROWSERNAME: 'safari'
BROWSER_NAME: 'safari'
NEXT_TELEMETRY_DISABLED: 1
SKIP_LOCAL_SELENIUM_SERVER: true
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
@@ -247,7 +213,7 @@ jobs:
with:
path: ./*
key: ${{ github.sha }}
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js test/integration/production/test/index.test.js'
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js -c 1 test/integration/production/test/index.test.js'
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testSafariOld:
@@ -257,7 +223,7 @@ jobs:
env:
BROWSERSTACK: true
LEGACY_SAFARI: true
BROWSERNAME: 'safari'
BROWSER_NAME: 'safari'
NEXT_TELEMETRY_DISABLED: 1
SKIP_LOCAL_SELENIUM_SERVER: true
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
@@ -269,7 +235,7 @@ jobs:
with:
path: ./*
key: ${{ github.sha }}
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js test/integration/production-nav/test/index.test.js'
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js -c 1 test/integration/production-nav/test/index.test.js'
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
publishRelease:

View File

@@ -1,55 +0,0 @@
on:
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '0 0,12 * * *'
name: Test react@experimental
jobs:
# build:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v2
# - run: yarn install --frozen-lockfile --check-files
# env:
# NEXT_TELEMETRY_DISABLED: 1
# - run: yarn upgrade react@next react-dom@next -W --dev
# - uses: actions/cache@v2
# id: cache-build
# with:
# path: ./*
# key: ${{ github.sha }}
testAll:
name: Test All
runs-on: ubuntu-latest
# needs: build
env:
NEXT_TELEMETRY_DISABLED: 1
HEADLESS: true
NEXT_PRIVATE_SKIP_SIZE_TESTS: true
NEXT_PRIVATE_REACT_ROOT: 1
strategy:
fail-fast: false
matrix:
group: [1, 2, 3, 4, 5, 6]
steps:
# - uses: actions/cache@v2
# id: restore-build
# with:
# path: ./*
# key: ${{ github.sha }}
- uses: actions/checkout@v2
- run: yarn install --frozen-lockfile --check-files
- run: yarn upgrade react@experimental react-dom@experimental -W --dev
# TODO: remove after we fix watchpack watching too much
- run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
- run: node run-tests.js --timings -g ${{ matrix.group }}/6 -c 3

View File

@@ -26,6 +26,7 @@ jobs:
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 = f485e5670f466b8be3a85c5d8cc3fb487157bbc8
parent = 9e96eaf6e729fb60e10c23c6643bced8dd0e479f
commit = 4be32b7a54fa68dfcf66d4a5cc7744409c409c7f
parent = 194a3720ce56aa3fabace4b07c5faeac1121b8d6
method = merge
cmdver = 0.4.3

View File

@@ -16,3 +16,6 @@ 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

@@ -34,7 +34,7 @@ pr:
variables:
YARN_CACHE_FOLDER: $(Pipeline.Workspace)/.yarn
NEXT_TELEMETRY_DISABLED: '1'
node_version: ^10.10.0
node_version: ^12.0.0
stages:
- stage: Build
@@ -86,7 +86,7 @@ stages:
path: $(System.DefaultWorkingDirectory)
displayName: Cache Build
- script: |
yarn testie --forceExit test/integration/production/ test/integration/css-client-nav/
yarn testie --forceExit test/integration/production/ test/integration/css-client-nav/ test/integration/rewrites-has-condition/
displayName: 'Run tests'
- job: test_unit
@@ -117,13 +117,13 @@ stages:
vmImage: 'windows-2019'
strategy:
matrix:
node-10-1:
nodejs-1:
group: 1/4
node-10-2:
nodejs-2:
group: 2/4
node-10-3:
nodejs-3:
group: 3/4
node-10-4:
nodejs-4:
group: 4/4
steps:
- checkout: none

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
# Contributing to Next.js
Our Commitment to Open Source can be found [here](https://vercel.com/oss).
Read about our [Commitment to Open Source](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 just one test in the `production` test suite:
Running one test in the `production` test suite:
```sh
yarn testonly --testPathPattern "production" -t "should allow etag header support"
@@ -124,12 +124,19 @@ 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 the custom types described [here](https://stackoverflow.com/a/50601125).
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).

View File

@@ -17,6 +17,14 @@ 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

@@ -52,6 +52,9 @@ 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 [here](https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics).
> Read more about [sending results to Google Analytics](https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics).
## TypeScript

View File

@@ -0,0 +1,139 @@
---
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, telemetry
build, start, export, dev, lint, telemetry
Options
--version, -v Version number
@@ -74,6 +74,20 @@ 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.
@@ -84,6 +98,27 @@ 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,13 +12,22 @@ 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. Yarn will be used by default if it's installed
- **--use-npm** - Explicitly tell the CLI to bootstrap the app using npm. To bootstrap using yarn we recommend running `yarn create next-app`
### Why use Create Next App?

View File

@@ -4,7 +4,14 @@ description: Learn more about setting a base path in Next.js
# Base Path
> 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>
<summary><b>Version History</b></summary>
| Version | Changes |
| -------- | ---------------- |
| `v9.5.0` | Base Path added. |
</details>
To deploy a Next.js application under a sub-path of a domain you can use the `basePath` config option.

View File

@@ -24,9 +24,21 @@ 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).
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:
Asset prefix support does not influence the following paths:
```
/_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:
- 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,7 +15,6 @@ 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)
@@ -24,10 +23,6 @@ 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

@@ -4,8 +4,6 @@ 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>
@@ -13,6 +11,16 @@ 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`:
@@ -365,3 +373,14 @@ 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

@@ -0,0 +1,39 @@
---
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 [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`:
`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`:
```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 [here](https://github.com/vercel/next.js/blob/canary/packages/next/next-server/server/config-shared.ts#L33).
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).
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,8 +4,6 @@ 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>
@@ -13,6 +11,16 @@ 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.
@@ -132,7 +140,7 @@ module.exports = {
// if the header `x-redirect-me` is present,
// this redirect will be applied
{
source: '/:path*',
source: '/:path((?!another-page$).*)',
has: [
{
type: 'header',
@@ -162,12 +170,12 @@ module.exports = {
},
],
permanent: false,
destination: '/:path*/:page',
destination: '/another/:path*',
},
// if the header `x-authorized` is present and
// contains a matching value, this redirect will be applied
{
source: '/:path*',
source: '/',
has: [
{
type: 'header',
@@ -181,7 +189,7 @@ module.exports = {
// if the host is `example.com`,
// this redirect will be applied
{
source: '/:path*',
source: '/:path((?!another-page$).*)',,
has: [
{
type: 'host',

View File

@@ -4,8 +4,6 @@ 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>
@@ -13,9 +11,19 @@ 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 are only available on the Node.js environment and do not affect client-side routing.
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.
To use rewrites you can use the `rewrites` key in `next.config.js`:
@@ -32,6 +40,8 @@ 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.
@@ -48,8 +58,8 @@ module.exports = {
return {
beforeFiles: [
// These rewrites are checked after headers/redirects
// and before pages/public files which allows overriding
// page files
// and before all files including _next/public files which
// allows overriding page files
{
source: '/some-page',
destination: '/somewhere-else',
@@ -69,7 +79,7 @@ module.exports = {
// and dynamic routes are checked
{
source: '/:path*',
destination: 'https://my-old-site.com',
destination: `https://my-old-site.com/:path*`,
},
],
}
@@ -317,7 +327,7 @@ module.exports = {
}
```
See additional information on incremental adoption [in the docs here](https://nextjs.org/docs/migrating/incremental-adoption).
See additional information on incremental adoption [in the docs here](/docs/migrating/incremental-adoption.md).
### Rewrites with basePath support

View File

@@ -4,7 +4,14 @@ description: Configure Next.js pages to resolve with or without a trailing slash
# Trailing Slash
> 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>
<summary><b>Version History</b></summary>
| Version | Changes |
| -------- | --------------------- |
| `v9.5.0` | Trailing Slash added. |
</details>
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 it [here](/docs/advanced-features/amp-support/introduction.md).
> AMP support is one of our advanced features, you can [read more about AMP here](/docs/advanced-features/amp-support/introduction.md).
To enable AMP, add the following config to your page:

View File

@@ -14,11 +14,12 @@ description: Enable Image Optimization with the built-in Image component.
<details>
<summary><b>Version History</b></summary>
| Version | Changes |
| --------- | ------------------------ |
| `v10.0.5` | `loader` prop added. |
| `v10.0.1` | `layout` prop added. |
| `v10.0.0` | `next/image` introduced. |
| 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. |
</details>
@@ -39,17 +40,13 @@ 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="/me.png"
alt="Picture of the author"
width={500}
height={500}
/>
<Image src={profilePic} alt="Picture of the author" />
<p>Welcome to my homepage!</p>
</>
)
@@ -64,7 +61,11 @@ The `<Image />` component requires the following properties.
### src
The path or URL to the source image. This is required.
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).
When using an external URL, you must add it to
[domains](/docs/basic-features/image-optimization.md#domains) in
@@ -74,13 +75,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 unless [`layout="fill"`](#layout).
Required, except for statically imported images, or those with [`layout="fill"`](#layout).
### height
The height of the image, in pixels. Must be an integer without a unit.
Required unless [`layout="fill"`](#layout).
Required, except for statically imported images, or those with [`layout="fill"`](#layout).
## Optional Props
@@ -101,8 +102,7 @@ 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
[object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit).
the parent element, usually paired with the [`objectFit`](#objectFit) property.
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,6 +163,21 @@ 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
@@ -197,6 +212,22 @@ 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

@@ -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`
- `pathname`: `String` - Current route. That is the path of the page in `/pages`, the configured `basePath` or `locale` is not included.
- `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,6 +49,7 @@ 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).
@@ -74,6 +75,7 @@ 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.
@@ -111,6 +113,8 @@ export default function Page() {
}
```
> **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

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 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)
- `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)
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(json)` - Sends a JSON response. `json` must be a valid JSON object
- `res.json(body)` - Sends a JSON response. `body` must be a [serialiazable object](https://developer.mozilla.org/en-US/docs/Glossary/Serialization)
- `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".

View File

@@ -48,7 +48,7 @@ const Profile = () => {
export default Profile
```
You can view this example in action [here](https://next-with-iron-session.vercel.app/). Check out the [`with-iron-session`](https://github.com/vercel/next.js/tree/canary/examples/with-iron-session) example to see how it works.
You can view this [example in action](https://next-with-iron-session.vercel.app/). Check out the [`with-iron-session`](https://github.com/vercel/next.js/tree/canary/examples/with-iron-session) example to see how it works.
### Authenticating Server-Rendered Pages
@@ -127,77 +127,23 @@ Both of these libraries support either authentication pattern. If you're interes
- [with-passport](https://github.com/vercel/next.js/tree/canary/examples/with-passport)
- [with-passport-and-next-connect](https://github.com/vercel/next.js/tree/canary/examples/with-passport-and-next-connect)
### Firebase
### Other Providers
To see examples with other authentication providers, check out the [examples folder](https://github.com/vercel/next.js/tree/canary/examples).
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-firebase-authentication">with-firebase-authentication</a></li>
</ul>
</details>
When using Firebase Authentication, we recommend using the static generation pattern.
It is possible to use the Firebase Client SDK to generate an ID token and forward it directly to Firebase's REST API on the server to log-in. However, requests to Firebase might take some time to resolve, depending on your user's location.
You can either use [FirebaseUI](https://github.com/firebase/firebaseui-web-react) for a drop-in UI, or create your own with a [custom React hook](https://usehooks.com/useAuth/).
### Magic (Passwordless)
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-magic">with-magic</a></li>
</ul>
</details>
[Magic](https://magic.link/), which uses [passwordless login](https://magic.link/), supports the static generation pattern. Similar to Firebase, a [unique identifier](https://w3c-ccg.github.io/did-primer/) has to be created on the client-side and then forwarded as a header to log-in. Then, Magic's Node SDK can be used to exchange the indentifier for a user's information.
### Auth0
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/auth0">auth0</a></li>
</ul>
</details>
[Auth0](https://auth0.com/) can support both authentication patterns. You can also utilize [API routes](/docs/api-routes/introduction.md) for logging in/out and retrieving user information. After logging in using the [Auth0 SDK](https://github.com/auth0/nextjs-auth0), you can utilize static generation or `getServerSideProps` for server-side rendering.
### Supabase
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-supabase-auth-realtime-db">with-supabase-auth-realtime-db</a></li>
</ul>
</details>
[Supabase](https://supabase.io/) is an open source Firebase alternative that supports many of its features, including authentication. It allows for row level security using JWT tokens and supports third party logins. Either authentication pattern is supported.
### Userbase
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-userbase">with-userbase</a></li>
</ul>
</details>
[Userbase](https://userbase.com/) supports the static generation pattern for authentication. It's open source and allows for a high level of security with end-to-end encryption. You can learn more about it in their [official site](https://userbase.com/).
### SuperTokens
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-supertokens">with-supertokens</a></li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-nhost-auth-realtime-graphql">with-nhost-auth-realtime-graphql</a></li>
</ul>
</details>
[SuperTokens](https://supertokens.io) is a highly customizable, open-source solution split into modules (so you only use what you need).
SuperTokens currently supports credentials login, email verification, password reset flows, third-party logins, and cookie based sessions with rotating refresh tokens.
## Related
For more information on what to do next, we recommend the following sections:

View File

@@ -181,19 +181,6 @@ module.exports = {
}
```
## Less and Stylus Support
To support importing `.less` or `.styl` files you can use the following plugins:
- [@zeit/next-less](https://github.com/vercel/next-plugins/tree/master/packages/next-less)
- [@zeit/next-stylus](https://github.com/vercel/next-plugins/tree/master/packages/next-stylus)
If using the less plugin, don't forget to add a dependency on less as well, otherwise you'll see an error like:
```bash
Error: Cannot find module 'less'
```
## CSS-in-JS
<details>

View File

@@ -72,8 +72,8 @@ The `context` parameter is an object containing the following keys:
`getStaticProps` should return an object with:
- `props` - A **required** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization)
- `revalidate` - An **optional** amount in seconds after which a page re-generation can occur. More on [Incremental Static Regeneration](#incremental-static-regeneration)
- `props` - An **optional** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization)
- `revalidate` - An **optional** amount in seconds after which a page re-generation can occur (defaults to: `false` or no revalidating). More on [Incremental Static Regeneration](#incremental-static-regeneration)
- `notFound` - An **optional** boolean value to allow the page to return a 404 status and page. Below is an example of how it works:
```js
@@ -222,20 +222,27 @@ export default Blog
### Incremental Static Regeneration
> This feature was introduced in [Next.js 9.5](https://nextjs.org/blog/next-9-5#stable-incremental-static-regeneration) and up. If youre using older versions of Next.js, please upgrade before trying Incremental Static Regeneration.
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://reactions-demo.vercel.app/">Static Reactions Demo</a></li>
<li><a href="https://nextjs.org/commerce">Next.js Commerce</a></li>
<li><a href="https://reactions-demo.vercel.app/">GitHub Reactions Demo</a></li>
<li><a href="https://static-tweet.vercel.app/">Static Tweet Demo</a></li>
</ul>
</details>
With [`getStaticProps`](#getstaticprops-static-generation) you don't have to stop relying on dynamic content, as **static content can also be dynamic**. Incremental Static Regeneration allows you to update _existing_ pages by re-rendering them in the background as traffic comes in.
<details>
<summary><b>Version History</b></summary>
Inspired by [stale-while-revalidate](https://tools.ietf.org/html/rfc5861), background regeneration ensures traffic is served uninterruptedly, always from static storage, and the newly built page is pushed only after it's done generating.
| Version | Changes |
| -------- | ---------------- |
| `v9.5.0` | Base Path added. |
Consider our previous [`getStaticProps` example](#simple-example), but now with regeneration enabled:
</details>
Next.js allows you to create or update static pages _after_ youve built your site. Incremental Static Regeneration (ISR) enables you to use static-generation on a per-page basis, **without needing to rebuild the entire site**. With ISR, you can retain the benefits of static while scaling to millions of pages.
Consider our previous [`getStaticProps` example](#simple-example), but now with Incremental Static Regeneration enabled through the `revalidate` property:
```jsx
function Blog({ posts }) {
@@ -261,25 +268,42 @@ export async function getStaticProps() {
},
// Next.js will attempt to re-generate the page:
// - When a request comes in
// - At most once every second
revalidate: 1, // In seconds
// - At most once every 10 seconds
revalidate: 10, // In seconds
}
}
// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// the path has not been generated.
export async function getStaticPaths() {
const res = await fetch('https://.../posts')
const posts = await res.json()
// Get the paths we want to pre-render based on posts
const paths = posts.map((post) => ({
params: { id: post.id },
}))
// We'll pre-render only these paths at build time.
// { fallback: blocking } will server-render pages
// on-demand if the path doesn't exist.
return { paths, fallback: 'blocking' }
}
export default Blog
```
Now the list of blog posts will be revalidated once per second; if you add a new blog post it will be available almost immediately, without having to re-build your app or make a new deployment.
When a request is made to a page that was pre-rendered at build time, it will initially show the cached page.
This works perfectly with [`fallback: true`](#fallback-true). Because now you can have a list of posts that's always up to date with the latest posts, and have a [blog post page](#fallback-pages) that generates blog posts on-demand, no matter how many posts you add or update.
- Any requests to the page after the initial request and before 10 seconds are also cached and instantaneous.
- After the 10-second window, the next request will still show the cached (stale) page
- Next.js triggers a regeneration of the page in the background.
- Once the page has been successfully generated, Next.js will invalidate the cache and show the updated product page. If the background regeneration fails, the old page remains unaltered.
#### Static content at scale
When a request is made to a path that hasnt been generated, Next.js will server-render the page on the first request. Future requests will serve the static file from the cache.
Unlike traditional SSR, [Incremental Static Regeneration](#incremental-static-regeneration) ensures you retain the benefits of static:
- No spikes in latency. Pages are served consistently fast
- Pages never go offline. If the background page re-generation fails, the old page remains unaltered
- Low database and backend load. Pages are re-computed at most once concurrently
To learn how to persist the cache globally and handle rollbacks, learn more about [Incremental Static Regeneration](https://vercel.com/docs/next.js/incremental-static-regeneration).
### Reading files: Use `process.cwd()`
@@ -648,7 +672,7 @@ The `context` parameter is an object containing the following keys:
`getServerSideProps` should return an object with:
- `props` - A **required** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization)
- `props` - An **optional** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization)
- `notFound` - An **optional** boolean value to allow the page to return a 404 status and page. Below is an example of how it works:
```js

View File

@@ -0,0 +1,175 @@
---
description: Next.js provides an integrated ESLint experience by default. These conformance rules help you use Next.js in the optimal way.
---
# ESLint
Since version **11.0.0**, Next.js provides an integrated [ESLint](https://eslint.org/) experience out of the box. Add `next lint` as a script to `package.json`:
```json
"scripts": {
"lint": "next lint"
}
```
Then run `npm run lint` or `yarn lint`:
```bash
yarn lint
```
If you don't already have ESLint configured in your application, you will be guided through the installation of the required packages.
```bash
yarn lint
# You'll see instructions like these:
#
# Please install eslint and eslint-config-next by running:
#
# yarn add --dev eslint eslint-config-next
#
# ...
```
If no ESLint configuration is present, Next.js will create an `.eslintrc` file in the root of your project and automatically configure it with the base configuration:
```js
{
"extends": "next"
}
```
You can now run `next lint` every time you want to run ESLint to catch errors.
> The default base configuration (`"extends": "next"`) can be updated at any time and will only be included if no ESLint configuration is present.
We recommend using an appropriate [integration](https://eslint.org/docs/user-guide/integrations#editors) to view warnings and errors directly in your code editor during development.
## Linting During Builds
Once ESLint has been set up, it will automatically run during every build (`next build`). Errors will fail the build, while warnings will not.
If you do not want ESLint to run as a build step, refer to the documentation for [Ignoring ESLint](/docs/api-reference/next.config.js/ignoring-eslint.md):
## Linting Custom Directories
By default, Next.js will run ESLint for all files in the `pages/`, `components/`, and `lib/` directories. However, you can specify which directories using the `dirs` option in the `eslint` config in `next.config.js` for production builds:
```js
module.exports = {
eslint: {
dirs: ['pages', 'utils'], // Only run ESLint on the 'pages' and 'utils' directories during production builds (next build)
},
}
```
Similarly, the `--dir` flag can be used for `next lint`:
```bash
yarn lint --dir pages --dir utils
```
## ESLint Plugin
Next.js provides an ESLint plugin, [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next), making it easier to catch common issues and problems in a Next.js application. The full set of rules is as follows:
| | Rule | Description |
| :-: | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| ✔️ | [next/google-font-display](https://nextjs.org/docs/messages/google-font-display) | Enforce optional or swap font-display behavior with Google Fonts |
| ✔️ | [next/google-font-preconnect](https://nextjs.org/docs/messages/google-font-preconnect) | Enforce preconnect usage with Google Fonts |
| ✔️ | [next/link-passhref](https://nextjs.org/docs/messages/link-passhref) | Enforce passHref prop usage with custom Link components |
| ✔️ | [next/no-css-tags](https://nextjs.org/docs/messages/no-css-tags) | Prevent manual stylesheet tags |
| ✔️ | [next/no-document-import-in-page](https://nextjs.org/docs/messages/no-document-import-in-page) | Disallow importing next/document outside of pages/document.js |
| ✔️ | [next/no-head-import-in-document](https://nextjs.org/docs/messages/no-head-import-in-document) | Disallow importing next/head in pages/document.js |
| ✔️ | [next/no-html-link-for-pages](https://nextjs.org/docs/messages/no-html-link-for-pages) | Prohibit HTML anchor links to pages without a Link component |
| ✔️ | [next/no-img-element](https://nextjs.org/docs/messages/no-img-element) | Prohibit usage of HTML &lt;img&gt; element |
| ✔️ | [next/no-page-custom-font](https://nextjs.org/docs/messages/no-page-custom-font) | Prevent page-only custom fonts |
| ✔️ | [next/no-sync-scripts](https://nextjs.org/docs/messages/no-sync-scripts) | Forbid synchronous scripts |
| ✔️ | [next/no-title-in-document-head](https://nextjs.org/docs/messages/no-title-in-document-head) | Disallow using &lt;title&gt; with Head from next/document |
| ✔️ | [next/no-unwanted-polyfillio](https://nextjs.org/docs/messages/no-unwanted-polyfillio) | Prevent duplicate polyfills from Polyfill.io |
- ✔: Enabled in the recommended configuration
## Base Configuration
The Next.js base ESLint configuration is automatically generated when `next lint` is run for the first time:
```js
{
"extends": "next"
}
```
This configuration extends recommended rule sets from various ESLint plugins:
- [`eslint-plugin-react`](https://www.npmjs.com/package/eslint-plugin-react)
- [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks)
- [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next)
You can see the full details of the shareable configuration in the [`eslint-config-next`](https://www.npmjs.com/package/eslint-config-next) package.
## Disabling Rules
If you would like to modify or disable any rules provided by the supported plugins (`react`, `react-hooks`, `next`), you can directly change them using the `rules` property in your `.eslintrc`:
```js
{
"extends": "next",
"rules": {
"react/no-unescaped-entities": "off",
"@next/next/no-page-custom-font": "off",
}
}
```
> **Note**: If you need to also include a separate, custom ESLint configuration, it is highly recommended that `eslint-config-next` is extended last after other configurations. For example:
>
> ```
> {
> "extends": ["eslint:recommended", "next"]
> }
> ```
>
> The `next` configuration already handles setting default values for the `parser`, `plugins` and `settings` properties.
> There is no need to manually re-declare any of these properties unless you need a different configuration for your use case.
> If you include any other shareable configurations, you will need to make sure that these properties are not overwritten or modified.
### Core Web Vitals
A stricter `next/core-web-vitals` rule set can also be added in `.eslintrc`:
```
{
"extends": ["next", "next/core-web-vitals"]
}
```
`next/core-web-vitals` updates `eslint-plugin-next` to error on a number of rules that are warnings by default if they affect [Core Web Vitals](https://web.dev/vitals/).
> Both `next` and `next/core-web-vitals` entry points are automatically included for new applications built with [Create Next App](/docs/api-reference/create-next-app.md).
## Usage with Prettier
ESLint also contains code formatting rules, which can conflict with your existing [Prettier](https://prettier.io/) setup. We recommend including [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) in your ESLint config to make ESLint and Prettier work together.
```js
{
"extends": ["next", "prettier"]
}
```
## Migrating Existing Config
If you already have ESLint configured in your application, we recommend extending directly from the Next.js ESLint plugin instead of the shareable configuration.
```js
module.exports = {
extends: [
//...
'plugin:@next/next/recommended',
],
}
```
This eliminates any risk of collisions that can occur due to importing the same plugin or parser across multiple configurations.

View File

@@ -0,0 +1,100 @@
---
description: Next.js supports built-in web font optimization to inline font CSS. Learn more here.
---
# Font Optimization
Since version **10.2**, Next.js has built-in web font optimization.
By default, Next.js will automatically inline font CSS at build time, eliminating an extra round trip to fetch font declarations. This results in improvements to [First Contentful Paint (FCP)](https://web.dev/fcp/) and [Largest Contentful Paint (LCP)](https://vercel.com/blog/core-web-vitals#largest-contentful-paint). For example:
```js
// Before
<link
href="https://fonts.googleapis.com/css2?family=Inter"
rel="stylesheet"
/>
// After
<style data-href="https://fonts.googleapis.com/css2?family=Inter">
@font-face{font-family:'Inter';font-style:normal...
</style>
```
## Usage
To add a web font to your Next.js application, override `next/head`. For example, you can add a font to a specific page:
```js
// pages/index.js
import Head from 'next/head'
export default function IndexPage() {
return (
<div>
<Head>
<link
href="https://fonts.googleapis.com/css2?family=Inter"
rel="stylesheet"
/>
</Head>
<p>Hello world!</p>
</div>
)
}
```
or to your entire application with a [Custom `Document`](/docs/advanced-features/custom-document.md).
```js
// pages/_document.js
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
render() {
return (
<Html>
<Head>
<link
href="https://fonts.googleapis.com/css2?family=Inter"
rel="stylesheet"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
```
Automatic Webfont Optimization currently supports Google Fonts and Typekit with support for other font providers coming soon. We're also planning to add control over [loading strategies](https://github.com/vercel/next.js/issues/21555) and `font-display` values.
## Disabling Optimization
If you do not want Next.js to optimize your fonts, you can opt-out.
```js
// next.config.js
module.exports = {
optimizeFonts: false,
}
```
## Related
For more information on what to do next, we recommend the following sections:
<div class="card">
<a href="/docs/advanced-features/custom-document.md">
<b>Custom Document</b>
<small>Learn how to augment your application's html and body tags.</small>
</a>
</div>

View File

@@ -50,6 +50,39 @@ function Home() {
export default Home
```
## Image Imports
You can `import` images that live in your project. (Note that `require` is not supported—only `import`.)
With direct `import`s, `width`, `height`, and `blurDataURL` will be automatically provided to the image component. Alt text is still needed separately.
```js
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"
// width={500} automatically provided
// height={500} automatically provided
// blurDataURL="data:..." automatically provided
// Optionally allows to add a blurred version of the image while loading
// placeholder="blur"
/>
<p>Welcome to my homepage!</p>
</>
)
}
```
For dynamic or remote images, you'll have to provide [`width`](/docs/api-reference/next/image#width), [`height`](/docs/api-reference/next/image#height) and [`blurDataURL`](/docs/api-reference/next/image#blurdataurl) manually.
## Properties
[View all properties](/docs/api-reference/next/image.md) available to the `next/image` component.
## Configuration
@@ -138,6 +171,22 @@ module.exports = {
}
```
### Disable Static Imports
The default behavior allows you to import static files such as `import icon from './icon.png` and then pass that to the `src` property.
In some cases, you may wish to disable this feature if it conflicts with other plugins that expect the import to behave differently.
You can disable static image imports with the following configuration below.
```js
module.exports = {
images: {
disableStaticImages: true,
},
}
```
## Related
For more information on what to do next, we recommend the following sections:

View File

@@ -0,0 +1,129 @@
---
description: Next.js helps you optimize loading third-party scripts with the built-in next/script component.
---
# Script Component
<details>
<summary><b>Version History</b></summary>
| Version | Changes |
| --------- | ------------------------- |
| `v11.0.0` | `next/script` introduced. |
</details>
The Next.js Script component enables developers to set the loading priority of third-party scripts to save developer time and improve loading performance.
Websites often need third parties for things like analytics, ads, customer support widgets, and consent management. However, these scripts tend to be heavy on loading performance and can drag down the user experience. Developers often struggle to decide where to place them in an application for optimal loading.
With `next/script`, you can define the `strategy` property and Next.js will optimize loading for the script:
- `beforeInteractive`: For critical scripts that need to be fetched and executed **before** the page is interactive, such as bot detection and consent management. These scripts are injected into the initial HTML from the server and run before self-bundled JavaScript is executed.
- `afterInteractive` (**default**): For scripts that can fetch and execute **after** the page is interactive, such as tag managers and analytics. These scripts are injected on the client-side and will run after hydration.
- `lazyOnload` For scripts that can wait to load during idle time, such as chat support and social media widgets.
> **Note:** These loading strategies work the same for inline scripts wrapped with `<Script>`. See the inline scripts example below.
## Usage
Previously, you needed to define `script` tags inside the `Head` of your Next.js page.
```js
// Before
// pages/index.js
import Head from 'next/head'
function Home() {
return (
<>
<Head>
<script async src="https://www.google-analytics.com/analytics.js" />
</Head>
</>
)
}
```
With `next/script`, you no longer need to wrap scripts in `next/head`. Further, `next/script` should **not** be used in `pages/_document.js` as `next/script` has client-side functionality to ensure loading order. For example:
```js
// After
// pages/index.js
import Script from 'next/script'
function Home() {
return (
<>
<Script src="https://www.google-analytics.com/analytics.js" />
</>
)
}
```
## Examples
### Loading Polyfills
```js
import Script from 'next/script'
;<Script
src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver"
strategy="beforeInteractive"
/>
```
### Lazy-Loading
```js
import Script from 'next/script'
;<Script
src="https://connect.facebook.net/en_US/sdk.js"
strategy="lazyOnload"
/>
```
### Executing Code After Loading (`onLoad`)
```js
import Script from 'next/script'
;<Script
id="stripe-js"
src="https://js.stripe.com/v3/"
onLoad={() => {
this.setState({ stripe: window.Stripe('pk_test_12345') })
}}
/>
```
### Inline Scripts
```js
import Script from 'next/script'
<Script strategy="lazyOnload">
{`document.getElementById('banner').removeClass('hidden')`}
</Script>
// or
<Script
dangerouslySetInnerHTML={{
__html: `document.getElementById('banner').removeClass('hidden')`
}}
/>
```
### Forwarding Attributes
```js
import Script from 'next/script'
;<Script
src="https://www.google-analytics.com/analytics.js"
id="analytics"
nonce="XUENAJFW"
data-test="analytics"
/>
```

View File

@@ -11,9 +11,23 @@ description: Next.js supports TypeScript by default and has built-in types for p
</ul>
</details>
Next.js provides an integrated [TypeScript](https://www.typescriptlang.org/) experience out of the box, similar to an IDE.
Next.js provides an integrated [TypeScript](https://www.typescriptlang.org/)
experience out of the box, similar to an IDE.
To get started, create an empty `tsconfig.json` file in the root of your project:
## `create-next-app` support
You can create a TypeScript project with [`create-next-app`](https://nextjs.org/docs/api-reference/create-next-app) using the `--ts, --typescript` flag like so:
```
npx create-next-app --ts
# or
yarn create next-app --typescript
```
## Existing projects
To get started in an existing project, create an empty `tsconfig.json` file in
the root folder:
```bash
touch tsconfig.json
@@ -127,3 +141,26 @@ export default MyApp
Next.js automatically supports the `tsconfig.json` `"paths"` and `"baseUrl"` options.
You can learn more about this feature on the [Module Path aliases documentation](/docs/advanced-features/module-path-aliases.md).
## Type checking next.config.js
The `next.config.js` file must be a JavaScript file as it does not get parsed by Babel or TypeScript, however you can add some type checking in your IDE using JSDoc as below:
```js
// @ts-check
/**
* @type {import('next/dist/next-server/server/config').NextConfig}
**/
const nextConfig = {
/* config options here */
}
module.exports = nextConfig
```
## Incremental type checking
Since `v10.2.1` Next.js supports [incremental type checking](https://www.typescriptlang.org/tsconfig#incremental) when enabled in your `tsconfig.json`, this can help speed up type checking in larger applications.
It is highly recommended to be on at least `v4.3.2` of TypeScript to experience the [best performance](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3/#lazier-incremental) when leveraging this feature.

View File

@@ -6,7 +6,7 @@ description: Get started with Next.js in the official documentation, and learn m
Welcome to the Next.js documentation!
If you're new to Next.js we recommend that you start with the [learn course](https://nextjs.org/learn/basics/getting-started).
If you're new to Next.js we recommend that you start with the [learn course](https://nextjs.org/learn/basics/create-nextjs-app).
The interactive course with quizzes will guide you through everything you need to know to use Next.js.
@@ -27,6 +27,14 @@ npx create-next-app
yarn create next-app
```
If you want to start with a TypeScript project you can use the `--typescript` flag:
```bash
npx create-next-app --typescript
# or
yarn create next-app --typescript
```
After the installation is complete, follow the instructions to start the development server. Try editing `pages/index.js` and see the result on your browser.
For more information on how to use `create-next-app`, you can review the [`create-next-app` documentation](/docs/api-reference/create-next-app.md)
@@ -47,7 +55,8 @@ Open `package.json` and add the following `scripts`:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
"start": "next start",
"lint": "next lint"
}
```
@@ -56,6 +65,7 @@ These scripts refer to the different stages of developing an application:
- `dev` - Runs [`next dev`](/docs/api-reference/cli.md#development) which starts Next.js in development mode
- `build` - Runs [`next build`](/docs/api-reference/cli.md#build) which builds the application for production usage
- `start` - Runs [`next start`](/docs/api-reference/cli.md#production) which starts a Next.js production server
- `lint` - Runs [`next lint`](/docs/api-reference/cli.md#lint) which sets up Next.js' built-in ESLint configuration
Next.js is built around the concept of [pages](/docs/basic-features/pages.md). A page is a [React Component](https://reactjs.org/docs/components-and-props.html) exported from a `.js`, `.jsx`, `.ts`, or `.tsx` file in the `pages` directory.

View File

@@ -25,6 +25,10 @@
"title": "Image Optimization",
"path": "/docs/basic-features/image-optimization.md"
},
{
"title": "Font Optimization",
"path": "/docs/basic-features/font-optimization.md"
},
{
"title": "Static File Serving",
"path": "/docs/basic-features/static-file-serving.md"
@@ -33,6 +37,10 @@
"title": "Fast Refresh",
"path": "/docs/basic-features/fast-refresh.md"
},
{
"title": "ESLint",
"path": "/docs/basic-features/eslint.md"
},
{
"title": "TypeScript",
"path": "/docs/basic-features/typescript.md"
@@ -44,6 +52,10 @@
{
"title": "Supported Browsers and Features",
"path": "/docs/basic-features/supported-browsers-features.md"
},
{
"title": "Script",
"path": "/docs/basic-features/script.md"
}
]
},
@@ -196,6 +208,10 @@
{
"title": "Internationalized Routing",
"path": "/docs/advanced-features/i18n-routing.md"
},
{
"title": "Security Headers",
"path": "/docs/advanced-features/security-headers.md"
}
]
},
@@ -336,6 +352,10 @@
"title": "Configuring onDemandEntries",
"path": "/docs/api-reference/next.config.js/configuring-onDemandEntries.md"
},
{
"title": "Ignoring ESLint",
"path": "/docs/api-reference/next.config.js/ignoring-eslint.md"
},
{
"title": "Ignoring TypeScript Errors",
"path": "/docs/api-reference/next.config.js/ignoring-typescript-errors.md"

View File

@@ -236,4 +236,4 @@ If you've ejected Create React App, here are some things to consider:
## Learn More
You can learn more about Next.js by completing our [starter tutorial](https://nextjs.org/learn/basics/getting-started). If you have questions or if this guide didn't work for you, feel free to reach out to our community on [GitHub Discussions](https://github.com/vercel/next.js/discussions).
You can learn more about Next.js by completing our [starter tutorial](https://nextjs.org/learn/basics/create-nextjs-app). If you have questions or if this guide didn't work for you, feel free to reach out to our community on [GitHub Discussions](https://github.com/vercel/next.js/discussions).

View File

@@ -4,6 +4,133 @@ description: Learn how to upgrade Next.js.
# Upgrade Guide
## Upgrading from version 10 to 11
### Upgrade React version to latest
Most applications already use the latest version of React, with Next.js 11 the minimum React version has been updated to 17.0.2.
To upgrade you can run the following command:
```
npm install react@latest react-dom@latest
```
Or using `yarn`:
```
yarn add react@latest react-dom@latest
```
### Upgrade Next.js version to latest
To upgrade you can run the following command in the terminal:
```
npm install next@latest
```
or
```
yarn add next@latest
```
### Webpack 5
Webpack 5 is now the default for all Next.js applications. If you did not have custom webpack configuration your application is already using webpack 5. If you do have custom webpack configuration you can refer to the [Next.js webpack 5 documentation](https://nextjs.org/docs/messages/webpack5) for upgrading guidance.
### Cleaning the `distDir` is now a default
The build output directory (defaults to `.next`) is now cleared by default except for the Next.js caches. You can refer to [the cleaning `distDir` RFC](https://github.com/vercel/next.js/discussions/6009) for more information.
If your application was relying on this behavior previously you can disable the new default behavior by adding the `cleanDistDir: false` flag in `next.config.js`.
### `PORT` is now supported for `next dev` and `next start`
Next.js 11 supports the `PORT` environment variable to set the port the application has to run on. Using `-p`/`--port` is still recommended but if you were prohibited from using `-p` in any way you can now use `PORT` as an alternative:
Example:
```
PORT=4000 next start
```
### Remove `super.componentDidCatch()` from `pages/_app.js`
The `next/app` component's `componentDidCatch` has been deprecated since Next.js 9 as it's no longer needed and has since been a no-op, in Next.js 11 it has been removed.
If your `pages/_app.js` has a custom `componentDidCatch` method you can remove `super.componentDidCatch` as it is no longer needed.
### Remove `Container` from `pages/_app.js`
This export has been deprecated since Next.js 9 as it's no longer needed and has since been a no-op with a warning during development. In Next.js 11 it has been removed.
If your `pages/_app.js` imports `Container` from `next/app` you can remove `Container` as it has been removed. Learn more in [the documentation](https://nextjs.org/docs/messages/app-container-deprecated).
### Remove `props.url` usage from page components
This property has been deprecated since Next.js 4 and has since shown a warning during development. With the introduction of `getStaticProps` / `getServerSideProps` these methods already disallowed usage of `props.url`. In Next.js 11 it has been removed completely.
You can learn more in [the documentation](https://nextjs.org/docs/messages/url-deprecated).
### Remove `unsized` property on `next/image`
The `unsized` property on `next/image` was deprecated in Next.js 10.0.1. You can use `layout="fill"` instead. In Next.js 11 `unsized` was removed.
### Remove `modules` property on `next/dynamic`
The `modules` and `render` option for `next/dynamic` have been deprecated since Next.js 9.5 showing a warning that it has been deprecated. This was done in order to make `next/dynamic` close to `React.lazy` in API surface. In Next.js 11 the `modules` and `render` options have been removed.
This option hasn't been mentioned in the documentation since Next.js 8 so it's less likely that your application is using it.
If you application does use `modules` and `render` you can refer to [the documentation](https://nextjs.org/docs/messages/next-dynamic-modules).
### Remove `Head.rewind`
`Head.rewind` has been a no-op since Next.js 9.5, in Next.js 11 it was removed. You can safely remove your usage of `Head.rewind`.
### Moment.js locales excluded by default
Moment.js includes translations for a lot of locales by default. Next.js now automatically excludes these locales by default to optimize bundle size for applications using Moment.js.
To load a specific locale use this snippet:
```js
import moment from 'moment'
import 'moment/locale/ja'
moment.locale('ja')
```
You can opt-out of this new default by adding `excludeDefaultMomentLocales: false` to `next.config.js` if you do not want the new behavior, do note it's highly recommended to not disable this new optimization as it significantly reduces the size of Moment.js.
### Update usage of `router.events`
In case you're accessing `router.events` during rendering, in Next.js 11 `router.events` is no longer provided during pre-rendering. Ensure you're accessing `router.events` in `useEffect`:
```js
useEffect(() => {
const handleRouteChange = (url, { shallow }) => {
console.log(
`App is changing to ${url} ${
shallow ? 'with' : 'without'
} shallow routing`
)
}
router.events.on('routeChangeStart', handleRouteChange)
// If the component is unmounted, unsubscribe
// from the event with the `off` method:
return () => {
router.events.off('routeChangeStart', handleRouteChange)
}
}, [router])
```
If your application uses `router.router.events` which was an internal property that was not public please make sure to use `router.events` as well.
## React 16 to 17
React 17 introduced a new [JSX Transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) that brings a long-time Next.js feature to the wider React ecosystem: Not having to `import React from 'react'` when using JSX. When using React 17 Next.js will automatically use the new transform. This transform does not make the `React` variable global, which was an unintended side-effect of the previous Next.js implementation. A [codemod is available](/docs/advanced-features/codemods.md#add-missing-react-import) to automatically fix cases where you accidentally used `React` without importing it.
@@ -15,7 +142,13 @@ There were no breaking changes between version 9 and 10.
To upgrade run the following command:
```
npm install next@latest
npm install next@10
```
Or using `yarn`:
```
yarn add next@10
```
## Upgrading from version 8 to 9

View File

@@ -0,0 +1,14 @@
# Client-side Exception Occurred
#### Why This Error Occurred
In your production application a client-side error occurred that was not caught by an error boundary. Additional information should be visible in the console tab of your browser.
#### Possible Ways to Fix It
Add error boundaries in your React tree to gracefully handle client-side errors and render a fallback view when they occur.
### Useful Links
- [Error Boundaries Documentation](https://reactjs.org/docs/error-boundaries.html)
- [Custom Error Page Documentation](https://nextjs.org/docs/advanced-features/custom-error-page#more-advanced-error-page-customizing)

View File

@@ -0,0 +1,33 @@
# `future.webpack5` has been moved to `webpack5`
#### Why This Error Occurred
The `future.webpack5` option has been moved to `webpack5` in `next.config.js`.
#### Possible Ways to Fix It
If you had the value `true` you can remove the option as webpack 5 is now the default for all Next.js apps unless opted out.
If you had he value `false` you can update `next.config.js`:
Change `future.webpack5` to `webpack5`.
Current `next.config.js`:
```js
// next.config.js
module.exports = {
future: {
webpack5: false,
},
}
```
Updated `next.config.js`:
```js
// next.config.js
module.exports = {
webpack5: false,
}
```

View File

@@ -0,0 +1,36 @@
# Google Font Display
### Why This Error Occurred
For a Google Font, the `display` descriptor was either not assigned or set to `auto`, `fallback`, or `block`.
### Possible Ways to Fix It
For most cases, the best font display strategy for custom fonts is `optional`.
```jsx
import Head from 'next/head'
export default function IndexPage() {
return (
<div>
<Head>
<link
href="https://fonts.googleapis.com/css2?family=Krona+One&display=optional"
rel="stylesheet"
/>
</Head>
</div>
)
}
```
Specifying `display=optional` minimizes the risk of invisible text or layout shift. If swapping to the custom font after it has loaded is important to you, then use `display=swap` instead.
### When Not To Use It
If you want to specifically display a font using a `block` or `fallback` strategy, then you can disable this rule.
### Useful Links
- [Font-display](https://font-display.glitch.me/)

View File

@@ -0,0 +1,17 @@
# Google Font Preconnect
### Why This Error Occurred
A preconnect resource hint was not used with a request to the Google Fonts domain. Adding `preconnect` is recommended to initiate an early connection to the origin.
### Possible Ways to Fix It
Add `rel="preconnect"` to the Google Font domain `<link>` tag:
```jsx
<link rel="preconnect" href="https://fonts.gstatic.com" />
```
### Useful Links
- [Preconnect to required origins](https://web.dev/uses-rel-preconnect/)

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