Site Config & SEO
CWA's SEO layer is built on top of @nuxtjs/seo — the full Nuxt SEO bundle is available to you out of the box, including useSeoMeta, useSchemaOrg, robots meta, sitemap generation, and OG image support. CWA layers on top of it with API-driven site config and automatic per-page meta from your Page and PageData records.
Site-wide settings are stored in the API and cached in Pinia. Admins change them at /_cwa/settings — no deploy required.
Default Settings
The module ships with sensible defaults:
| Key | Default | Description |
|---|---|---|
siteName | 'CWA Web App' | Used in <title> concatenation |
fallbackTitle | true | Show siteName when a page has no title |
concatTitle | true | Append | siteName to page titles |
indexable | true | Whether search engines should index the site |
canonicalUrl | '' | Base URL for canonical tags |
sitemapEnabled | true | Generate /sitemap.xml from routes |
maintenanceModeEnabled | false | Redirect all non-admin visitors to maintenance page |
robotsText | '' | Custom robots.txt content |
robotsAllowNonSeoCrawlers | true | Allow non-SEO bots |
robotsAllowAiBots | true | Allow AI crawlers |
Accessing Site Config
Use cwa.siteConfig.config — it's a reactive store getter:
const cwa = useCwa()
const siteName = computed(() => cwa.siteConfig.config.value?.siteName)
const isMaintenanceMode = computed(() => cwa.siteConfig.config.value?.maintenanceModeEnabled)
const sitemapEnabled = computed(() => cwa.siteConfig.config.value?.sitemapEnabled)
Or use useCwaSiteConfig directly for utility functions:
import { useCwaSiteConfig } from '#imports'
const { defaultSiteConfig } = useCwaSiteConfig()
Saving Config Changes (Admin)
const result = cwa.siteConfig.saveConfig({
siteName: 'My Rebranded Site',
maintenanceModeEnabled: false,
robotsAllowAiBots: false
})
// result.totalConfigsChanged — number of keys that actually changed
// Only changed keys are PATCHed to the API
Per-Page SEO
The route resolution middleware automatically applies SEO meta tags from the current page or page data:
| Source | Applied as |
|---|---|
Page.title | <title> |
Page.metaDescription | <meta name="description"> |
PageData.title | Overrides Page.title |
PageData.metaDescription | Overrides Page.metaDescription |
These are wired into @nuxtjs/seo via useSeoMeta(). You can add your own after the middleware runs and your call will win:
// In a page template component
useHead({
title: computed(() => `${articleHeadline.value} - In-depth Guide`)
})
Default OG Image
The module ships a default Open Graph image template via nuxt-og-image. Every CWA page automatically gets a dark-background social card containing the CWA logo, the page title, and the meta description — no setup required.
The template is CwaDefault.satori.vue (a Satori/SVG renderer). It receives:
| Prop | Source |
|---|---|
title | Current page or pageData title |
description | Current page or pageData meta description |
Previewing locally — visit /__og-image__/image/your-path/og.png to preview the generated image for any route.
Overriding the OG image
Per-page override — call defineOgImage() in your page template component. Your call replaces the module default for that route:
// In your page template <script setup>
defineOgImage('MyCustomTemplate', {
title: pageData.value?.data?.headline,
imageUrl: pageData.value?.data?.heroImage?.contentUrl
})
Project-wide override — create app/components/og-image/CwaDefault.satori.vue in your application. Nuxt resolves component names from the app layer first, so this shadows the module's default template for all pages that haven't overridden per-page.
Open Graph and Twitter Cards
Social card meta tags (og:title, og:description, og:image, twitter:card) are too content-specific for the module to set automatically — add them in your page templates alongside your own content fields:
useSeoMeta({
ogTitle: computed(() => pageData.value?.data?.headline),
ogDescription: computed(() => pageData.value?.data?.summary),
ogImage: computed(() => pageData.value?.data?.heroImage?.contentUrl),
twitterCard: 'summary_large_image'
})
Maintenance Mode
When maintenanceModeEnabled: true, the module redirects all non-admin visitors to /_cwa/maintenance. Admins are not redirected and can still access the site to turn maintenance mode off.
Override the maintenance page by creating app/pages/_cwa/maintenance.vue.
Sitemap
/sitemap.xml is auto-generated from all Route resources in the API. Only published, public routes are included. Customise priority and changefreq per-route in the admin under /_cwa/routes.
Disable sitemap generation if you manage it externally:
// Admin settings panel → Sitemap → Disabled
// Or programmatically:
cwa.siteConfig.saveConfig({ sitemapEnabled: false })
Nuxt Config Overrides (Static Defaults)
You can set site config defaults in nuxt.config — these are merged with the API's stored values, with the API winning for any key it defines:
// nuxt.config.ts
cwa: {
siteConfig: {
siteName: 'My App',
canonicalUrl: 'https://www.example.com'
}
}
This lets you ship a sensible default without requiring a database record on first boot.