# Reference Architecture: Marketing Website

> Source: https://agilitycms.com/docs/developers/reference-architecture-marketing-site

This is the most common Agility solution: one brand's public website, where marketers create and arrange pages themselves and developers own the front end. Pages are rendered ahead of time and cached, and publishing in Agility clears exactly the cache entries that changed.

The examples use Next.js, which is the framework the Agility starter and most of these docs use. The same shape works with ASP.NET Core or any framework that can cache rendered output and expose a webhook endpoint. See [Why We Recommend Next.js and .NET](/docs/developers/why-we-recommend-nextjs-and-dotnet).

## Components

| Component | Owned by | Role |
| --- | --- | --- |
| Agility instance, one sitemap | Agility (you configure it) | Pages, components, content lists, assets, workflow |
| Content Fetch API (or GraphQL) | Agility | Published content for the live site, latest saved content for preview |
| Asset CDN (`cdn.aglty.io`) | Agility | Images and files, resized and converted by query string |
| Next.js app | You | Renders pages from the sitemap, caches every CMS read with a tag |
| Host and its CDN (for example Vercel or Netlify) | You | Serves rendered pages to visitors |
| Revalidation endpoint | You | Receives Agility webhooks and clears the matching cache tags |
| Preview deployment | You | The same app, reading with the preview key, opened by Web Studio |

## Data flow

**When a visitor asks for a page:**

| Step | From | To | What happens |
| --- | --- | --- | --- |
| 1 | Browser | Your host's CDN | A cached page is returned straight away |
| 2 | Your host | Next.js | On a miss, the route resolves the path from the cached flat sitemap |
| 3 | Next.js | Data cache | The page and its components are read through cached, tagged wrappers |
| 4 | Next.js | Content Fetch API | Only for entries not yet cached. Responses on Agility's CDN don't count towards the rate limit |
| 5 | Browser | `cdn.aglty.io` | Images load from the asset CDN at the size the page asks for |

**When an editor publishes:**

| Step | From | To | What happens |
| --- | --- | --- | --- |
| 1 | Editor | Agility | Content or a page is published |
| 2 | Agility | Its own CDN | Cached API responses for that content are invalidated |
| 3 | Agility | Your revalidation endpoint | A webhook with `state`, `contentID` or `pageID`, `referenceName` and `languageCode` |
| 4 | Your endpoint | Next.js cache | Clears the tags for that item, its list, and for pages the sitemap |
| 5 | Next visitor | Your site | The page is rendered again with fresh content and cached again |

## Caching

| Layer | What it holds | How it is cleared |
| --- | --- | --- |
| Agility's CDN | Content API responses and assets | Automatically, when content is published |
| Your data cache | Each CMS read, tagged by item, list, page and sitemap | Your webhook endpoint calls `revalidateTag` |
| Your rendered pages | HTML for each route | Cleared with the tags the page used |
| Your host's CDN | Rendered pages at the edge | Your host's revalidation, triggered by the above |
| Browsers | Pages and images | Your `Cache-Control` headers |

Cache published reads for a long time and rely on webhooks to clear them, rather than on short timers. [Caching with Next.js and Agility](/docs/nextjs/caching-with-next-js-and-agility) shows the tag scheme (`agility-content-{id}-{locale}`, `agility-page-{pageID}-{locale}`, `agility-sitemap-flat-{locale}`) and a complete revalidation route.

Never cache preview reads. Preview responses must bypass the data cache so editors always see their latest save.

## Preview

1. Register two deployments for the sitemap in **Settings > Sitemaps**: production, and preview. See [Setting Up Preview](/docs/developers/setting-up-preview).
2. When an editor previews, Agility opens your site with `agilitypreviewkey` in the query string. Your app validates it, turns on draft mode and reads with the preview API key.
3. Send `Content-Security-Policy: frame-ancestors 'self' https://app.agilitycms.com;` so Web Studio can frame the site, and load the Web Studio SDK. See [Set Up Web Studio with Any Framework](/docs/developers/web-studio-setup-any-framework).
4. Make sure preview requests reach your app rather than a cached page. [Preview URL Lifecycle](/docs/nextjs/preview-url-lifecycle) explains why this matters on Next.js.

## Failure modes

| What goes wrong | What visitors or editors see | Design for it |
| --- | --- | --- |
| A webhook delivery fails | Published changes don't appear | Turn on webhook retries and check the webhook's **History**. Retries are off by default. See [Webhook Events and Payload Reference](/docs/developers/webhook-events-and-payloads) |
| The handler only handles `Published` | Unpublished pages and items stay on the site | Unpublishing arrives as `state: "Deleted"`. Clear the cache for it too |
| A build or traffic burst sends too many uncached requests | `429` responses, missing content in the build | Limit build concurrency and cache every read. See [Handle Rate Limits and Outages Gracefully](/docs/developers/handle-rate-limits-and-outages) |
| A content request fails during rendering | An empty section, or an empty page cached for a long time | `@agility/content-fetch` 2.0.11 logs a failed request and returns `undefined` instead of throwing. Check the result and throw, so the last good page keeps being served |
| The Agility API is unavailable | Nothing, for pages already cached | Prerendered and cached pages keep serving. Only uncached routes and preview are affected |
| Preview shows published content | Editors think their change is lost | A CDN answered before your app checked the preview key. See [Troubleshooting Web Studio](/docs/developers/troubleshooting-web-studio) |
| The site refuses to load in Web Studio | A blank frame | An `X-Frame-Options` header or a `frame-ancestors` directive without `https://app.agilitycms.com` |

## Related

- [Reference Architectures](/docs/developers/reference-architectures)
- [Caching with Next.js and Agility](/docs/nextjs/caching-with-next-js-and-agility)
- [Webhooks](/docs/developers/webhooks)
- [Fetch API Status Codes and Caching](/docs/developers/fetch-api-status-codes-and-caching)
- [Content Delivery & CDN Architecture](/docs/developers/content-delivery-and-cdn-architecture)
- [Website Deployment Checklist](/docs/developers/website-deployment-checklist)
