Skip to content
16 changes: 16 additions & 0 deletions examples/app-router/app/api/after/revalidate/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { revalidateTag } from "next/cache";
import { NextResponse, unstable_after as after } from "next/server";

export function POST() {
after(
() =>
new Promise<void>((resolve) =>
setTimeout(() => {
revalidateTag("date");
resolve();
}, 5000),
),
);

return NextResponse.json({ success: true });
}
13 changes: 13 additions & 0 deletions examples/app-router/app/api/after/ssg/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { unstable_cache } from "next/cache";
import { NextResponse } from "next/server";

export const dynamic = "force-static";

export async function GET() {
const dateFn = unstable_cache(() => new Date().toISOString(), ["date"], {
tags: ["date"],
});
const date = await dateFn();
console.log("date", date);
return NextResponse.json({ date: date });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small nit

Suggested change
console.log("date", date);
return NextResponse.json({ date: date });
console.log({ date });
return NextResponse.json({ date });

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think i'll remove the console.log entirely, not really useful

}
3 changes: 3 additions & 0 deletions examples/app-router/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ const nextConfig: NextConfig = {
},
],
},
experimental: {
after: true,
},
redirects: async () => {
return [
{
Expand Down
29 changes: 29 additions & 0 deletions packages/tests-e2e/tests/appRouter/after.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { test, expect } from "@playwright/test";

test("Next after", async ({ request }) => {
const initialSSG = await request.get("/api/after/ssg");
expect(initialSSG.status()).toEqual(200);
const initialSSGJson = await initialSSG.json();

// We then fire a post request that will revalidate the SSG page 5 seconds after, but should respond immediately
const dateNow = Date.now();
const revalidateSSG = await request.post("/api/after/revalidate");
expect(revalidateSSG.status()).toEqual(200);
const revalidateSSGJson = await revalidateSSG.json();
expect(revalidateSSGJson.success).toEqual(true);
// This request should take less than 5 seconds to respond
expect(Date.now() - dateNow).toBeLessThan(5000);

// We want to immediately check if the SSG page has been revalidated, it should not have been
const notRevalidatedSSG = await request.get("/api/after/ssg");
expect(notRevalidatedSSG.status()).toEqual(200);
const notRevalidatedSSGJson = await notRevalidatedSSG.json();
expect(notRevalidatedSSGJson.date).toEqual(initialSSGJson.date);

// We then wait for 5 seconds to ensure the SSG page has been revalidated
await new Promise((resolve) => setTimeout(resolve, 5000));
const revalidatedSSG = await request.get("/api/after/ssg");
expect(revalidatedSSG.status()).toEqual(200);
const revalidatedSSGJson = await revalidatedSSG.json();
expect(revalidatedSSGJson.date).not.toEqual(initialSSGJson.date);
});