Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Opt-in to dynamic rendering when reading searchParams (#46205)
Ensures that using `searchParams` opts into dynamic rendering. Fixes #43077 fix NEXT-601 ([link](https://linear.app/vercel/issue/NEXT-601)) <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/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` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) 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`](https://github.com/vercel/next.js/blob/canary/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)
- Loading branch information
1 parent
dbdf47c
commit cc0da4b
Showing
15 changed files
with
251 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
packages/next/src/client/components/searchparams-bailout-proxy.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { staticGenerationBailout } from './static-generation-bailout' | ||
|
||
export function createSearchParamsBailoutProxy() { | ||
return new Proxy( | ||
{}, | ||
{ | ||
get(_target, prop) { | ||
// React adds some properties on the object when serializing for client components | ||
if (typeof prop === 'string') { | ||
staticGenerationBailout(`searchParams.${prop}`) | ||
} | ||
}, | ||
} | ||
) | ||
} |
14 changes: 14 additions & 0 deletions
14
packages/next/src/client/components/static-generation-searchparams-bailout-provider.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
'use client' | ||
import React from 'react' | ||
import { createSearchParamsBailoutProxy } from './searchparams-bailout-proxy' | ||
|
||
export default function StaticGenerationSearchParamsBailoutProvider({ | ||
Component, | ||
propsForComponent, | ||
}: { | ||
Component: React.ComponentType<any> | ||
propsForComponent: any | ||
}) { | ||
const searchParams = createSearchParamsBailoutProxy() | ||
return <Component searchParams={searchParams} {...propsForComponent} /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
test/e2e/app-dir/searchparams-static-bailout/app/client-component-page/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
'use client' | ||
import { nanoid } from 'nanoid' | ||
export default function Page({ searchParams }) { | ||
return ( | ||
<> | ||
<h1>Parameter: {searchParams.search}</h1> | ||
<p id="nanoid">{nanoid()}</p> | ||
</> | ||
) | ||
} |
11 changes: 11 additions & 0 deletions
11
...2e/app-dir/searchparams-static-bailout/app/client-component-without-searchparams/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
'use client' | ||
import { nanoid } from 'nanoid' | ||
|
||
export default function Page() { | ||
return ( | ||
<> | ||
<h1>No searchParams used</h1> | ||
<p id="nanoid">{nanoid()}</p> | ||
</> | ||
) | ||
} |
8 changes: 8 additions & 0 deletions
8
test/e2e/app-dir/searchparams-static-bailout/app/client-component/component.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
'use client' | ||
export default function ClientComponent({ searchParams }) { | ||
return ( | ||
<> | ||
<h1>Parameter: {searchParams.search}</h1> | ||
</> | ||
) | ||
} |
11 changes: 11 additions & 0 deletions
11
test/e2e/app-dir/searchparams-static-bailout/app/client-component/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { nanoid } from 'nanoid' | ||
import ClientComponent from './component' | ||
|
||
export default function Page({ searchParams }) { | ||
return ( | ||
<> | ||
<ClientComponent searchParams={searchParams} /> | ||
<p id="nanoid">{nanoid()}</p> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export default function Root({ children }: { children: React.ReactNode }) { | ||
return ( | ||
<html> | ||
<body>{children}</body> | ||
</html> | ||
) | ||
} |
10 changes: 10 additions & 0 deletions
10
test/e2e/app-dir/searchparams-static-bailout/app/server-component-page/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { nanoid } from 'nanoid' | ||
|
||
export default function Page({ searchParams }) { | ||
return ( | ||
<> | ||
<h1>Parameter: {searchParams.search}</h1> | ||
<p id="nanoid">{nanoid()}</p> | ||
</> | ||
) | ||
} |
10 changes: 10 additions & 0 deletions
10
...2e/app-dir/searchparams-static-bailout/app/server-component-without-searchparams/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { nanoid } from 'nanoid' | ||
|
||
export default function Page() { | ||
return ( | ||
<> | ||
<h1>No searchParams used</h1> | ||
<p id="nanoid">{nanoid()}</p> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** | ||
* @type {import('next').NextConfig} | ||
*/ | ||
const nextConfig = { | ||
experimental: { appDir: true }, | ||
} | ||
|
||
module.exports = nextConfig |
87 changes: 87 additions & 0 deletions
87
test/e2e/app-dir/searchparams-static-bailout/searchparams-static-bailout.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { createNextDescribe } from 'e2e-utils' | ||
|
||
createNextDescribe( | ||
'searchparams-static-bailout', | ||
{ | ||
files: __dirname, | ||
dependencies: { | ||
nanoid: '4.0.1', | ||
}, | ||
}, | ||
({ next, isNextStart }) => { | ||
describe('server component', () => { | ||
it('should bailout when using searchParams', async () => { | ||
const url = '/server-component-page?search=hello' | ||
const $ = await next.render$(url) | ||
expect($('h1').text()).toBe('Parameter: hello') | ||
|
||
// Check if the page is not statically generated. | ||
if (isNextStart) { | ||
const id = $('#nanoid').text() | ||
const $2 = await next.render$(url) | ||
const id2 = $2('#nanoid').text() | ||
expect(id).not.toBe(id2) | ||
} | ||
}) | ||
|
||
it('should not bailout when not using searchParams', async () => { | ||
const url = '/server-component-without-searchparams?search=hello' | ||
|
||
const $ = await next.render$(url) | ||
expect($('h1').text()).toBe('No searchParams used') | ||
|
||
// Check if the page is not statically generated. | ||
if (isNextStart) { | ||
const id = $('#nanoid').text() | ||
const $2 = await next.render$(url) | ||
const id2 = $2('#nanoid').text() | ||
expect(id).toBe(id2) | ||
} | ||
}) | ||
}) | ||
|
||
describe('client component', () => { | ||
it('should bailout when using searchParams', async () => { | ||
const url = '/client-component-page?search=hello' | ||
const $ = await next.render$(url) | ||
expect($('h1').text()).toBe('Parameter: hello') | ||
|
||
// Check if the page is not statically generated. | ||
if (isNextStart) { | ||
const id = $('#nanoid').text() | ||
const $2 = await next.render$(url) | ||
const id2 = $2('#nanoid').text() | ||
expect(id).not.toBe(id2) | ||
} | ||
}) | ||
|
||
it('should bailout when using searchParams is passed to client component', async () => { | ||
const url = '/client-component?search=hello' | ||
const $ = await next.render$(url) | ||
expect($('h1').text()).toBe('Parameter: hello') | ||
|
||
// Check if the page is not statically generated. | ||
if (isNextStart) { | ||
const id = $('#nanoid').text() | ||
const $2 = await next.render$(url) | ||
const id2 = $2('#nanoid').text() | ||
expect(id).not.toBe(id2) | ||
} | ||
}) | ||
|
||
it('should not bailout when not using searchParams', async () => { | ||
const url = '/client-component-without-searchparams?search=hello' | ||
const $ = await next.render$(url) | ||
expect($('h1').text()).toBe('No searchParams used') | ||
|
||
// Check if the page is not statically generated. | ||
if (isNextStart) { | ||
const id = $('#nanoid').text() | ||
const $2 = await next.render$(url) | ||
const id2 = $2('#nanoid').text() | ||
expect(id).toBe(id2) | ||
} | ||
}) | ||
}) | ||
} | ||
) |
24 changes: 24 additions & 0 deletions
24
test/e2e/app-dir/searchparams-static-bailout/tsconfig.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"compilerOptions": { | ||
"lib": ["dom", "dom.iterable", "esnext"], | ||
"allowJs": true, | ||
"skipLibCheck": true, | ||
"strict": false, | ||
"forceConsistentCasingInFileNames": true, | ||
"noEmit": true, | ||
"incremental": true, | ||
"esModuleInterop": true, | ||
"module": "esnext", | ||
"moduleResolution": "node", | ||
"resolveJsonModule": true, | ||
"isolatedModules": true, | ||
"jsx": "preserve", | ||
"plugins": [ | ||
{ | ||
"name": "next" | ||
} | ||
] | ||
}, | ||
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"], | ||
"exclude": ["node_modules"] | ||
} |