What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
Tutorials
The best way to host your Next.js site is on the platform built by the creators of Next.js!
Vercel is built by the team behind Next.js, so every Next.js feature works there on the day it ships — including Cache Components, the proxy, and on-demand revalidation. This guide covers deploying an Agility-powered Next.js site, wiring up publish-triggered updates, and the two settings that most often break preview after a successful deploy.
The fastest path. In the Agility Manager, go to Settings → Deployment and click Setup Deployment for Vercel.
Note: You'll need a GitHub account and a Vercel account.
The wizard then:
AGILITY_* environment variables on the Vercel project — for Production and Preview both.That last step is what makes preview work without you configuring anything: Agility now knows which URL to open when an editor clicks Preview.
If your project isn't based on a starter:
Push your repository to GitHub, GitLab or Bitbucket.
At vercel.com/new, import it. Vercel detects Next.js and needs no build configuration.
Add your environment variables:
| Variable | Purpose |
|---|---|
AGILITY_GUID | Your instance identifier |
AGILITY_API_FETCH_KEY | Live (published) content |
AGILITY_API_PREVIEW_KEY | Draft content, for preview |
AGILITY_SECURITY_KEY | Validates preview links and webhooks |
AGILITY_LOCALES | Comma-separated, first is the default |
AGILITY_SITEMAP | Sitemap channel name, usually website |
Set them for Production, Preview and Development. A missing key on Preview is the classic cause of "it works in production but every preview deploy 500s."
Deploy, then install the Agility CMS integration from the Vercel Marketplace to link the project back to your instance.
Coming from the older recipe? This guide used to show
getStaticPathswithfallback: trueplusrevalidate: 10ingetStaticProps— Incremental Static Regeneration on a timer. That model is gone in the App Router, and route segment configs likeexport const revalidateare rejected outright whencacheComponentsis enabled. The replacement is better: instead of every page re-checking on a stopwatch, a publish webhook invalidates exactly the affected cache tags, so the change is live in seconds and nothing else re-renders.
With Cache Components, each content read is cached and tagged:
const cachedContentItem = async (params) => {
"use cache"
cacheTag(`agility-content-${params.contentID}-${params.languageCode}`)
cacheLife("days")
return fetchContentItem(params)
}
and a route handler clears those tags when Agility says something changed:
// app/api/revalidate/route.ts
import { revalidateTag } from "next/cache"
export async function POST(req: NextRequest) {
const data = await req.json()
if (data.state === "Published" && data.referenceName) {
// Next 16 requires the second argument — the cache profile to expire
revalidateTag(`agility-content-${data.referenceName}-${data.languageCode}`, "max")
}
return NextResponse.json({ revalidated: true })
}
revalidateTag(tag)with one argument is a Next 15 signature. In Next 16 it takes a cache-life profile as a second argument, and omitting it is a build error.
In the Manager, go to Settings → Web Hooks and add one pointing at https://your-site.com/api/revalidate. Check Receive Content Publish Events, and send a Test Payload to confirm you get a success response before relying on it.
If you want to trigger a full rebuild instead — appropriate if you don't use tag revalidation — create a Deploy Hook in Vercel under Settings → Git → Deploy Hooks and point the Agility webhook at that URL.
Two things bite here, and both only appear once the site is actually on Vercel.
Vercel serves prerendered pages straight from its edge cache without invoking your proxy. On exactly the pages that matter most, ?agilitypreviewkey= never reaches /api/preview, draft mode is never enabled, and Web Studio quietly shows published content.
The fix is a beforeFiles rewrite, which is compiled into the routes manifest and evaluated before the cache lookup:
// next.config.mjs
async rewrites() {
return {
beforeFiles: [
{
source: "/:path((?!api).*)",
has: [{ type: "query", key: "agilitypreviewkey" }],
destination: "/api/preview?slug=/:path",
},
],
}
}
Keep the proxy logic as well — it handles uncached requests. Full detail in Handling Preview URLs & Request Lifecycle.
Vercel protects preview deployments by default. Agility's preview requests and your webhook calls arrive unauthenticated and get an SSO page instead of your site — so preview shows a Vercel login screen, and publishes appear not to revalidate.
Under Settings → Deployment Protection, either add a Protection Bypass for Automation secret and configure it in your Agility integration, or scope protection so the domain Agility calls is reachable. Don't simply switch protection off.
prebuild — if your project syncs redirects or other data before building (npm runs prebuild automatically before build), confirm that step has the env vars it needs on Vercel, not just locally..next/cache between builds, which is what keeps incremental builds fast. Use Redeploy without cache when debugging a build that succeeds locally but not on Vercel.curl -I https://your-site.com/about-us # 200, with cache headers
curl -I https://your-site.com/no-such-page # a real 404, not a 200
curl -X POST https://your-site.com/api/revalidate \
-H "Content-Type: application/json" -d '{"state":"Published", ...}'
Then publish a change in Agility and confirm it appears on the live site within seconds — the end-to-end test that actually proves the wiring.
AGILITY_* variable on all three environments.revalidateTag(tag, "max").beforeFiles preview rewrite, or preview breaks on exactly the cached pages editors care about.