diff --git a/packages/next/src/server/web/spec-extension/revalidate-tag.ts b/packages/next/src/server/web/spec-extension/revalidate-tag.ts index 620545987eae6..fcd3be4fb80c3 100644 --- a/packages/next/src/server/web/spec-extension/revalidate-tag.ts +++ b/packages/next/src/server/web/spec-extension/revalidate-tag.ts @@ -2,6 +2,7 @@ import type { StaticGenerationAsyncStorage, StaticGenerationStore, } from '../../../client/components/static-generation-async-storage.external' +import { staticGenerationBailout } from '../../../client/components/static-generation-bailout' export function revalidateTag(tag: string) { const staticGenerationAsyncStorage = ( @@ -16,6 +17,11 @@ export function revalidateTag(tag: string) { `Invariant: static generation store missing in revalidateTag ${tag}` ) } + + // a route that makes use of revalidation APIs should be considered dynamic + // as otherwise it would be impossible to revalidate + staticGenerationBailout(`revalidateTag ${tag}`) + if (!store.revalidatedTags) { store.revalidatedTags = [] } diff --git a/test/e2e/app-dir/revalidate-dynamic/app/api/revalidate-path/route.js b/test/e2e/app-dir/revalidate-dynamic/app/api/revalidate-path/route.js new file mode 100644 index 0000000000000..602822742a442 --- /dev/null +++ b/test/e2e/app-dir/revalidate-dynamic/app/api/revalidate-path/route.js @@ -0,0 +1,7 @@ +import { NextResponse } from 'next/server' +import { revalidatePath } from 'next/cache' + +export async function GET(req) { + revalidatePath('/') + return NextResponse.json({ revalidated: true, now: Date.now() }) +} diff --git a/test/e2e/app-dir/revalidate-dynamic/app/api/revalidate-tag/route.js b/test/e2e/app-dir/revalidate-dynamic/app/api/revalidate-tag/route.js new file mode 100644 index 0000000000000..5fc2a51a59a52 --- /dev/null +++ b/test/e2e/app-dir/revalidate-dynamic/app/api/revalidate-tag/route.js @@ -0,0 +1,7 @@ +import { NextResponse } from 'next/server' +import { revalidateTag } from 'next/cache' + +export async function GET(req) { + revalidateTag('thankyounext') + return NextResponse.json({ revalidated: true, now: Date.now() }) +} diff --git a/test/e2e/app-dir/revalidate-dynamic/app/layout.js b/test/e2e/app-dir/revalidate-dynamic/app/layout.js new file mode 100644 index 0000000000000..0ea378c6fcbbd --- /dev/null +++ b/test/e2e/app-dir/revalidate-dynamic/app/layout.js @@ -0,0 +1,7 @@ +export default function Layout({ children }) { + return ( + +
{children} + + ) +} diff --git a/test/e2e/app-dir/revalidate-dynamic/app/page.js b/test/e2e/app-dir/revalidate-dynamic/app/page.js new file mode 100644 index 0000000000000..2d510fb21aba8 --- /dev/null +++ b/test/e2e/app-dir/revalidate-dynamic/app/page.js @@ -0,0 +1,17 @@ +export default async function Page() { + const data = await fetch( + 'https://next-data-api-endpoint.vercel.app/api/random', + { + next: { + tags: ['thankyounext'], + }, + } + ).then((res) => res.text()) + + return ( + <> + Data: +