Files
9931cc0c85 Fix fallback route params case in app-page handler (#91737)
## Summary
- add production-route-shape fixture coverage for
`/[teamSlug]/[project]/settings/domains`
- add revalidation helpers (API and server action) and browser controls
used by the regression test
- reproduce the failing production sequence by priming, revalidating,
then loading a page with in-view `next/link` and navigating repeatedly

x-ref: https://github.com/vercel/next.js/pull/91627
x-ref: https://github.com/vercel/next.js/pull/91603

## Testing
- `IS_WEBPACK_TEST=1 NEXT_SKIP_ISOLATE=1 NEXT_TEST_MODE=start pnpm
testheadless
test/e2e/app-dir/segment-cache/vary-params-base-dynamic/vary-params-base-dynamic.test.ts
-t "production route shape"` (passes)
- `NEXT_ENABLE_ADAPTER=1 pnpm test-deploy
test/e2e/app-dir/segment-cache/vary-params-base-dynamic/vary-params-base-dynamic.test.ts
-t "production route shape"`
- `NEXT_ENABLE_ADAPTER=1 pnpm test-deploy
test/e2e/app-dir/segment-cache/vary-params-base-dynamic/vary-params-base-dynamic.test.ts`
(fails in the two production-shape cases)

---------

Co-authored-by: Zack Tanner <[email protected]>
2026-04-06 09:37:22 -07:00

130 lines
3.6 KiB
TypeScript

'use client'
import { useState } from 'react'
import {
revalidateLayoutByTagExpireNowAction,
revalidateLayoutByTagLegacyAction,
revalidateLayoutByTagMaxAction,
} from '../app/revalidate-actions'
type ApiRevalidateMode =
| 'tag-layout-expireNow'
| 'tag-layout-max'
| 'tag-layout-legacy'
| 'path-root-layout'
| 'path-team-layout'
| 'path-team-page'
type ServerActionMode =
| 'server-action-tag-layout-expireNow'
| 'server-action-tag-layout-max'
| 'server-action-tag-layout-legacy'
export function RevalidateControls() {
const [result, setResult] = useState('idle')
const [isPending, setIsPending] = useState(false)
const runApiRevalidate = async (mode: ApiRevalidateMode) => {
setIsPending(true)
try {
const response = await fetch(`/api/revalidate-layout?mode=${mode}`, {
method: 'GET',
})
const data = await response.json()
setResult(JSON.stringify(data))
} catch (error) {
setResult(
JSON.stringify({
error: error instanceof Error ? error.message : 'unknown error',
mode,
})
)
} finally {
setIsPending(false)
}
}
const runServerActionRevalidate = async (mode: ServerActionMode) => {
setIsPending(true)
try {
const data =
mode === 'server-action-tag-layout-expireNow'
? await revalidateLayoutByTagExpireNowAction()
: mode === 'server-action-tag-layout-max'
? await revalidateLayoutByTagMaxAction()
: await revalidateLayoutByTagLegacyAction()
setResult(JSON.stringify(data))
} catch (error) {
setResult(
JSON.stringify({
error: error instanceof Error ? error.message : 'unknown error',
mode,
})
)
} finally {
setIsPending(false)
}
}
return (
<div data-revalidate-controls="true">
<button
id="revalidate-in-browser-tag-layout-expireNow"
type="button"
disabled={isPending}
onClick={() => runApiRevalidate('tag-layout-expireNow')}
>
Browser Revalidate Tag Layout (expireNow)
</button>
<button
id="revalidate-in-browser-tag-layout-max"
type="button"
disabled={isPending}
onClick={() => runApiRevalidate('tag-layout-max')}
>
Browser Revalidate Tag Layout (max)
</button>
<button
id="revalidate-in-browser-tag-layout-legacy"
type="button"
disabled={isPending}
onClick={() => runApiRevalidate('tag-layout-legacy')}
>
Browser Revalidate Tag Layout (legacy)
</button>
<button
id="revalidate-in-browser-server-action-tag-layout-expireNow"
type="button"
disabled={isPending}
onClick={() =>
runServerActionRevalidate('server-action-tag-layout-expireNow')
}
>
Server Action Revalidate Tag Layout (expireNow)
</button>
<button
id="revalidate-in-browser-server-action-tag-layout-max"
type="button"
disabled={isPending}
onClick={() =>
runServerActionRevalidate('server-action-tag-layout-max')
}
>
Server Action Revalidate Tag Layout (max)
</button>
<button
id="revalidate-in-browser-server-action-tag-layout-legacy"
type="button"
disabled={isPending}
onClick={() =>
runServerActionRevalidate('server-action-tag-layout-legacy')
}
>
Server Action Revalidate Tag Layout (legacy)
</button>
<div id="revalidate-result" data-revalidate-result={result}>
{result}
</div>
</div>
)
}