From 1fd00899c75cbff9aa9ce269d8c0a4a04a8cbff7 Mon Sep 17 00:00:00 2001 From: Lee Robinson Date: Sun, 20 Nov 2022 21:45:15 -0600 Subject: [PATCH 01/20] Remove unneeded `async` in docs. (#43161) https://github.com/vercel/feedback/issues/23545 --- docs/api-reference/next/server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-reference/next/server.md b/docs/api-reference/next/server.md index e9987ae75f81..6f2fe46acfe4 100644 --- a/docs/api-reference/next/server.md +++ b/docs/api-reference/next/server.md @@ -56,7 +56,7 @@ The `waitUntil()` method can be used to prolong the execution of the function if import { NextResponse } from 'next/server' import type { NextFetchEvent, NextRequest } from 'next/server' -export async function middleware(req: NextRequest, event: NextFetchEvent) { +export function middleware(req: NextRequest, event: NextFetchEvent) { event.waitUntil( fetch('https://my-analytics-platform.com', { method: 'POST', From 21d7d224543f00d0bbc58a0ea7b457a3d2b7d884 Mon Sep 17 00:00:00 2001 From: Lee Robinson Date: Mon, 21 Nov 2022 00:48:13 -0600 Subject: [PATCH 02/20] Add JWT example to error page. (#43162) https://github.com/vercel/feedback/issues/23531 --- errors/node-module-in-edge-runtime.md | 1 + 1 file changed, 1 insertion(+) diff --git a/errors/node-module-in-edge-runtime.md b/errors/node-module-in-edge-runtime.md index ea128326a41b..cd7a38fd809a 100644 --- a/errors/node-module-in-edge-runtime.md +++ b/errors/node-module-in-edge-runtime.md @@ -16,3 +16,4 @@ For example, you might replace the Node.js `crypto` module with the [Web Crypto - [Edge Runtime Supported APIs](https://nextjs.org/docs/api-reference/edge-runtime) - [Next.js Middleware](https://nextjs.org/docs/advanced-features/middleware) +- [JWT Example](https://github.com/vercel/examples/tree/main/edge-functions/jwt-authentication) From 447cba0f5d8d6e8f86460f7c6aa2482fddb38ec2 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Mon, 21 Nov 2022 14:35:57 +0100 Subject: [PATCH 03/20] Remove the timestamp query for CSS resources (#43185) As discussed [here](https://vercel.slack.com/archives/C035J346QQL/p1668425692084449), we don't need the timestamp for CSS resources in the app dir for now as we are not preloading them. Manually tested with Safari and added corresponding e2e tests. Closes #42862. ## Bug - [ ] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) --- packages/next/server/app-render.tsx | 19 +++++--- test/e2e/app-dir/index.test.ts | 76 +++++++++++++++++++++++------ 2 files changed, 73 insertions(+), 22 deletions(-) diff --git a/packages/next/server/app-render.tsx b/packages/next/server/app-render.tsx index 4a6d4b55b3d0..44ec95e2ac6e 100644 --- a/packages/next/server/app-render.tsx +++ b/packages/next/server/app-render.tsx @@ -999,13 +999,17 @@ export async function renderToHTMLOrFlight( filePath, serverCSSForEntries ) - const cacheBustingUrlSuffix = dev ? `?ts=${Date.now()}` : '' const styles = cssHrefs ? cssHrefs.map((href, index) => ( { - // Add extra cache busting (DEV only) for https://github.com/vercel/next.js/issues/5860 - // See also https://bugs.webkit.org/show_bug.cgi?id=187726 - const cacheBustingUrlSuffix = dev ? `?ts=${Date.now()}` : '' - return ( <> {preloadedFontFiles.map((fontFile) => { @@ -1347,7 +1347,12 @@ export async function renderToHTMLOrFlight( ? stylesheets.map((href, index) => ( { expect(html).toContain('hello from app/partial-match-[id]. ID is: 123') }) - // This is a workaround to fix https://github.com/vercel/next.js/issues/5860 - // TODO: remove this workaround when https://bugs.webkit.org/show_bug.cgi?id=187726 is fixed. - it('should use cache busting when loading css (dev only)', async () => { - const html = await renderViaHTTP(next.url, '/') - const $ = cheerio.load(html) - const links = $('link[rel=stylesheet]') - links.each((_, link) => { - const href = $(link).attr('href') - isDev - ? expect(href).toMatch(/\?ts=/) - : expect(href).not.toMatch(/\?ts=/) - }) - }) - describe('rewrites', () => { // TODO-APP: rewrite url is broken it('should support rewrites on initial load', async () => { @@ -1514,7 +1500,7 @@ describe('app dir', () => { const html = await renderViaHTTP(next.url, '/loading-bug/hi') // The link tag should be included together with loading expect(html).toMatch( - /

Loading...<\/h2>/ + /

Loading...<\/h2>/ ) }) @@ -1574,6 +1560,66 @@ describe('app dir', () => { ).toBe('50px') }) }) + + if (isDev) { + describe('HMR', () => { + it('should support HMR for CSS imports in server components', async () => { + const filePath = 'app/css/css-page/style.css' + const origContent = await next.readFile(filePath) + + // h1 should be red + const browser = await webdriver(next.url, '/css/css-page') + expect( + await browser.eval( + `window.getComputedStyle(document.querySelector('h1')).color` + ) + ).toBe('rgb(255, 0, 0)') + + try { + await next.patchFile(filePath, origContent.replace('red', 'blue')) + + // Wait for HMR to trigger + await new Promise((resolve) => setTimeout(resolve, 2000)) + + expect( + await browser.eval( + `window.getComputedStyle(document.querySelector('h1')).color` + ) + ).toBe('rgb(0, 0, 255)') + } finally { + await next.patchFile(filePath, origContent) + } + }) + + it('should support HMR for CSS imports in client components', async () => { + const filePath = 'app/css/css-client/client-page.css' + const origContent = await next.readFile(filePath) + + // h1 should be red + const browser = await webdriver(next.url, '/css/css-client') + expect( + await browser.eval( + `window.getComputedStyle(document.querySelector('h1')).color` + ) + ).toBe('rgb(255, 0, 0)') + + try { + await next.patchFile(filePath, origContent.replace('red', 'blue')) + + // Wait for HMR to trigger + await new Promise((resolve) => setTimeout(resolve, 2000)) + + expect( + await browser.eval( + `window.getComputedStyle(document.querySelector('h1')).color` + ) + ).toBe('rgb(0, 0, 255)') + } finally { + await next.patchFile(filePath, origContent) + } + }) + }) + } }) describe('searchParams prop', () => { From a3e37e325ec5b8114191f7422c85d50511fc1176 Mon Sep 17 00:00:00 2001 From: AZM Date: Mon, 21 Nov 2022 22:50:17 +0900 Subject: [PATCH 04/20] Updated typo in the documentation (#43160) It's is confusing for the first time readers and probably wrong! ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [x] Errors have a helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [x] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [x] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) Co-authored-by: Steven <229881+styfle@users.noreply.github.com> --- docs/basic-features/static-file-serving.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/basic-features/static-file-serving.md b/docs/basic-features/static-file-serving.md index c4234b7aa2f2..a479361ec832 100644 --- a/docs/basic-features/static-file-serving.md +++ b/docs/basic-features/static-file-serving.md @@ -22,7 +22,7 @@ export default Avatar This folder is also useful for `robots.txt`, `favicon.ico`, Google Site Verification, and any other static files (including `.html`)! -> **Note**: Don't name the `public` directory anything else. The name cannot be changed and is the only directory used to serve static assets. +> **Note**: Be sure the directory is named `public`. The name cannot be changed and is the only directory used to serve static assets. > **Note**: Be sure to not have a static file with the same name as a file in the `pages/` directory, as this will result in an error. > From 3e8c6f45beca9db9cc19cd10c882feda353a39e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Niedzi=C3=B3=C5=82ka?= Date: Mon, 21 Nov 2022 20:47:49 +0100 Subject: [PATCH 05/20] Add missing quote in `next/script` example (#43196) It looks like a simple typo. --- docs/api-reference/next/script.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-reference/next/script.md b/docs/api-reference/next/script.md index a8f95a41c077..b28a3903af2d 100644 --- a/docs/api-reference/next/script.md +++ b/docs/api-reference/next/script.md @@ -37,7 +37,7 @@ Here's a summary of the props available for the Script Component: | Prop | Example | Values | Required | | ----------------------- | --------------------------------- | -------- | ------------------------------------- | | [`src`](#src) | `src="http://example.com/script"` | String | Required unless inline script is used | -| [`strategy`](#strategy) | `strategy="lazyOnload` | String | Optional | +| [`strategy`](#strategy) | `strategy="lazyOnload"` | String | Optional | | [`onLoad`](#onload) | `onLoad={onLoadFunc}` | Function | Optional | | [`onReady`](#onReady) | `onReady={onReadyFunc}` | Function | Optional | | [`onError`](#onerror) | `onError={onErrorFunc}` | Function | Optional | From c1370c923ef6aad2a37e1655d0c42031d13cdb2e Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 21 Nov 2022 13:25:01 -0800 Subject: [PATCH 06/20] Update experimental skipTrailingSlashRedirect handling (#43201) Fixes: [slack thread](https://vercel.slack.com/archives/C01224Q5M99/p1669029502713689?thread_ts=1668452468.314249&cid=C01224Q5M99) ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` --- packages/next/build/webpack-config.ts | 3 ++ .../next/client/normalize-trailing-slash.ts | 2 +- .../app/pages/index.js | 4 ++ .../index.test.ts | 48 +++++++++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index 2e7bebaaf90d..aaa3821d304a 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -299,6 +299,9 @@ export function getDefineEnv({ 'process.env.__NEXT_NO_MIDDLEWARE_URL_NORMALIZE': JSON.stringify( config.experimental.skipMiddlewareUrlNormalize ), + 'process.env.__NEXT_MANUAL_TRAILING_SLASH': JSON.stringify( + config.experimental?.skipTrailingSlashRedirect + ), 'process.env.__NEXT_HAS_WEB_VITALS_ATTRIBUTION': JSON.stringify( config.experimental.webVitalsAttribution && config.experimental.webVitalsAttribution.length > 0 diff --git a/packages/next/client/normalize-trailing-slash.ts b/packages/next/client/normalize-trailing-slash.ts index d2405675a1de..11547936af6b 100644 --- a/packages/next/client/normalize-trailing-slash.ts +++ b/packages/next/client/normalize-trailing-slash.ts @@ -6,7 +6,7 @@ import { parsePath } from '../shared/lib/router/utils/parse-path' * in `next.config.js`. */ export const normalizePathTrailingSlash = (path: string) => { - if (!path.startsWith('/')) { + if (!path.startsWith('/') || process.env.__NEXT_MANUAL_TRAILING_SLASH) { return path } diff --git a/test/e2e/skip-trailing-slash-redirect/app/pages/index.js b/test/e2e/skip-trailing-slash-redirect/app/pages/index.js index 04fbd07fee5b..8cf5943c3cd9 100644 --- a/test/e2e/skip-trailing-slash-redirect/app/pages/index.js +++ b/test/e2e/skip-trailing-slash-redirect/app/pages/index.js @@ -8,6 +8,10 @@ export default function Page(props) { to another
+ + to another + +
to /blog/first diff --git a/test/e2e/skip-trailing-slash-redirect/index.test.ts b/test/e2e/skip-trailing-slash-redirect/index.test.ts index e31d7a6909fc..cb3e14c15f54 100644 --- a/test/e2e/skip-trailing-slash-redirect/index.test.ts +++ b/test/e2e/skip-trailing-slash-redirect/index.test.ts @@ -174,6 +174,54 @@ describe('skip-trailing-slash-redirect', () => { expect(await res.text()).toContain('another page') }) + it('should not apply trailing slash to links on client', async () => { + const browser = await webdriver(next.url, '/') + await browser.eval('window.beforeNav = 1') + + expect( + new URL( + await browser.elementByCss('#to-another').getAttribute('href'), + 'http://n' + ).pathname + ).toBe('/another') + + await browser.elementByCss('#to-another').click() + await browser.waitForElementByCss('#another') + + expect(await browser.eval('window.location.pathname')).toBe('/another') + + await browser.back().waitForElementByCss('#to-another') + + expect( + new URL( + await browser + .elementByCss('#to-another-with-slash') + .getAttribute('href'), + 'http://n' + ).pathname + ).toBe('/another/') + + await browser.elementByCss('#to-another-with-slash').click() + await browser.waitForElementByCss('#another') + + expect(await browser.eval('window.location.pathname')).toBe('/another/') + + await browser.back().waitForElementByCss('#to-another') + expect(await browser.eval('window.beforeNav')).toBe(1) + }) + + it('should not apply trailing slash on load on client', async () => { + let browser = await webdriver(next.url, '/another') + await check(() => browser.eval('next.router.isReady ? "yes": "no"'), 'yes') + + expect(await browser.eval('location.pathname')).toBe('/another') + + browser = await webdriver(next.url, '/another/') + await check(() => browser.eval('next.router.isReady ? "yes": "no"'), 'yes') + + expect(await browser.eval('location.pathname')).toBe('/another/') + }) + it('should respond to index correctly', async () => { const res = await fetchViaHTTP(next.url, '/', undefined, { redirect: 'manual', From 2763f6080604dae7071d7347e3029c16871452ed Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 21 Nov 2022 23:09:46 +0100 Subject: [PATCH 07/20] Avoid bundling appDir rendering into pages edge SSR bundle (#43184) Do not directly import app-render into base-server since base-server is shared module for both nodejs SSR and edge SSR. Co-authored-by: JJ Kasper Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/next/client/components/app-router-headers.ts | 6 ++++++ packages/next/server/app-render.tsx | 7 +------ packages/next/server/base-server.ts | 7 +++++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/next/client/components/app-router-headers.ts b/packages/next/client/components/app-router-headers.ts index 1eb2747dd1cd..de00963e625e 100644 --- a/packages/next/client/components/app-router-headers.ts +++ b/packages/next/client/components/app-router-headers.ts @@ -3,3 +3,9 @@ export const NEXT_ROUTER_STATE_TREE = 'Next-Router-State-Tree' as const export const NEXT_ROUTER_PREFETCH = 'Next-Router-Prefetch' as const export const RSC_VARY_HEADER = `${RSC}, ${NEXT_ROUTER_STATE_TREE}, ${NEXT_ROUTER_PREFETCH}` as const + +export const FLIGHT_PARAMETERS = [ + [RSC], + [NEXT_ROUTER_STATE_TREE], + [NEXT_ROUTER_PREFETCH], +] as const diff --git a/packages/next/server/app-render.tsx b/packages/next/server/app-render.tsx index 44ec95e2ac6e..293360ad2146 100644 --- a/packages/next/server/app-render.tsx +++ b/packages/next/server/app-render.tsx @@ -42,6 +42,7 @@ import { NEXT_ROUTER_PREFETCH, NEXT_ROUTER_STATE_TREE, RSC, + FLIGHT_PARAMETERS, } from '../client/components/app-router-headers' import type { StaticGenerationStore } from '../client/components/static-generation-async-storage' @@ -704,12 +705,6 @@ function getScriptNonceFromHeader(cspHeaderValue: string): string | undefined { return nonce } -export const FLIGHT_PARAMETERS = [ - [RSC], - [NEXT_ROUTER_STATE_TREE], - [NEXT_ROUTER_PREFETCH], -] as const - function headersWithoutFlight(headers: IncomingHttpHeaders) { const newHeaders = { ...headers } for (const param of FLIGHT_PARAMETERS) { diff --git a/packages/next/server/base-server.ts b/packages/next/server/base-server.ts index a6a17c56c0b6..b91508e5ad1b 100644 --- a/packages/next/server/base-server.ts +++ b/packages/next/server/base-server.ts @@ -74,8 +74,11 @@ import { getHostname } from '../shared/lib/get-hostname' import { parseUrl as parseUrlUtil } from '../shared/lib/router/utils/parse-url' import { getNextPathnameInfo } from '../shared/lib/router/utils/get-next-pathname-info' import { MiddlewareMatcher } from '../build/analysis/get-page-static-info' -import { RSC, RSC_VARY_HEADER } from '../client/components/app-router-headers' -import { FLIGHT_PARAMETERS } from './app-render' +import { + RSC, + RSC_VARY_HEADER, + FLIGHT_PARAMETERS, +} from '../client/components/app-router-headers' export type FindComponentsResult = { components: LoadComponentsReturnType From 869039529ca53bcec049342a52e9976371299418 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 21 Nov 2022 23:15:55 +0100 Subject: [PATCH 08/20] Alias esm next document to avoid mismatch react context (#43192) When using custom document and importing from `next/document`, `HtmlContext` instance will mismatch due to CJS version of `next/document` is consumed. Gotta alias it to the ESM version for edge runtime ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` --- packages/next/build/webpack-config.ts | 11 ++++++--- test/e2e/streaming-ssr/index.test.ts | 32 +++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index aaa3821d304a..6e09c85cb558 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -831,6 +831,7 @@ export default async function getBaseWebpackConfig( const customRootAliases: { [key: string]: string[] } = {} if (dev) { + const nextDist = 'next/dist/' + (isEdgeServer ? 'esm/' : '') customAppAliases[`${PAGES_DIR_ALIAS}/_app`] = [ ...(pagesDir ? pageExtensions.reduce((prev, ext) => { @@ -838,7 +839,7 @@ export default async function getBaseWebpackConfig( return prev }, [] as string[]) : []), - 'next/dist/pages/_app.js', + `${nextDist}pages/_app.js`, ] customAppAliases[`${PAGES_DIR_ALIAS}/_error`] = [ ...(pagesDir @@ -847,7 +848,7 @@ export default async function getBaseWebpackConfig( return prev }, [] as string[]) : []), - 'next/dist/pages/_error.js', + `${nextDist}pages/_error.js`, ] customDocumentAliases[`${PAGES_DIR_ALIAS}/_document`] = [ ...(pagesDir @@ -856,7 +857,7 @@ export default async function getBaseWebpackConfig( return prev }, [] as string[]) : []), - 'next/dist/pages/_document.js', + `${nextDist}pages/_document.js`, ] } @@ -908,6 +909,10 @@ export default async function getBaseWebpackConfig( 'next/dist/esm/shared/lib/head', [require.resolve('next/dist/shared/lib/dynamic')]: 'next/dist/esm/shared/lib/dynamic', + [require.resolve('next/dist/pages/_document')]: + 'next/dist/esm/pages/_document', + [require.resolve('next/dist/pages/_app')]: + 'next/dist/esm/pages/_app', } : undefined), diff --git a/test/e2e/streaming-ssr/index.test.ts b/test/e2e/streaming-ssr/index.test.ts index 958bec7e0a5c..9f500fa2a17c 100644 --- a/test/e2e/streaming-ssr/index.test.ts +++ b/test/e2e/streaming-ssr/index.test.ts @@ -2,6 +2,7 @@ import { join } from 'path' import { createNext, FileRef } from 'e2e-utils' import { NextInstance } from 'test/lib/next-modes/base' import { + check, fetchViaHTTP, findPort, initNextServerScript, @@ -16,7 +17,7 @@ const react18Deps = { const isNextProd = !(global as any).isNextDev && !(global as any).isNextDeploy -describe('react 18 streaming SSR with custom next configs', () => { +describe('streaming SSR with custom next configs', () => { let next: NextInstance beforeAll(async () => { @@ -74,10 +75,37 @@ describe('react 18 streaming SSR with custom next configs', () => { const html = await renderViaHTTP(next.url, '/multi-byte') expect(html).toContain('マルチバイト'.repeat(28)) }) + + if ((global as any).isNextDev) { + it('should work with custom document', async () => { + await next.patchFile( + 'pages/_document.js', + ` + import { Html, Head, Main, NextScript } from 'next/document' + + export default function Document() { + return ( + + + +
+ + + + ) + } + ` + ) + await check(async () => { + return await renderViaHTTP(next.url, '/') + }, /index/) + await next.deleteFile('pages/_document.js') + }) + } }) if (isNextProd) { - describe('react 18 streaming SSR with custom server', () => { + describe('streaming SSR with custom server', () => { let next let server let appPort From 5d39daaf1c5d4ce530ae336010045e7bc7316f02 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 21 Nov 2022 14:39:47 -0800 Subject: [PATCH 09/20] Update tests config (#43204) Testing if this reduces flakiness we've been seeing --- .github/workflows/build_test_deploy.yml | 147 ++++++++++++------------ 1 file changed, 71 insertions(+), 76 deletions(-) diff --git a/.github/workflows/build_test_deploy.yml b/.github/workflows/build_test_deploy.yml index 5385a03bcada..3ad8cc36f014 100644 --- a/.github/workflows/build_test_deploy.yml +++ b/.github/workflows/build_test_deploy.yml @@ -297,25 +297,24 @@ jobs: timeout-minutes: 10 if: ${{needs.build.outputs.docsChange == 'nope'}} - - run: npx @replayio/playwright install chromium - if: ${{needs.build.outputs.docsChange == 'nope'}} - + # - run: npx @replayio/playwright install chromium + # if: ${{needs.build.outputs.docsChange == 'nope'}} - run: node run-tests.js --type development --timings -g ${{ matrix.group }}/2 name: Run test/development if: ${{needs.build.outputs.docsChange == 'nope'}} - env: - RECORD_REPLAY_METADATA_TEST_RUN_TITLE: testDev / Group ${{ matrix.group }} - RECORD_ALL_CONTENT: 1 - RECORD_REPLAY: 1 - RECORD_REPLAY_TEST_METRICS: 1 - RECORD_REPLAY_WEBHOOK_URL: ${{ secrets.RECORD_REPLAY_WEBHOOK_URL }} + # env: + # RECORD_REPLAY_METADATA_TEST_RUN_TITLE: testDev / Group ${{ matrix.group }} + # RECORD_ALL_CONTENT: 1 + # RECORD_REPLAY: 1 + # RECORD_REPLAY_TEST_METRICS: 1 + # RECORD_REPLAY_WEBHOOK_URL: ${{ secrets.RECORD_REPLAY_WEBHOOK_URL }} - - uses: replayio/action-upload@v0.4.5 - if: always() - with: - api-key: rwk_iKsQnEoQwKd31WAJxgN9ARPFuAlyXlVrDH4uhYpRnti - public: true - filter: ${{ 'function($v) { $v.metadata.test.result = "failed" }' }} + # - uses: replayio/action-upload@v0.4.5 + # if: always() + # with: + # api-key: rwk_iKsQnEoQwKd31WAJxgN9ARPFuAlyXlVrDH4uhYpRnti + # public: true + # filter: ${{ 'function($v) { $v.metadata.test.result = "failed" }' }} - name: Upload test trace if: always() @@ -375,26 +374,25 @@ jobs: timeout-minutes: 10 if: ${{needs.build.outputs.docsChange == 'nope'}} - - run: npx @replayio/playwright install chromium - if: ${{needs.build.outputs.docsChange == 'nope'}} - + # - run: npx @replayio/playwright install chromium + # if: ${{needs.build.outputs.docsChange == 'nope'}} - run: node run-tests.js --type e2e --timings -g ${{ matrix.group }}/3 name: Run test/e2e (dev) if: ${{needs.build.outputs.docsChange == 'nope'}} env: - RECORD_REPLAY_METADATA_TEST_RUN_TITLE: testDevE2E / Group ${{ matrix.group }} / Node ${{ matrix.node }} - RECORD_ALL_CONTENT: 1 - RECORD_REPLAY: 1 NEXT_TEST_MODE: dev - RECORD_REPLAY_TEST_METRICS: 1 - RECORD_REPLAY_WEBHOOK_URL: ${{ secrets.RECORD_REPLAY_WEBHOOK_URL }} - - - uses: replayio/action-upload@v0.4.5 - if: always() - with: - api-key: rwk_iKsQnEoQwKd31WAJxgN9ARPFuAlyXlVrDH4uhYpRnti - public: true - filter: ${{ 'function($v) { $v.metadata.test.result = "failed" }' }} + # RECORD_REPLAY_METADATA_TEST_RUN_TITLE: testDevE2E / Group ${{ matrix.group }} / Node ${{ matrix.node }} + # RECORD_ALL_CONTENT: 1 + # RECORD_REPLAY: 1 + # RECORD_REPLAY_TEST_METRICS: 1 + # RECORD_REPLAY_WEBHOOK_URL: ${{ secrets.RECORD_REPLAY_WEBHOOK_URL }} + + # - uses: replayio/action-upload@v0.4.5 + # if: always() + # with: + # api-key: rwk_iKsQnEoQwKd31WAJxgN9ARPFuAlyXlVrDH4uhYpRnti + # public: true + # filter: ${{ 'function($v) { $v.metadata.test.result = "failed" }' }} - name: Upload test trace if: always() @@ -453,25 +451,24 @@ jobs: timeout-minutes: 10 if: ${{needs.build.outputs.docsChange == 'nope'}} - - run: npx @replayio/playwright install chromium - if: ${{needs.build.outputs.docsChange == 'nope'}} - + # - run: npx @replayio/playwright install chromium + # if: ${{needs.build.outputs.docsChange == 'nope'}} - run: node run-tests.js --type production --timings -g ${{ matrix.group }}/2 name: Run test/production if: ${{needs.build.outputs.docsChange == 'nope'}} - env: - RECORD_REPLAY_METADATA_TEST_RUN_TITLE: testProd / Group ${{ matrix.group }} / Node ${{ matrix.node }} - RECORD_ALL_CONTENT: 1 - RECORD_REPLAY: 1 - RECORD_REPLAY_TEST_METRICS: 1 - RECORD_REPLAY_WEBHOOK_URL: ${{ secrets.RECORD_REPLAY_WEBHOOK_URL }} + # env: + # RECORD_REPLAY_METADATA_TEST_RUN_TITLE: testProd / Group ${{ matrix.group }} / Node ${{ matrix.node }} + # RECORD_ALL_CONTENT: 1 + # RECORD_REPLAY: 1 + # RECORD_REPLAY_TEST_METRICS: 1 + # RECORD_REPLAY_WEBHOOK_URL: ${{ secrets.RECORD_REPLAY_WEBHOOK_URL }} - - uses: replayio/action-upload@v0.4.5 - if: always() - with: - api-key: rwk_iKsQnEoQwKd31WAJxgN9ARPFuAlyXlVrDH4uhYpRnti - public: true - filter: ${{ 'function($v) { $v.metadata.test.result = "failed" }' }} + # - uses: replayio/action-upload@v0.4.5 + # if: always() + # with: + # api-key: rwk_iKsQnEoQwKd31WAJxgN9ARPFuAlyXlVrDH4uhYpRnti + # public: true + # filter: ${{ 'function($v) { $v.metadata.test.result = "failed" }' }} testProdE2E: name: Test Production (E2E) @@ -521,26 +518,25 @@ jobs: timeout-minutes: 10 if: ${{needs.build.outputs.docsChange == 'nope'}} - - run: npx @replayio/playwright install chromium - if: ${{needs.build.outputs.docsChange == 'nope'}} - + # - run: npx @replayio/playwright install chromium + # if: ${{needs.build.outputs.docsChange == 'nope'}} - run: node run-tests.js --type e2e --timings -g ${{ matrix.group }}/3 name: Run test/e2e (production) if: ${{needs.build.outputs.docsChange == 'nope'}} env: - RECORD_REPLAY_METADATA_TEST_RUN_TITLE: testProdE2E / Group ${{ matrix.group }} / Node ${{ matrix.node }} - RECORD_ALL_CONTENT: 1 - RECORD_REPLAY: 1 NEXT_TEST_MODE: start - RECORD_REPLAY_TEST_METRICS: 1 - RECORD_REPLAY_WEBHOOK_URL: ${{ secrets.RECORD_REPLAY_WEBHOOK_URL }} - - - uses: replayio/action-upload@v0.4.5 - if: always() - with: - api-key: rwk_iKsQnEoQwKd31WAJxgN9ARPFuAlyXlVrDH4uhYpRnti - public: true - filter: ${{ 'function($v) { $v.metadata.test.result = "failed" }' }} + # RECORD_REPLAY_METADATA_TEST_RUN_TITLE: testProdE2E / Group ${{ matrix.group }} / Node ${{ matrix.node }} + # RECORD_ALL_CONTENT: 1 + # RECORD_REPLAY: 1 + # RECORD_REPLAY_TEST_METRICS: 1 + # RECORD_REPLAY_WEBHOOK_URL: ${{ secrets.RECORD_REPLAY_WEBHOOK_URL }} + + # - uses: replayio/action-upload@v0.4.5 + # if: always() + # with: + # api-key: rwk_iKsQnEoQwKd31WAJxgN9ARPFuAlyXlVrDH4uhYpRnti + # public: true + # filter: ${{ 'function($v) { $v.metadata.test.result = "failed" }' }} testIntegration: name: Test Integration @@ -611,24 +607,23 @@ jobs: timeout-minutes: 10 if: ${{needs.build.outputs.docsChange == 'nope'}} - - run: npx @replayio/playwright install chromium - if: ${{needs.build.outputs.docsChange == 'nope'}} - + # - run: npx @replayio/playwright install chromium + # if: ${{needs.build.outputs.docsChange == 'nope'}} - run: xvfb-run node run-tests.js --timings -g ${{ matrix.group }}/20 if: ${{needs.build.outputs.docsChange == 'nope'}} - env: - RECORD_REPLAY_METADATA_TEST_RUN_TITLE: testIntegration / Group ${{ matrix.group }} - RECORD_ALL_CONTENT: 1 - RECORD_REPLAY: 1 - RECORD_REPLAY_TEST_METRICS: 1 - RECORD_REPLAY_WEBHOOK_URL: ${{ secrets.RECORD_REPLAY_WEBHOOK_URL }} - - - uses: replayio/action-upload@v0.4.5 - if: always() - with: - api-key: rwk_iKsQnEoQwKd31WAJxgN9ARPFuAlyXlVrDH4uhYpRnti - public: true - filter: ${{ 'function($v) { $v.metadata.test.result = "failed" }' }} + # env: + # RECORD_REPLAY_METADATA_TEST_RUN_TITLE: testIntegration / Group ${{ matrix.group }} + # RECORD_ALL_CONTENT: 1 + # RECORD_REPLAY: 1 + # RECORD_REPLAY_TEST_METRICS: 1 + # RECORD_REPLAY_WEBHOOK_URL: ${{ secrets.RECORD_REPLAY_WEBHOOK_URL }} + + # - uses: replayio/action-upload@v0.4.5 + # if: always() + # with: + # api-key: rwk_iKsQnEoQwKd31WAJxgN9ARPFuAlyXlVrDH4uhYpRnti + # public: true + # filter: ${{ 'function($v) { $v.metadata.test.result = "failed" }' }} - name: Upload test trace if: always() From ee969ea8fc15105839393692e480786ab596646e Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Tue, 22 Nov 2022 00:37:58 +0100 Subject: [PATCH 10/20] Fix middleware not executed when pages directory is empty (#43205) Fixes #41995 Closes #43144 ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` Co-authored-by: Bruno Nascimento --- packages/next/build/entries.ts | 6 ++- packages/next/build/index.ts | 26 +++++------ packages/next/build/utils.ts | 8 +++- packages/next/cli/next-dev.ts | 6 +-- packages/next/server/dev/next-dev-server.ts | 24 +++++----- test/e2e/app-dir/app-middleware.test.ts | 44 ++++++++++++++++--- .../e2e/app-dir/app-middleware/next.config.js | 3 +- 7 files changed, 79 insertions(+), 38 deletions(-) diff --git a/packages/next/build/entries.ts b/packages/next/build/entries.ts index e6f5fc1d11d8..57305cc15566 100644 --- a/packages/next/build/entries.ts +++ b/packages/next/build/entries.ts @@ -457,7 +457,11 @@ export async function createEntrypoints(params: CreateEntrypointsParams) { await Promise.all(Object.keys(pages).map(getEntryHandler(pages, 'pages'))) if (nestedMiddleware.length > 0) { - throw new NestedMiddlewareError(nestedMiddleware, rootDir, pagesDir!) + throw new NestedMiddlewareError( + nestedMiddleware, + rootDir, + (appDir || pagesDir)! + ) } return { diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index fbdf356c28a4..5ea05ac8cec2 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -11,7 +11,7 @@ import { escapeStringRegexp } from '../shared/lib/escape-regexp' import findUp from 'next/dist/compiled/find-up' import { nanoid } from 'next/dist/compiled/nanoid/index.cjs' import { pathToRegexp } from 'next/dist/compiled/path-to-regexp' -import path, { join } from 'path' +import path from 'path' import formatWebpackMessages from '../client/dev/error-overlay/format-webpack-messages' import { STATIC_STATUS_PAGE_GET_INITIAL_PROPS_ERROR, @@ -331,15 +331,16 @@ export default async function build( }) const { pagesDir, appDir } = findPagesDir(dir, isAppDirEnabled) + const isSrcDir = path + .relative(dir, pagesDir || appDir || '') + .startsWith('src') const hasPublicDir = await fileExists(publicDir) telemetry.record( eventCliSession(dir, config, { webpackVersion: 5, cliCommand: 'build', - isSrcDir: - (!!pagesDir && path.relative(dir, pagesDir).startsWith('src')) || - (!!appDir && path.relative(dir, appDir).startsWith('src')), + isSrcDir, hasNowJson: !!(await findUp('now.json', { cwd: dir })), isCustomServer: null, turboFlag: false, @@ -502,11 +503,10 @@ export default async function build( `^${MIDDLEWARE_FILENAME}\\.(?:${config.pageExtensions.join('|')})$` ) - const rootPaths = pagesDir - ? ( - await flatReaddir(join(pagesDir, '..'), middlewareDetectionRegExp) - ).map((absoluteFile) => absoluteFile.replace(dir, '')) - : [] + const rootDir = path.join((pagesDir || appDir)!, '..') + const rootPaths = ( + await flatReaddir(rootDir, middlewareDetectionRegExp) + ).map((absoluteFile) => absoluteFile.replace(dir, '')) // needed for static exporting since we want to replace with HTML // files @@ -1306,7 +1306,7 @@ export default async function build( config.experimental.gzipSize ) - const middlewareManifest: MiddlewareManifest = require(join( + const middlewareManifest: MiddlewareManifest = require(path.join( distDir, SERVER_DIRECTORY, MIDDLEWARE_MANIFEST @@ -1387,7 +1387,7 @@ export default async function build( const staticInfo = pagePath ? await getPageStaticInfo({ - pageFilePath: join( + pageFilePath: path.join( (pageType === 'pages' ? pagesDir : appDir) || '', pagePath ), @@ -1982,7 +1982,7 @@ export default async function build( const cssFilePaths = await new Promise((resolve, reject) => { globOrig( '**/*.css', - { cwd: join(distDir, 'static') }, + { cwd: path.join(distDir, 'static') }, (err, files) => { if (err) { return reject(err) @@ -2803,7 +2803,7 @@ export default async function build( .traceAsyncFn(async () => { await verifyPartytownSetup( dir, - join(distDir, CLIENT_STATIC_FILES_PATH) + path.join(distDir, CLIENT_STATIC_FILES_PATH) ) }) } diff --git a/packages/next/build/utils.ts b/packages/next/build/utils.ts index 6b20468b2339..aea1ace28871 100644 --- a/packages/next/build/utils.ts +++ b/packages/next/build/utils.ts @@ -1774,13 +1774,17 @@ export function getPossibleMiddlewareFilenames( } export class NestedMiddlewareError extends Error { - constructor(nestedFileNames: string[], mainDir: string, pagesDir: string) { + constructor( + nestedFileNames: string[], + mainDir: string, + pagesOrAppDir: string + ) { super( `Nested Middleware is not allowed, found:\n` + `${nestedFileNames.map((file) => `pages${file}`).join('\n')}\n` + `Please move your code to a single file at ${path.join( path.posix.sep, - path.relative(mainDir, path.resolve(pagesDir, '..')), + path.relative(mainDir, path.resolve(pagesOrAppDir, '..')), 'middleware' )} instead.\n` + `Read More - https://nextjs.org/docs/messages/nested-middleware` diff --git a/packages/next/cli/next-dev.ts b/packages/next/cli/next-dev.ts index 1f0fc1ab875d..b0a689c84f66 100755 --- a/packages/next/cli/next-dev.ts +++ b/packages/next/cli/next-dev.ts @@ -380,9 +380,9 @@ If you cannot make the changes above, but still want to try out\nNext.js v13 wit eventCliSession(distDir, rawNextConfig as NextConfigComplete, { webpackVersion: 5, cliCommand: 'dev', - isSrcDir: - (!!pagesDir && path.relative(dir, pagesDir).startsWith('src')) || - (!!appDir && path.relative(dir, appDir).startsWith('src')), + isSrcDir: path + .relative(dir, pagesDir || appDir || '') + .startsWith('src'), hasNowJson: !!(await findUp('now.json', { cwd: dir })), isCustomServer: false, turboFlag: true, diff --git a/packages/next/server/dev/next-dev-server.ts b/packages/next/server/dev/next-dev-server.ts index 389f283c367f..967d7103a58d 100644 --- a/packages/next/server/dev/next-dev-server.ts +++ b/packages/next/server/dev/next-dev-server.ts @@ -277,12 +277,11 @@ export default class DevServer extends Server { const app = this.appDir ? [this.appDir] : [] const directories = [...pages, ...app] - const files = this.pagesDir - ? getPossibleMiddlewareFilenames( - pathJoin(this.pagesDir, '..'), - this.nextConfig.pageExtensions - ) - : [] + const rootDir = this.pagesDir || this.appDir + const files = getPossibleMiddlewareFilenames( + pathJoin(rootDir!, '..'), + this.nextConfig.pageExtensions + ) let nestedMiddleware: string[] = [] const envFiles = [ @@ -294,7 +293,7 @@ export default class DevServer extends Server { files.push(...envFiles) - // tsconfig/jsonfig paths hot-reloading + // tsconfig/jsconfig paths hot-reloading const tsconfigPaths = [ pathJoin(this.dir, 'tsconfig.json'), pathJoin(this.dir, 'jsconfig.json'), @@ -577,7 +576,7 @@ export default class DevServer extends Server { new NestedMiddlewareError( nestedMiddleware, this.dir, - this.pagesDir! + (this.pagesDir || this.appDir)! ).message ) nestedMiddleware = [] @@ -726,14 +725,15 @@ export default class DevServer extends Server { } const telemetry = new Telemetry({ distDir: this.distDir }) + const isSrcDir = relative( + this.dir, + this.pagesDir || this.appDir || '' + ).startsWith('src') telemetry.record( eventCliSession(this.distDir, this.nextConfig, { webpackVersion: 5, cliCommand: 'dev', - isSrcDir: - (!!this.pagesDir && - relative(this.dir, this.pagesDir).startsWith('src')) || - (!!this.appDir && relative(this.dir, this.appDir).startsWith('src')), + isSrcDir, hasNowJson: !!(await findUp('now.json', { cwd: this.dir })), isCustomServer: this.isCustomServer, turboFlag: false, diff --git a/test/e2e/app-dir/app-middleware.test.ts b/test/e2e/app-dir/app-middleware.test.ts index 91b79a72f52a..4c1caccd53d8 100644 --- a/test/e2e/app-dir/app-middleware.test.ts +++ b/test/e2e/app-dir/app-middleware.test.ts @@ -1,7 +1,7 @@ /* eslint-env jest */ import { NextInstance } from 'test/lib/next-modes/base' -import { fetchViaHTTP } from 'next-test-utils' +import { fetchViaHTTP, renderViaHTTP } from 'next-test-utils' import { createNext, FileRef } from 'e2e-utils' import cheerio from 'cheerio' import path from 'path' @@ -18,10 +18,6 @@ describe('app-dir with middleware', () => { beforeAll(async () => { next = await createNext({ files: new FileRef(path.join(__dirname, 'app-middleware')), - dependencies: { - react: 'experimental', - 'react-dom': 'experimental', - }, }) }) @@ -122,3 +118,41 @@ describe('app-dir with middleware', () => { }) }) }) + +describe('app dir middleware without pages dir', () => { + if ((global as any).isNextDeploy) { + it('should skip next deploy for now', () => {}) + return + } + + let next: NextInstance + + afterAll(() => next.destroy()) + beforeAll(async () => { + next = await createNext({ + files: { + app: new FileRef(path.join(__dirname, 'app-middleware/app')), + 'next.config.js': new FileRef( + path.join(__dirname, 'app-middleware/next.config.js') + ), + 'middleware.js': ` + import { NextResponse } from 'next/server' + + export async function middleware(request) { + return new NextResponse('redirected') + } + + export const config = { + matcher: '/headers' + } + `, + }, + }) + }) + + it(`Updates headers`, async () => { + const html = await renderViaHTTP(next.url, '/headers') + + expect(html).toContain('redirected') + }) +}) diff --git a/test/e2e/app-dir/app-middleware/next.config.js b/test/e2e/app-dir/app-middleware/next.config.js index a928ea943ce2..4ab660b86b15 100644 --- a/test/e2e/app-dir/app-middleware/next.config.js +++ b/test/e2e/app-dir/app-middleware/next.config.js @@ -1,7 +1,6 @@ module.exports = { experimental: { appDir: true, - legacyBrowsers: false, - browsersListForSwc: true, + allowMiddlewareResponseBody: true, }, } From d8d9b2c985d576500821508b92c6e18a50be5df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Born=C3=B6?= Date: Tue, 22 Nov 2022 00:52:12 +0100 Subject: [PATCH 11/20] Remove app routes from _devPagesManifest (#43188) Currently in dev the `_devPagesManifest` includes the `/app` routes as well. However, In production, the `_buildManifest.js` does not include the `/app` routes. This causes the `/pages` router to behave differently in the two environments. This change excludes the `/app` routes from `_devPagesManifest` to make it work the same in dev/prod. Fixes #42513 Fixes #42532 ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) --- packages/next/server/dev/next-dev-server.ts | 4 +++- .../app-dir/page.js | 7 ++++++ .../pages/dynamic-pages-route-app-overlap.js | 9 ++++++++ .../dynamic-pages-route-app-overlap/[slug].js | 7 ++++++ test/e2e/app-dir/index.test.ts | 23 +++++++++++++++++++ 5 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 test/e2e/app-dir/app/app/dynamic-pages-route-app-overlap/app-dir/page.js create mode 100644 test/e2e/app-dir/app/pages/dynamic-pages-route-app-overlap.js create mode 100644 test/e2e/app-dir/app/pages/dynamic-pages-route-app-overlap/[slug].js diff --git a/packages/next/server/dev/next-dev-server.ts b/packages/next/server/dev/next-dev-server.ts index 967d7103a58d..a372f49a336e 100644 --- a/packages/next/server/dev/next-dev-server.ts +++ b/packages/next/server/dev/next-dev-server.ts @@ -1226,7 +1226,9 @@ export default class DevServer extends Server { res .body( JSON.stringify({ - pages: this.sortedRoutes, + pages: this.sortedRoutes?.filter( + (route) => !this.appPathRoutes![route] + ), }) ) .send() diff --git a/test/e2e/app-dir/app/app/dynamic-pages-route-app-overlap/app-dir/page.js b/test/e2e/app-dir/app/app/dynamic-pages-route-app-overlap/app-dir/page.js new file mode 100644 index 000000000000..2b529331402f --- /dev/null +++ b/test/e2e/app-dir/app/app/dynamic-pages-route-app-overlap/app-dir/page.js @@ -0,0 +1,7 @@ +export default function Page() { + return ( +

+ hello from app/dynamic-pages-route-app-overlap/app-dir/page +

+ ) +} diff --git a/test/e2e/app-dir/app/pages/dynamic-pages-route-app-overlap.js b/test/e2e/app-dir/app/pages/dynamic-pages-route-app-overlap.js new file mode 100644 index 000000000000..725caae59813 --- /dev/null +++ b/test/e2e/app-dir/app/pages/dynamic-pages-route-app-overlap.js @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default function Page() { + return ( + + To /dynamic-pages-route-app-overlap/app-dir + + ) +} diff --git a/test/e2e/app-dir/app/pages/dynamic-pages-route-app-overlap/[slug].js b/test/e2e/app-dir/app/pages/dynamic-pages-route-app-overlap/[slug].js new file mode 100644 index 000000000000..80f7029a0281 --- /dev/null +++ b/test/e2e/app-dir/app/pages/dynamic-pages-route-app-overlap/[slug].js @@ -0,0 +1,7 @@ +export default function Page() { + return ( +

+ hello from pages/dynamic-pages-route-app-overlap/[slug] +

+ ) +} diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 5b0a2e34d72d..af5fa3044f75 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -601,6 +601,29 @@ describe('app dir', () => { await browser.close() } }) + + it('should navigate to pages dynamic route from pages page if it overlaps with an app page', async () => { + const browser = await webdriver( + next.url, + '/dynamic-pages-route-app-overlap' + ) + + try { + // Click the link. + await browser.elementById('pages-link').click() + expect(await browser.waitForElementByCss('#pages-text').text()).toBe( + 'hello from pages/dynamic-pages-route-app-overlap/[slug]' + ) + + // When refreshing the browser, the app page should be rendered + await browser.refresh() + expect(await browser.waitForElementByCss('#app-text').text()).toBe( + 'hello from app/dynamic-pages-route-app-overlap/app-dir/page' + ) + } finally { + await browser.close() + } + }) }) describe('server components', () => { From ed2aa9fd75fa2b82de30261d6d3abaa3f7aad55f Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 21 Nov 2022 19:50:03 -0500 Subject: [PATCH 12/20] Fix HMR error: "Cannot read properties of null (reading 'length')" (#43145) After upgrading to Next.js 13, we started seeing the following HMR errors: ```sh $ next dev # ... warn - Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/basic-features/fast-refresh#how-it-works TypeError: Cannot read properties of null (reading 'length') at eval (webpack-internal:///./node_modules/next/dist/client/dev/error-overlay/hot-dev-client.js:262:55) ``` This error appears related to the changes made in https://github.com/vercel/next.js/pull/42350 (cc @alexkirsz). It appears that `module.hot.check` will pass `null` when there are no updates: ```ts /** * Throws an exceptions if status() is not idle. * Check all currently loaded modules for updates and apply updates if found. * If no update was found, the callback is called with null. * If autoApply is truthy the callback will be called with all modules that were disposed. * apply() is automatically called with autoApply as options parameter. * If autoApply is not set the callback will be called with all modules that will be disposed on apply(). * @param autoApply */ check(autoApply?: boolean): Promise; ``` When `updatedModules` is `null`, we skip the `apply()` call as this was producing `apply() is only allowed in ready status (state: idle)` errors. This matches [the prior behavior when `autoApply` was enabled](https://github.com/webpack/webpack/blob/8241da7f1e75c5581ba535d127fa66aeb9eb2ac8/lib/hmr/HotModuleReplacement.runtime.js#L266-L272). Fixes #43143. Also reported on Stack Overflow: - https://stackoverflow.com/questions/74415937/nextjs-typeerror-cannot-read-properties-of-null-reading-length - https://stackoverflow.com/questions/74504229/nextjs-v-13-typeerror-cannot-read-properties-of-null-reading-length I tested this change locally and no longer see these HMR errors. ## Bug - [X] Related issues linked using `fixes #number` - no related issues - [X] Integration tests added - there aren't any existing tests, afaict - [X] Errors have a helpful link attached, see `contributing.md` - N/A Co-authored-by: JJ Kasper --- .../components/react-dev-overlay/hot-reloader-client.tsx | 8 ++++---- packages/next/client/dev/error-overlay/hot-dev-client.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/next/client/components/react-dev-overlay/hot-reloader-client.tsx b/packages/next/client/components/react-dev-overlay/hot-reloader-client.tsx index f5a4f91f9fa8..0a5cbb9c6a78 100644 --- a/packages/next/client/components/react-dev-overlay/hot-reloader-client.tsx +++ b/packages/next/client/components/react-dev-overlay/hot-reloader-client.tsx @@ -124,7 +124,7 @@ function tryApplyUpdates( return } - function handleApplyUpdates(err: any, updatedModules: any) { + function handleApplyUpdates(err: any, updatedModules: any[] | null) { if (err || RuntimeErrorHandler.hadRuntimeError || !updatedModules) { if (err) { console.warn( @@ -144,7 +144,7 @@ function tryApplyUpdates( return } - const hasUpdates = Boolean(updatedModules.length) + const hasUpdates = Boolean(updatedModules?.length) if (typeof onHotUpdateSuccess === 'function') { // Maybe we want to do something. onHotUpdateSuccess(hasUpdates) @@ -175,8 +175,8 @@ function tryApplyUpdates( // @ts-expect-error module.hot exists module.hot .check(/* autoApply */ false) - .then((updatedModules: any) => { - const hasUpdates = Boolean(updatedModules.length) + .then((updatedModules: any[] | null) => { + const hasUpdates = Boolean(updatedModules?.length) if (typeof onBeforeUpdate === 'function') { onBeforeUpdate(hasUpdates) } diff --git a/packages/next/client/dev/error-overlay/hot-dev-client.js b/packages/next/client/dev/error-overlay/hot-dev-client.js index 697c99945c21..fa613a6ee03d 100644 --- a/packages/next/client/dev/error-overlay/hot-dev-client.js +++ b/packages/next/client/dev/error-overlay/hot-dev-client.js @@ -337,7 +337,7 @@ function tryApplyUpdates(onBeforeHotUpdate, onHotUpdateSuccess) { return } - const hasUpdates = Boolean(updatedModules.length) + const hasUpdates = Boolean(updatedModules?.length) if (typeof onHotUpdateSuccess === 'function') { // Maybe we want to do something. onHotUpdateSuccess(hasUpdates) @@ -368,7 +368,7 @@ function tryApplyUpdates(onBeforeHotUpdate, onHotUpdateSuccess) { .check(/* autoApply */ false) .then((updatedModules) => { if (typeof onBeforeHotUpdate === 'function') { - const hasUpdates = Boolean(updatedModules.length) + const hasUpdates = Boolean(updatedModules?.length) onBeforeHotUpdate(hasUpdates) } return module.hot.apply() From 9f93d34061e63e16c802eceaeea7ca8f7e1737e1 Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Tue, 22 Nov 2022 01:51:57 +0100 Subject: [PATCH 13/20] fix: create-next-app copies files it shouldn't (#43131) Closes #43130 This fixes the bug where the CLI copies files it shouldn't, by adding a `/` separator at the end of the directory name. Given `examples/next-prisma-starter` and `examples/next-prisma-starter-websockets`, only files inside the `examples/next-prisma-starter` will now be copied. Here is a repo created by the CLI after this fix, using ```bash # Inside packages/create-next-app pnpm build node dist/index.js --example https://github.com/trpc/trpc --example-path examples/next-prisma-starter ``` https://github.com/juliusmarminge/create-next-app-bugfix ## Bug - [x] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see `contributing.md` ## Documentation / Examples - [x] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) --- packages/create-next-app/helpers/examples.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/create-next-app/helpers/examples.ts b/packages/create-next-app/helpers/examples.ts index 06fef57d27b1..3ff54b51fac0 100644 --- a/packages/create-next-app/helpers/examples.ts +++ b/packages/create-next-app/helpers/examples.ts @@ -102,7 +102,9 @@ export async function downloadAndExtractRepo( strip: filePath ? filePath.split('/').length + 1 : 1, filter: (p) => p.startsWith( - `${name}-${branch.replace(/\//g, '-')}${filePath ? `/${filePath}` : ''}` + `${name}-${branch.replace(/\//g, '-')}${ + filePath ? `/${filePath}/` : '/' + }` ), }) From 7ae1cb8e8dd6af530bee80c7c76d56bee515a666 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 21 Nov 2022 17:03:50 -0800 Subject: [PATCH 14/20] v13.0.5-canary.4 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- 17 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lerna.json b/lerna.json index 2d477b3a484e..6fbde5eb3f97 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "13.0.5-canary.3" + "version": "13.0.5-canary.4" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index bc0531c1f074..0f2e5bd02edd 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 34d66a1a6267..c46636e9b3dd 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "description": "ESLint configuration used by NextJS.", "main": "index.js", "license": "MIT", @@ -9,7 +9,7 @@ "directory": "packages/eslint-config-next" }, "dependencies": { - "@next/eslint-plugin-next": "13.0.5-canary.3", + "@next/eslint-plugin-next": "13.0.5-canary.4", "@rushstack/eslint-patch": "^1.1.3", "@typescript-eslint/parser": "^5.42.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 1761c7dc4861..d4732e7a6fc9 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "description": "ESLint plugin for NextJS.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 2e10b0149dd2..1b5d670fa37b 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 5349e03c7741..565594a4737a 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index d25ae51d6b0b..525ec1be0639 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "license": "MIT", "dependencies": { "chalk": "4.1.0", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index ff70f169028c..1cfbd9637b07 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 4027d2ad096b..7795868b7612 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 8c65d734c07d..ae3e70283fbf 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 259b1f0ecaf7..d53079b6ad35 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 87ee8957ac25..af179d3f247e 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 7384ec8dd567..c526ac5cd4f6 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "private": true, "scripts": { "build-native": "napi build --platform -p next-swc-napi --cargo-name next_swc_napi --features plugin --js false native", diff --git a/packages/next/package.json b/packages/next/package.json index 53d96414645d..da1ae1710729 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -75,7 +75,7 @@ ] }, "dependencies": { - "@next/env": "13.0.5-canary.3", + "@next/env": "13.0.5-canary.4", "@swc/helpers": "0.4.14", "caniuse-lite": "^1.0.30001406", "postcss": "8.4.14", @@ -126,11 +126,11 @@ "@hapi/accept": "5.0.2", "@napi-rs/cli": "2.12.0", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "13.0.5-canary.3", - "@next/polyfill-nomodule": "13.0.5-canary.3", - "@next/react-dev-overlay": "13.0.5-canary.3", - "@next/react-refresh-utils": "13.0.5-canary.3", - "@next/swc": "13.0.5-canary.3", + "@next/polyfill-module": "13.0.5-canary.4", + "@next/polyfill-nomodule": "13.0.5-canary.4", + "@next/react-dev-overlay": "13.0.5-canary.4", + "@next/react-refresh-utils": "13.0.5-canary.4", + "@next/swc": "13.0.5-canary.4", "@segment/ajv-human-errors": "2.1.2", "@taskr/clear": "1.1.0", "@taskr/esnext": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 753dd1163778..c76016103393 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index e68b764481a9..2a6a6999b5bd 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "13.0.5-canary.3", + "version": "13.0.5-canary.4", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f94b6011783a..819b1ed56419 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -410,7 +410,7 @@ importers: packages/eslint-config-next: specifiers: - '@next/eslint-plugin-next': 13.0.5-canary.3 + '@next/eslint-plugin-next': 13.0.5-canary.4 '@rushstack/eslint-patch': ^1.1.3 '@typescript-eslint/parser': ^5.42.0 eslint-import-resolver-node: ^0.3.6 @@ -478,12 +478,12 @@ importers: '@hapi/accept': 5.0.2 '@napi-rs/cli': 2.12.0 '@napi-rs/triples': 1.1.0 - '@next/env': 13.0.5-canary.3 - '@next/polyfill-module': 13.0.5-canary.3 - '@next/polyfill-nomodule': 13.0.5-canary.3 - '@next/react-dev-overlay': 13.0.5-canary.3 - '@next/react-refresh-utils': 13.0.5-canary.3 - '@next/swc': 13.0.5-canary.3 + '@next/env': 13.0.5-canary.4 + '@next/polyfill-module': 13.0.5-canary.4 + '@next/polyfill-nomodule': 13.0.5-canary.4 + '@next/react-dev-overlay': 13.0.5-canary.4 + '@next/react-refresh-utils': 13.0.5-canary.4 + '@next/swc': 13.0.5-canary.4 '@segment/ajv-human-errors': 2.1.2 '@swc/helpers': 0.4.14 '@taskr/clear': 1.1.0 From f400adf5e9a5a5471cb0b800a5c336b07cab8d3b Mon Sep 17 00:00:00 2001 From: Andy Kenward <4893048+andykenward@users.noreply.github.com> Date: Tue, 22 Nov 2022 10:33:44 +0000 Subject: [PATCH 15/20] chore(examples): with-msw update msw (#43224) CLOSES https://github.com/vercel/next.js/issues/43221 --- examples/with-msw/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/with-msw/package.json b/examples/with-msw/package.json index 5b9b20b7b4b4..131fad7ab032 100644 --- a/examples/with-msw/package.json +++ b/examples/with-msw/package.json @@ -6,7 +6,7 @@ "start": "next start" }, "dependencies": { - "msw": "0.47.3", + "msw": "^0.49.0", "next": "latest", "react": "^18.2.0", "react-dom": "^18.2.0" From 3a2af8fb0bdaabc7ca5ae7f06ddd929c91b0c88c Mon Sep 17 00:00:00 2001 From: Mateus Etto Date: Tue, 22 Nov 2022 21:45:19 +0900 Subject: [PATCH 16/20] Fix With Passport example (#43232) --- examples/with-passport/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/with-passport/package.json b/examples/with-passport/package.json index 083feeb81e76..2d01f8c0bb4a 100644 --- a/examples/with-passport/package.json +++ b/examples/with-passport/package.json @@ -10,11 +10,11 @@ "cookie": "0.4.1", "next": "latest", "next-connect": "0.8.1", - "passport": "0.4.1", - "passport-local": "1.0.0", + "passport": "^0.4.1", + "passport-local": "^1.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "swr": "^0.5.5", + "swr": "^1.3.0", "uuid": "8.3.1" } } From 7596132a0cb8d5730463a4c2353dffac4a14ff79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 22 Nov 2022 13:49:01 +0100 Subject: [PATCH 17/20] fix(ts): re-export `PageComponent` and `LayoutComponent` types (#43226) --- packages/next/build/webpack/plugins/flight-types-plugin.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/next/build/webpack/plugins/flight-types-plugin.ts b/packages/next/build/webpack/plugins/flight-types-plugin.ts index 15371d5337a2..9d92207b222a 100644 --- a/packages/next/build/webpack/plugins/flight-types-plugin.ts +++ b/packages/next/build/webpack/plugins/flight-types-plugin.ts @@ -35,8 +35,8 @@ interface LayoutProps { params: any } -type PageComponent = (props: PageProps) => React.ReactNode | Promise -type LayoutComponent = (props: LayoutProps) => React.ReactNode | Promise +export type PageComponent = (props: PageProps) => React.ReactNode | Promise +export type LayoutComponent = (props: LayoutProps) => React.ReactNode | Promise interface IEntry { ${ From 807c59a21516f3690ff927ca014599192c8ace01 Mon Sep 17 00:00:00 2001 From: FomichRoman <100326856+FomichRoman@users.noreply.github.com> Date: Tue, 22 Nov 2022 22:28:07 +0900 Subject: [PATCH 18/20] chore(examples): update Next.js in `with-redux-reducer` (#43237) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Balázs Orbán --- examples/with-redux-wrapper/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/with-redux-wrapper/package.json b/examples/with-redux-wrapper/package.json index fcafedde23b7..03d3411794e9 100644 --- a/examples/with-redux-wrapper/package.json +++ b/examples/with-redux-wrapper/package.json @@ -6,7 +6,7 @@ "start": "next start" }, "dependencies": { - "next": "9.4.1", + "next": "latest", "next-redux-wrapper": "^7.0.2", "react": "^18.2.0", "react-dom": "^18.2.0", From 08ee7b22ec568c066d5b31a615f37cc0d2c38cda Mon Sep 17 00:00:00 2001 From: Rishabh Poddar Date: Tue, 22 Nov 2022 19:02:49 +0530 Subject: [PATCH 19/20] Updates supertokens example app SSR behaviour (#43218) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Rishabh Co-authored-by: Balázs Orbán --- examples/with-supertokens/pages/index.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/with-supertokens/pages/index.tsx b/examples/with-supertokens/pages/index.tsx index 43950b22f434..81c3c34567ec 100644 --- a/examples/with-supertokens/pages/index.tsx +++ b/examples/with-supertokens/pages/index.tsx @@ -16,7 +16,11 @@ export async function getServerSideProps(context) { supertokensNode.init(backendConfig()) let session try { - session = await Session.getSession(context.req, context.res) + session = await Session.getSession(context.req, context.res, { + overrideGlobalClaimValidators: async function () { + return [] + }, + }) } catch (err) { if (err.type === Session.Error.TRY_REFRESH_TOKEN) { return { props: { fromSupertokens: 'needs-refresh' } } @@ -24,11 +28,8 @@ export async function getServerSideProps(context) { // this will force the frontend to try and refresh which will fail // clearing all cookies and redirecting the user to the login screen. return { props: { fromSupertokens: 'needs-refresh' } } - } else if (err.type === Session.Error.INVALID_CLAIMS) { - return { props: {} } - } else { - throw err } + throw err } return { From ef7a6e12107c6bf59ec3312d2c2040f169238d82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20Bie=C5=84?= Date: Tue, 22 Nov 2022 14:33:29 +0100 Subject: [PATCH 20/20] docs: add missing AppProps import (#43136) --- examples/with-styled-components-babel/pages/_app.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/with-styled-components-babel/pages/_app.tsx b/examples/with-styled-components-babel/pages/_app.tsx index 75b23189d4b1..0f4c9ce68e0f 100644 --- a/examples/with-styled-components-babel/pages/_app.tsx +++ b/examples/with-styled-components-babel/pages/_app.tsx @@ -1,3 +1,4 @@ +import type { AppProps } from 'next/app' import { createGlobalStyle, ThemeProvider } from 'styled-components' const GlobalStyle = createGlobalStyle` @@ -20,7 +21,7 @@ const theme: ThemeInterface = { }, } -export default function App({ Component, pageProps }) { +export default function App({ Component, pageProps }: AppProps) { return ( <>