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", - }, }; });