Skip to content

Deploy to Vercel

A static site needs nothing special: astro build writes the images and Vercel serves them as files. This guide is for on-demand rendering, where the image route runs inside a serverless function.

Terminal window
pnpm astro add vercel
astro.config.mjs
import { defineConfig } from "astro/config";
import react from "@astrojs/react";
import vercel from "@astrojs/vercel";
import { astroAssetsGeneration } from "@bearstudio/astro-assets-generation";
export default defineConfig({
site: "https://your-domain.com",
integrations: [react(), astroAssetsGeneration()],
adapter: vercel(),
});

Keep astroAssetsGeneration() in the list. On Vercel it does one extra thing: it registers Takumi’s WebAssembly renderer with the adapter’s file tracer, so the file is copied into the function bundle. Without it the function fails at runtime with a message starting with Could not locate the Takumi WASM binary.

src/pages/blog/[slug]/assets/[__image].[__type].ts
import { apiImageEndpoint } from "@bearstudio/astro-assets-generation";
import type { APIRoute } from "astro";
import "../../../../lib/assets";
export const prerender = false;
export const GET: APIRoute = apiImageEndpoint(
import.meta.glob("./_*.tsx", { eager: true }),
);

Delete loadAsset: diskLoader() and the disk-loader import from your config module:

src/lib/assets.ts
import { configure } from "@bearstudio/astro-assets-generation";
configure({
siteUrl: import.meta.env.SITE,
isDev: import.meta.env.DEV,
});

Vercel traces every file your function reads. The disk loader reads from dist/, so leaving it in place ships your whole build output inside the function and can push it over the size limit. Without it, fonts and images are fetched from siteUrl at request time.

siteUrl must be the domain the function can fetch its own assets from. Set site in the Astro config to your production domain. Preview deployments then fetch from production, which is fine as long as the fonts and images exist there.

Terminal window
vercel deploy

Request an image on the deployment and check the function logs. A successful render logs two lines:

[API] Request: og-image/png
[API] Rendering template: _og-image.tsx

Serverless renders cost execution time. Return Cache-Control so Vercel’s edge cache serves repeat requests. See step 6 of the dynamic tutorial for the wrapper.

Netlify and Cloudflare adapters follow the same steps: add the adapter, set prerender = false, remove the disk loader, set siteUrl. The renderer is WebAssembly and needs no native binary, so it runs wherever Node or a compatible runtime does.