Configuration
Configuration
How to configure this module via app.config.ts and environment variables.
app.config.ts
export default defineAppConfig({
ui: {
primary: "brand",
colors: {
primary: "brand",
secondary: "deep",
neutral: "zinc",
},
},
xMarketing: {
name: "X Enterprises",
url: "https://x-enterprises.com",
config: {
markerProjectId: "",
emailMarketingNewsletters: {
organizationId: "",
},
},
header: {
logo: {
src: "",
srcDark: "",
alt: "",
},
nav: {
links: [],
buttons: [],
},
},
footer: {
logo: { src: "", alt: "" },
body: "",
bg: {
color: "",
img: { src: "", alt: "" },
},
socials: [],
columns: [],
},
blog: {
active: true,
title: "Blog",
description: "Welcome to our blog. Here you can find the latest news, updates, and articles.",
meta: {
title: "Blog",
description: "Welcome to our blog. Here you can find the latest news, updates, and articles.",
},
},
// Tracking + analytics — read by <XMarkPrivacyCookieConsent />.
// Scripts only fire after the matching consent category is granted.
tracking: {
gtmId: "GTM-XXXXXXX",
ga4Id: "G-XXXXXXXX",
clarityId: "abc123def4",
scripts: [], // Meta Pixel, Hotjar, Segment, etc.
autoInject: true,
},
},
})
Schema Reference
Top-level
| Key | Type | Default | Description |
|---|---|---|---|
xMarketing.name | string | undefined | Brand/site name. Drives the shipped shell's SEO: when set, app.vue applies the title template "<page> | <name>" via useSeoMeta and emits og:site_name. Leave undefined for bare titles. |
xMarketing.url | string | undefined | Canonical site URL — emitted as og:url on the shipped home page. |
xMarketing.config
| Key | Type | Default | Description |
|---|---|---|---|
config.markerProjectId | string | "" | Marker.io project ID. When set, the Marker.io feedback widget is loaded on mount. Leave empty to disable. |
config.emailMarketingNewsletters.organizationId | string | "" | Email-marketing organization ID for newsletter components that integrate with an external provider. |
xMarketing.header
| Key | Type | Default | Description |
|---|---|---|---|
header.logo.src | string | "" | Light-mode logo URL. Used by XMarkLayoutNavbar when no logo prop is passed. |
header.logo.srcDark | string | "" | Dark-mode logo URL. Falls back to src. |
header.logo.alt | string | "" | Logo alt text. |
header.nav.links | NavLink[] | [] | Top-level nav links { label, to?, target?, children? }. Used as fallback by XMarkLayoutNavbar. |
header.nav.buttons | NavButton[] | [] | Action buttons rendered on the right of the navbar. Each: { label, to, icon?, target?, variant?, square?, color? }. |
xMarketing.footer
| Key | Type | Default | Description |
|---|---|---|---|
footer.logo.src | string | "" | Footer logo URL. |
footer.logo.alt | string | "" | Footer logo alt text. |
footer.body | string | "" | Footer body/tagline copy. |
footer.bg.color | string | "" | Tailwind background color class for the footer. |
footer.bg.img.src | string | "" | Background image URL. |
footer.bg.img.alt | string | "" | Background image alt text. |
footer.socials | Social[] | [] | Social links { name, url, icon }. |
footer.columns | FooterColumn[] | [] | Link columns { headerLabel, links: [{ label, to, target? }] }. |
xMarketing.blog
| Key | Type | Default | Description |
|---|---|---|---|
blog.active | boolean | true | Enables/disables the blog pages. |
blog.title | string | "Blog" | Blog landing page title. |
blog.description | string | Default blog description | Blog landing page description. |
blog.meta.title | string | "Blog" | SEO title for /blog. |
blog.meta.description | string | Default blog description | SEO description for /blog. |
xMarketing.tracking
Read by <XMarkPrivacyCookieConsent /> and useConsentTracking(). Scripts only fire after the matching consent category is granted.
| Key | Type | Default | Description |
|---|---|---|---|
tracking.gtmId | string | — | Google Tag Manager container ID (e.g. "GTM-XXXXXXX"). Fires the analytics category. |
tracking.ga4Id | string | — | Google Analytics 4 measurement ID (e.g. "G-XXXXXXXX"). Skipped when gtmId is set (avoids double-counting). |
tracking.clarityId | string | — | Microsoft Clarity project ID. Skipped when gtmId is set. |
tracking.scripts | TrackingScript[] | [] | Arbitrary scripts (Meta Pixel, Hotjar, Segment, etc.). Each fires when its category is granted. |
tracking.autoInject | boolean | true | When false, no scripts are injected (state still tracked). |
TrackingScript:
| Field | Type | Description |
|---|---|---|
id | string | Stable ID — used to dedupe re-injection. Required. |
src | string | External script URL. |
inline | string | Inline script body. |
category | 'necessary' | 'analytics' | 'marketing' | Category gate. Default 'analytics'. |
attrs | Record<string, string> | Extra attributes applied to the injected <script> (e.g. { async: '' }). |
See PrivacyCookieConsent for the full pattern.
Nuxt UI Theme Overrides
The layer ships with overrides under app.config.ts → ui:
| Key | Value | Purpose |
|---|---|---|
ui.primary | "brand" | Primary color alias. |
ui.colors.primary | "brand" | Maps primary semantic color to the brand palette. |
ui.colors.secondary | "deep" | Maps secondary semantic color to deep palette. |
ui.colors.neutral | "zinc" | Neutral palette. |
ui.button.slots.base | "font-medium tracking-wide" | Base slot on all UButton. |
ui.button.variants.size.lg | "px-8 py-4 text-base" | Larger lg size. |
ui.button.variants.size.xl | "px-10 py-5 text-lg" | Extra-large size. |
ui.card.slots.root | "overflow-hidden" | Card root overflow. |
ui.card.slots.body | "p-0" | Removes default card body padding. |
Define your brand and deep palettes in your own app.config.ts (via @nuxt/ui theme extension) or override per-app.
Runtime Config (Environment Variables)
No environment variables are required. The layer's runtimeConfig.public is empty — all configuration lives in app/app.config.ts under the xMarketing namespace.
Blog posts come from Nuxt Content, not an API: install the @nuxt/content + better-sqlite3 peers, declare the blog collection in your own content.config.ts so it binds to your content dir (Nuxt Content v3 resolves a collection's source against the layer whose content.config.ts defines it — the layer's shipped collection never sees your content/blog/*.md; snippet on the index page), and write markdown under content/blog/.
NUXT_PUBLIC_API_URL and NUXT_PUBLIC_BUILDERIO_KEY are no longer read. The Builder.io-backed blog pages and the old useXBlog().get() stub were replaced by Nuxt Content queries (useXBlog().getPosts() / getPostByPath() / getSurround()). Migrate posts to content/blog/*.md.AI Context
package: "@xenterprises/nuxt-x-marketing"
config-key: xMarketing
use-when: >
Customising the site name, header/footer logo, nav links, socials, footer
columns, blog metadata, consent-aware tracking (GTM/GA4/Clarity/arbitrary
scripts), Marker.io feedback widget, or email-marketing organization in the
nuxt-x-marketing layer. No environment variables are required — blog posts
are markdown under content/blog/ via Nuxt Content (the consumer must
re-declare the blog collection in its own content.config.ts). The former
NUXT_PUBLIC_API_URL / NUXT_PUBLIC_BUILDERIO_KEY settings were removed in
2026-07.
useConsentTracking
Reads app.config.xMarketing.tracking and dynamically injects GTM / GA4 / Clarity / custom scripts only after the matching consent category is granted. Used by <XMarkPrivacyCookieConsent> and the consent-tracking.client.ts plugin.
nuxt-x-auth
Provider-agnostic authentication Nuxt layer — unified useXAuth composable, 10 pre-built UI components, global route middleware, and support for Stack Auth, Better Auth, Neon Auth, and Local JWT backends.
