diff --git a/.changeset/warm-kangaroos-retire.md b/.changeset/warm-kangaroos-retire.md
new file mode 100644
index 000000000..f100fd02e
--- /dev/null
+++ b/.changeset/warm-kangaroos-retire.md
@@ -0,0 +1,6 @@
+---
+"framesjs-starter": patch
+"docs": patch
+---
+
+fix: cache control example
diff --git a/docs/pages/guides/caching.mdx b/docs/pages/guides/caching.mdx
index 76c62f463..1d3e56cd8 100644
--- a/docs/pages/guides/caching.mdx
+++ b/docs/pages/guides/caching.mdx
@@ -5,19 +5,41 @@ description: ""
# Caching
-You can set the caching policy of your frames by defining the `Cache-Control` headers of your responses
+You can set the caching policy of your frames by defining the `Cache-Control` headers of your frame's **image response**
-```tsx
+Since images are returned as an inline Data URL by default, this will require you to create a separate endpoint for your dynamic images that you want to avoid caching for.
+
+```tsx [frames/route.tsx]
// ...
const handleRequest = frames(async (ctx) => {
return {
+ image: "/images/my-image",
// ...
- headers: {
- // Max cache age of 5 seconds
- "Cache-Control": "max-age=5",
- },
};
});
```
+```tsx [frames/images/my-image.tsx]
+import { NextRequest } from "next/server";
+import { ImageResponse } from "@vercel/og";
+
+export async function GET(req: NextRequest) {
+ const imageResponse = new ImageResponse(
+ (
+
+ The current time is {new Date().toLocaleString()}
+
+ ),
+ { width: 1146, height: 600 }
+ );
+
+ // Set the cache control headers to ensure the image is not cached
+ imageResponse.headers.set("Cache-Control", "public, max-age=0");
+
+ return imageResponse;
+}
+```
+
+Additional context can be passed to the image endpoint via URL query params.
+
See an example of how to use the `Cache-Control` header in the [Caching example](https://github.com/framesjs/frames.js/tree/main/examples/framesjs-starter/app/examples/new-api-cache-control).
diff --git a/examples/framesjs-starter/app/examples/new-api-cache-control/frames/frames.ts b/examples/framesjs-starter/app/examples/new-api-cache-control/frames/frames.ts
index fe4ae3f1e..6e3474064 100644
--- a/examples/framesjs-starter/app/examples/new-api-cache-control/frames/frames.ts
+++ b/examples/framesjs-starter/app/examples/new-api-cache-control/frames/frames.ts
@@ -1,5 +1,5 @@
import { createFrames } from "frames.js/next";
export const frames = createFrames({
- basePath: "/examples/new-api-cache-control",
+ basePath: "/examples/new-api-cache-control/frames",
});
diff --git a/examples/framesjs-starter/app/examples/new-api-cache-control/frames/images/current-time/route.tsx b/examples/framesjs-starter/app/examples/new-api-cache-control/frames/images/current-time/route.tsx
new file mode 100644
index 000000000..1cfd0e020
--- /dev/null
+++ b/examples/framesjs-starter/app/examples/new-api-cache-control/frames/images/current-time/route.tsx
@@ -0,0 +1,18 @@
+import { NextRequest } from "next/server";
+import { ImageResponse } from "@vercel/og";
+
+export async function GET(req: NextRequest) {
+ const imageResponse = new ImageResponse(
+ (
+
+ The current time is {new Date().toLocaleString()}
+
+ ),
+ { width: 1146, height: 600 }
+ );
+
+ // Set the cache control headers to ensure the image is not cached
+ imageResponse.headers.set("Cache-Control", "public, max-age=0");
+
+ return imageResponse;
+}
diff --git a/examples/framesjs-starter/app/examples/new-api-cache-control/frames/route.tsx b/examples/framesjs-starter/app/examples/new-api-cache-control/frames/route.tsx
index 0b8a89e6f..aa92d85f8 100644
--- a/examples/framesjs-starter/app/examples/new-api-cache-control/frames/route.tsx
+++ b/examples/framesjs-starter/app/examples/new-api-cache-control/frames/route.tsx
@@ -1,22 +1,14 @@
/* eslint-disable react/jsx-key */
import { Button } from "frames.js/next";
import { frames } from "./frames";
+import { vercelURL } from "../../../utils";
const handleRequest = frames(async (ctx) => {
return {
- image: (
-
- The current time is {new Date().toLocaleString()}
-
- ),
- imageOptions: {
- aspectRatio: "1:1",
- },
+ // Separate image response because cache control headers need to be set on the image response
+ // Add a random query param to ensure the frame action response image is not cached
+ image: `/images/current-time?t=${Math.random()}`,
buttons: [],
- headers: {
- // Max cache age in seconds
- "Cache-Control": "max-age=5",
- },
};
});