Skip to content

Commit 58cd581

Browse files
authored
Fix: Add support for revalidateTag (#145)
* feat: add revalidateTag handling * fix: do not override tags on page set * fix: force revalidation for stale tags and write meta for page * fix: patch fetch function * fix for 13.4.20 * add docs to help retrieve paths * custom provider to populate dynamodb * fix for esm loader * fix for next bundled 13.5 * revert serverHandler to use custom routing * remove patchFetch as it no longer works * docs: add docs about fetch behaviour * get fetch cache tags directly from cache file
1 parent affbe5d commit 58cd581

File tree

11 files changed

+893
-275
lines changed

11 files changed

+893
-275
lines changed

README.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,35 @@ await invalidateCFPaths(["/page/a", "/page/b", "/page/c"]);
329329
await invalidateCFPaths(["/page/*"]);
330330
```
331331

332-
Please note that on-demand revalidation via the [`next/cache` module](https://nextjs.org/docs/app/building-your-application/data-fetching/revalidating#using-on-demand-revalidation) (`revalidatePath` and `revalidateTag`) is not yet supported.
332+
For on-demand revalidation via the [`next/cache` module](https://nextjs.org/docs/app/building-your-application/data-fetching/revalidating#using-on-demand-revalidation), if you want to retrieve the associated paths for a given tag, you can use this function:
333+
334+
```ts
335+
function getByTag(tag: string) {
336+
try {
337+
const { Items } = await this.dynamoClient.send(
338+
new QueryCommand({
339+
TableName: process.env.CACHE_DYNAMO_TABLE,
340+
KeyConditionExpression: "#tag = :tag",
341+
ExpressionAttributeNames: {
342+
"#tag": "tag",
343+
},
344+
ExpressionAttributeValues: {
345+
":tag": { S: `${process.env.NEXT_BUILD_ID}/${tag}` },
346+
},
347+
}),
348+
);
349+
return (
350+
// We need to remove the buildId from the path
351+
Items?.map(
352+
({ path: { S: key } }) => key?.replace(`${process.env.NEXT_BUILD_ID}/`, "") ?? "",
353+
) ?? []
354+
);
355+
} catch (e) {
356+
error("Failed to get by tag", e);
357+
return [];
358+
}
359+
}
360+
```
333361

334362
## How warming works
335363

@@ -383,6 +411,19 @@ This cost estimate is based on the `us-east-1` region pricing and does not consi
383411

384412
## Limitations and workarounds
385413

414+
#### WORKAROUND: Patch fetch behaviour for ISR. Only for [email protected]+
415+
416+
In order to make fetch work as expected with ISR, you need to patch the `fetch` function in your app. Just add this lines to your root layout component:
417+
418+
```ts
419+
const asyncStorage = require("next/dist/client/components/static-generation-async-storage.external");
420+
//@ts-ignore
421+
const staticStore = (fetch as any).__nextGetStaticStore?.() || asyncStorage.staticGenerationAsyncStorage;
422+
const store = staticStore.getStore();
423+
store.isOnDemandRevalidate = store.isOnDemandRevalidate && !(process.env.OPEN_NEXT_ISR === 'true');
424+
```
425+
Without this workaround, if you have 2 fetch calls in your page with different revalidate values, both will use the smallest value during ISR revalidation.
426+
386427
#### WORKAROUND: Create one cache behavior per top-level file and folder in `public/` (AWS specific)
387428

388429
As mentioned in the [Asset files](#asset-files) section, files in your app's `public/` folder are static and are uploaded to the S3 bucket. And requests for these files are handled by the S3 bucket, like so:

packages/open-next/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"README.md"
3535
],
3636
"dependencies": {
37+
"@aws-sdk/client-dynamodb": "^3.398.0",
3738
"@aws-sdk/client-lambda": "^3.398.0",
3839
"@aws-sdk/client-s3": "^3.398.0",
3940
"@aws-sdk/client-sqs": "^3.398.0",

0 commit comments

Comments
 (0)