@atlas/nuxt
A Nuxt 4 layer that turns an AtlasCMS brand into a website: catch-all route, block renderer, SEO, redirects, preview and purge.
2 min read
Install and extend
Install the four packages at the same version (@atlas/nuxt, @atlas/blocks, @atlas/client, @atlas/tokens) as described in the client guide, then extend the layer.
export default defineNuxtConfig({
extends: ['@atlas/nuxt'],
})NUXT_ATLAS_API_URL=https://api.atlascms.id
NUXT_ATLAS_TOKEN=atl_read_...
NUXT_ATLAS_PURGE_SECRET=the-webhook-secretWhat you get
- A catch-all route that asks the API for the page at the visited path and renders its blocks. A page file in your own app wins over the catch-all.
- A block renderer and a block library, with your own brand blocks added next to it.
- The theme tokens as CSS variables, header, footer and templates from the active theme.
- SEO: titles, canonical links, Open Graph and generated share images, JSON-LD, sitemap,
robots.txt,llms.txtand IndexNow. - Redirects from the API, category and tag archives, and a posts index.
- Consent Mode v2 and consent-gated analytics, and a lead form block that posts through a rate limited server route.
- Preview mode and the visual editor bridge for the dashboard.
- The signed purge route described in webhooks.
Configuration keys
| Key (environment) | Purpose |
|---|---|
atlas.apiUrl (NUXT_ATLAS_API_URL) | The API address. |
atlas.token (NUXT_ATLAS_TOKEN) | The read token of a single brand deployment. |
atlas.purgeSecret (NUXT_ATLAS_PURGE_SECRET) | The webhook secret of a single brand deployment. |
atlas.sites (NUXT_ATLAS_SITES) | Run several brands in one app: a JSON array of { host, brand, token, purgeSecret }. A host outside the list is answered 421. |
atlas.brandSlug (NUXT_ATLAS_BRAND_SLUG) | The brand a preview token must belong to. |
atlas.editorOrigins (NUXT_ATLAS_EDITOR_ORIGINS) | Dashboard origins allowed to frame previews and drive the editor bridge. Empty turns the bridge off. |
atlas.trustProxy (NUXT_ATLAS_TRUST_PROXY) | Believe X-Forwarded-For and forward the visitor address to the API. |
atlas.formsEndpoint (NUXT_ATLAS_FORMS_ENDPOINT) | Override the lead target. Use {key} for the form key. |
ogImage.secret (NUXT_OG_IMAGE_SECRET) | Signs share image links. Required in production and the same on every instance. |
public.atlas.locales, defaultLocale | The languages of the site. |
Composables
Every composable uses an explicit fetch key, so server data survives hydration. If you wrap useFetch in your own code, give it an explicit key too.
| Composable | Use |
|---|---|
useAtlasPage() | The page entry a block is rendered on: fields, terms, seo, dates. Prefer it over copying text into block props. |
useAtlasEntries(params) | A cursor paged list of one entry type. |
useAtlasMenu(key, locale) | A navigation menu, or null when the brand has none. |
useAtlasStrings({ locale, namespace }) | Interface texts with a per-key fallback to the default language. |
useAtlasSettings() | The public brand settings. |
useAtlasTheme() | Theme tokens and options. |
const { data: menu } = useAtlasMenu('footer', 'en')
const { data: page } = await useAtlasEntries({ type: 'post', limit: 6, fields: undefined })Brand blocks
Generic blocks ship in @atlas/blocks. A block only your brand needs lives in your site, with a prefix of its own, and is registered next to the generic ones. Describe each one in a definitions file and run the sync, so the dashboard offers it and the API validates it.
atlas blocks:sync --schemas ./app/atlas/definitions.ts --custom-only --out brand-blocks.jsonThe same command line builds, checks, packs and pushes a theme: atlas theme create, check, pack and push. Pushing needs a developer token.
Preview and the visual editor
Set NUXT_ATLAS_EDITOR_ORIGINS to the dashboard origin. The dashboard then opens your site inside a frame with a short preview token. The layer checks that the token belongs to this brand before it sets its partitioned preview cookie, serves drafts with no-store, adds noindex, and lets the editor click a block to edit it in place.
Was this page helpful?