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

102 lines
2.9 KiB
TypeScript

import { cacheLife } from 'next/cache'
import Link from 'next/link'
import { Suspense } from 'react'
import { LinkAccordion } from '../../../components/link-accordion'
type Params = { teamSlug: string; project: string }
export default function TeamProjectPage({
params,
}: {
params: Promise<Params>
}) {
return (
<div id="team-project-page">
<Suspense
fallback={<div data-loading="true">Loading team/project route...</div>}
>
<TeamProjectContent params={params} />
</Suspense>
<nav data-nav-link-list="true">
<ul>
<li>
<Link href="/" data-nav-link="/">
Navigate: home
</Link>
</li>
<li>
<Link href="/acme/dashboard" data-nav-link="/acme/dashboard">
Navigate: acme/dashboard
</Link>
</li>
<li>
<Link href="/globex/portal" data-nav-link="/globex/portal">
Navigate: globex/portal
</Link>
</li>
<li>
<Link
href="/acme/dashboard/settings"
data-nav-link="/acme/dashboard/settings"
>
Navigate: acme/dashboard/settings
</Link>
</li>
<li>
<Link
href="/globex/portal/settings"
data-nav-link="/globex/portal/settings"
>
Navigate: globex/portal/settings
</Link>
</li>
<li>
<Link
href="/acme/dashboard/settings/domains"
data-nav-link="/acme/dashboard/settings/domains"
>
Navigate: acme/dashboard/settings/domains
</Link>
</li>
<li>
<Link
href="/globex/portal/settings/domains"
data-nav-link="/globex/portal/settings/domains"
>
Navigate: globex/portal/settings/domains
</Link>
</li>
</ul>
</nav>
<div data-related-link-list="true">
<LinkAccordion href="/acme/dashboard">
Related route: acme/dashboard
</LinkAccordion>
<LinkAccordion href="/globex/portal">
Related route: globex/portal
</LinkAccordion>
<LinkAccordion href="/acme/dashboard/settings/domains">
Related route: acme/dashboard/settings/domains
</LinkAccordion>
<LinkAccordion href="/globex/portal/settings/domains">
Related route: globex/portal/settings/domains
</LinkAccordion>
</div>
</div>
)
}
async function TeamProjectContent({ params }: { params: Promise<Params> }) {
'use cache'
cacheLife({ stale: 0, revalidate: 1, expire: 60 })
const { teamSlug, project } = await params
const marker = Date.now()
return (
<div data-team-project-content="true">
{`Team project content - team: ${teamSlug}, project: ${project}, marker: ${marker}`}
</div>
)
}