Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/sour-points-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@opennextjs/aws": patch
---

fix fetch cache for next 15
4 changes: 4 additions & 0 deletions examples/app-router/app/ssr/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ async function getTime() {
export default async function SSR() {
const time = await getTime();
const headerList = await headers();
const responseOpenNext = await fetch("https://opennext.js.org", {
cache: "force-cache",
});
return (
<div>
<h1>Time: {time}</h1>
<div> {headerList.get("host")}</div>
<p>Cached fetch: {responseOpenNext.headers.get("date")}</p>
</div>
);
}
31 changes: 24 additions & 7 deletions packages/open-next/src/adapters/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,28 @@ declare global {
var lastModified: Record<string, number>;
var isNextAfter15: boolean;
}

function isFetchCache(
options?:
| boolean
| {
fetchCache?: boolean;
kindHint?: "app" | "pages" | "fetch";
kind?: "FETCH";
},
): boolean {
if (typeof options === "boolean") {
return options;
}
if (typeof options === "object") {
return (
options.kindHint === "fetch" ||
options.fetchCache ||
options.kind === "FETCH"
);
}
return false;
}
// We need to use globalThis client here as this class can be defined at load time in next 12 but client is not available at load time
export default class S3Cache {
constructor(_ctx: CacheHandlerContext) {}
Expand All @@ -122,21 +144,16 @@ export default class S3Cache {
kindHint?: "app" | "pages" | "fetch";
tags?: string[];
softTags?: string[];
kind?: "FETCH";
},
) {
if (globalThis.disableIncrementalCache) {
return null;
}
const isFetchCache =
typeof options === "object"
? options.kindHint
? options.kindHint === "fetch"
: options.fetchCache
: options;

const softTags = typeof options === "object" ? options.softTags : [];
const tags = typeof options === "object" ? options.tags : [];
return isFetchCache
return isFetchCache(options)
? this.getFetchCache(key, softTags, tags)
: this.getIncrementalCache(key);
}
Expand Down
9 changes: 9 additions & 0 deletions packages/tests-e2e/tests/appRouter/ssr.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,12 @@ test("Server Side Render and loading.tsx", async ({ page }) => {
// await expect(el).toBeVisible();
// await expect(time).not.toEqual(newTime);
});

test("Fetch cache properly cached", async ({ page }) => {
await page.goto("/ssr");
const originalDate = await page.getByText("Cached fetch:").textContent();
await wait(2000);
await page.reload();
const newDate = await page.getByText("Cached fetch:").textContent();
expect(originalDate).toEqual(newDate);
});
Loading