# From Proof of Concept to Production

> Source: https://agilitycms.com/docs/developers/vibe-coding-to-production

A vibe-coded proof of concept is built to answer one question: can this work, for this use case, on Agility? It's allowed to cut corners to get there. Production isn't. This article lists what a proof of concept typically skips and what to put back before real users or real data arrive.

If you followed [the vibe coding workflow](/docs/developers/vibe-coding-workflow), your handoff notes already list what's simulated and what was left out. Start from that list, then work through the sections below. The general [Website Deployment Checklist](/docs/developers/website-deployment-checklist) applies too.

## Restore webhook signature verification

Your publish webhook endpoint is a public URL. Without a signature check, anyone who finds it can post to it and trigger revalidation, or anything else the handler does.

This is the shortcut most worth looking for. In the builds behind this section, at least two proofs of concept switched off the webhook's secret check to get a demo working. The Agility Next.js Starter's revalidate route doesn't check a signature by default either.

- Verify every request's signature before acting on it. Agility signs webhooks using the Standard Webhooks specification. See [Verifying Signed Webhooks](/docs/developers/verifying-signed-webhooks).
- Reject unsigned and badly signed requests, and log the rejection.
- Search the code for any flag, comment or environment variable that disables the check, and remove it.

## Handle secrets properly

- Keep API keys, the preview key, webhook signing secrets and any Personal Access Token in your host's environment variables or a secrets manager, never in the repository. Check the git history as well as the current files.
- Use separate keys per environment, and rotate anything that was pasted into a conversation, a demo script or a shared document during the proof of concept.
- Never expose the preview key, a management token or a webhook secret to the browser. Read them only in server code, through your typed environment module.
- For unattended automation, use a dedicated automation user and a [Personal Access Token](/docs/developers/personal-access-tokens) with an explicit expiry, not a person's login.

## Get caching and revalidation right

- Confirm that every CMS read goes through your data layer and sets a cache tag, and that the tags your webhook revalidates match those tags exactly. A mismatch works in development and then only refreshes when the time-based revalidation window expires.
- Decide what happens to items that are unpublished or deleted, not only published.
- Remove defensive workarounds added for the demo, such as duplicate routes or "refresh twice" instructions, once caching behaves.
- See [Caching with Next.js and Agility](/docs/nextjs/caching-with-next-js-and-agility) for the full model, including Cache Components.

## Secure preview

- Make sure draft content can never be stored in a shared cache or served to the public. Draft renders must bypass the CDN.
- Validate the preview key on the preview route, and give editors a clear way to exit preview.
- Remove any demo-only preview panels, persona toggles or mocked sign-in from the production build, or put them behind real authentication.
- See [Preview URL Lifecycle](/docs/nextjs/preview-url-lifecycle) and [Setting Up Preview](/docs/developers/setting-up-preview).

## Replace what was simulated

Proofs of concept often mock sign-in, membership lookups, search indexes, inventory feeds or analytics. For each mocked piece in your handoff notes, decide whether it's in scope, and replace it with the real integration or remove it. Gated content in particular needs real authentication and authorization before any of it is genuinely private.

Replace invented sample content too. If you kept a content provenance file, it lists exactly which items were copied, rewritten or invented.

## Accessibility

Automated checks (Lighthouse, axe, contrast checkers) catch a useful share of problems, but they are not a WCAG audit. Before launch:

- Run automated checks in CI so regressions fail the build.
- Test keyboard navigation, focus order and screen reader output by hand on each page model and key component.
- Check that editors can't easily create inaccessible content, for example by making image alt text a required field.

## Tests

A proof of concept usually has none. Add at least:

- A build in CI on every change (`npm run build` type-checks and prerenders every page in the sitemap).
- Tests for your data layer and any transformation of CMS content, including empty, missing and unexpected field values.
- An end-to-end smoke test of the main pages, preview entry and exit, and the webhook route with a signed and an unsigned request.

## Observability

- Log webhook calls, revalidation and errors somewhere you can search.
- Add error monitoring for server and client errors.
- Watch Core Web Vitals in production, not only in a lab test.

## Content governance and the publishing level

During a proof of concept the AI tool often creates and publishes content freely. In production, decide deliberately:

- **Who publishes.** For each content type, choose whether a person reviews and publishes, an approver signs off, or an automation publishes after checks. See [Governing AI Access to Agility CMS](/docs/owners-admins/governing-ai-access).
- **Roles and workflow.** Set up roles, users and approval workflow in the Agility app for the people who will actually edit.
- **The content model.** Review the model with the editors who'll use it every day. Remove fields and models the proof of concept added and nobody needs.

## Performance budgets

Set budgets for page weight, JavaScript, images and Core Web Vitals, and check them in CI. Watch for demo-era shortcuts: unoptimized images, large client components that could be server components, and third-party scripts added for the demo.

## Modern defaults

Proofs of concept are often started from whatever was on hand. Before production, bring the stack up to current defaults:

- **Node.js 24 LTS** for builds and runtime.
- **Next.js 16** (16.3 at the time of writing) with the App Router, **React 19** (19.3) and **Tailwind CSS 4**.
- Current versions of the Agility SDKs.
- Apply framework security patches, and keep applying them. Patches will keep arriving after your demo is over.

Also clean out leftovers: if the project was copied from an earlier build, search for the previous project's names, components, environment variables and copy.

## Related

- [Vibe Coding with Agility](/docs/developers/vibe-coding-with-agility)
- [MCP and Agility Gotchas to Know Before You Build](/docs/developers/vibe-coding-gotchas)
- [Writing an AGENTS.md for Agility Projects](/docs/developers/agents-md-for-agility)
- [Building an Agility Site with AI Coding Tools](/docs/developers/building-sites-with-ai-coding-tools)
