@xenterprises/nuxt-x-marketing
| Install | |
|---|---|
npm install @xenterprises/nuxt-x-marketing |
|
| Latest Version: | 1.15.5 |
| Vue: | 3 |
| License: | Custom |
| Last Updated: | Oct 22, 2026 |
| Links: | npm |
@xenterprises/nuxt-x-marketing
A comprehensive Nuxt layer for building marketing websites with 38+ pre-built components. Features dark mode support, responsive design, accessibility, and seamless integration with Nuxt UI.
Features
- 38+ Marketing Components - Hero, Features, Pricing, Testimonials, Blog, Affiliate/Review, and more
- Consent-aware tracking - Drop GTM/GA4/Clarity IDs in
app.config, the cookie banner auto-fires them on accept - Zero Required Props - Every component works out of the box with sensible defaults
- Dark Mode Support - All components support light and dark themes
- Responsive Design - Mobile-first approach with tablet and desktop breakpoints
- Accessible - WCAG 2.0 AA compliant with proper ARIA attributes
- Customizable - Props-based configuration with slot overrides
- Nuxt UI v4 Integration - Built on top of Nuxt UI v4 components
- Animations - Scroll-triggered fade-in animations and parallax effects
- Two Footer Modes - Generic white-label (
XMarkLayoutFooter) and X Enterprises branded (XFooter)
Installation
npm install @xenterprises/nuxt-x-marketing
Add the layer to your nuxt.config.js:
export default defineNuxtConfig({
extends: "@xenterprises/nuxt-x-marketing",
});
Quick Start
What the consumer writes
The layer is batteries-included: it ships a default app shell (navbar + footer + cookie-consent banner) and default pages (/, /blog, /blog/[...slug]). You do not write an app.vue — configure the shell in app/app.config.ts under the xMarketing namespace (it must live in app/, not the project root):
// app/app.config.ts
export default defineAppConfig({
xMarketing: {
name: "Acme Inc",
url: "https://acme.com",
header: {
logo: { src: "/logo.svg", srcDark: "/logo-dark.svg", alt: "Acme" },
nav: {
links: [
{ label: "Pricing", to: "/#pricing" },
{ label: "Blog", to: "/blog" },
],
buttons: [{ label: "Get Started", to: "/signup", color: "primary" }],
},
},
footer: {
logo: { src: "/logo.svg", alt: "Acme" },
body: "Building the future of modern software.",
socials: [
{ name: "GitHub", url: "https://github.com/acme", icon: "i-lucide-github" },
],
columns: [
{
headerLabel: "Product",
links: [{ label: "Blog", to: "/blog" }],
},
],
},
blog: { active: true, title: "Blog" },
tracking: { gtmId: "GTM-XXXXXXX" }, // optional; fires only after consent
},
});
Blog posts are markdown in content/blog/*.md — re-declare the blog collection in your own content.config.ts so Nuxt Content binds it to your content dir (the layer's .playground/content.config.ts is the reference).
Opting out of the defaults
Every shipped default has a switch or a standard Nuxt override:
xMarketing.header.active: false— removes the default navbar from the shellxMarketing.footer.active: false— removes the default footerxMarketing.consent.active: false— removes the cookie-consent banner (tracking scripts then never fire)xMarketing.blog.active: false— the shipped/blogpages 404- Replace the whole shell by shipping your own
app/app.vue; replace any page by shipping the same path underapp/pages/(standard Nuxt layer overriding)
Example Landing Page
All components work with zero required props — just drop them in and customize as needed:
<template>
<div>
<!-- Hero — works with zero props, or fully customized -->
<XMarkHero
:img="{ src: 'https://images.unsplash.com/photo-1551434678-e076c223a692', alt: 'Hero' }"
eyebrow="Welcome to the future"
title="Build something amazing today"
subtitle="The modern platform for teams who want to ship faster."
align="left"
overlay="gradient"
:buttons="[
{ label: 'Get Started Free', color: 'primary' },
{ label: 'Watch Demo', variant: 'outline' }
]"
/>
<!-- Features — works with zero props, or pass your own -->
<XMarkSection id="features" bg="default" padding="xl">
<header class="text-center max-w-3xl mx-auto mb-16">
<h2 class="xText-headline">Everything you need to succeed</h2>
</header>
<XMarkFeatures :features="features" layout="grid" :columns="3" />
</XMarkSection>
<!-- Testimonials -->
<XMarkSection bg="subtle" padding="xl">
<XMarkTestimonials :testimonials="testimonials" layout="grid" />
</XMarkSection>
<!-- Pricing -->
<XMarkSection bg="default" padding="xl">
<XMarkPricingPlans :plans="pricingPlans" />
</XMarkSection>
</div>
</template>
<script setup>
const features = [
{ icon: 'i-lucide-zap', title: 'Lightning Fast', description: 'Built for speed.' },
{ icon: 'i-lucide-shield-check', title: 'Secure by Default', description: 'Enterprise-grade security.' },
{ icon: 'i-lucide-users', title: 'Team Collaboration', description: 'Real-time collaboration tools.' },
]
const testimonials = [
{ quote: 'This platform transformed how our team works.', name: 'Sarah Chen', title: 'CTO', company: 'TechStart', rating: 5 },
]
const pricingPlans = [
{ name: 'Starter', price: '$19', period: '/month', features: ['5 team members', 'Basic analytics'], button: { label: 'Start Free Trial' } },
{ name: 'Pro', price: '$49', period: '/month', features: ['25 team members', 'Advanced analytics'], button: { label: 'Start Free Trial' }, popular: true },
]
</script>
Components
Core Layout
XMarkLayoutNavbar
Fixed navigation header with transparent-to-solid scroll transition. Falls back to xMarketing.header (logo, nav links, nav buttons) when props are omitted.
<XMarkLayoutNavbar
:links="[{ label: 'Features', to: '/#features' }]"
:logo="{ src: '/logo.svg', srcDark: '/logo-dark.svg', alt: 'Company' }"
:buttons="[
{ label: 'Sign In', to: '/login', variant: 'ghost' },
{ label: 'Get Started', to: '/signup', color: 'primary' },
]"
:transparent="true"
:scroll-threshold="100"
/>
| Prop | Type | Default | Description |
|---|---|---|---|
links |
Array |
xMarketing.header.nav.links |
Navigation links { label, to } |
logo |
Object |
xMarketing.header.logo |
Logo { src, srcDark?, alt? } |
buttons |
Array |
xMarketing.header.nav.buttons |
Action buttons { label, to, color?, variant?, icon? } |
transparent |
Boolean |
true |
Start transparent over hero |
scrollThreshold |
Number |
100 |
Pixels before transition |
XMarkSection
Section wrapper with background variants and optional patterns.
<XMarkSection bg="subtle" padding="xl" pattern="dots">
<h2>Section Content</h2>
</XMarkSection>
| Prop | Type | Default | Description |
|---|---|---|---|
bg |
String |
'default' |
default, subtle, elevated, bold, transparent |
padding |
String |
'lg' |
none, sm, md, lg, xl |
container |
String |
'lg' |
sm, md, lg, xl, full, none |
pattern |
String |
'' |
dots, grid, diagonal, topography, circuit, waves |
patternOpacity |
Number |
0.05 |
Pattern opacity (0-1) |
bgImage |
String |
'' |
Background image URL |
parallax |
Boolean |
false |
Enable parallax on bg image |
XMarkLayoutFooter
Full footer with brand, link columns, social icons, and newsletter.
<XMarkLayoutFooter
:logo="{ src: '/logo.svg', alt: 'Company' }"
description="Building the future of modern software."
:social="[{ name: 'Twitter', href: 'https://twitter.com', icon: 'i-lucide-twitter' }]"
:columns="[{ title: 'Product', links: [{ label: 'Features', to: '/features' }] }]"
:legal-links="[{ label: 'Privacy', to: '/privacy' }]"
:has-newsletter="true"
@newsletter-submit="handleSubmit"
/>
| Prop | Type | Default | Description |
|---|---|---|---|
logo |
Object |
null |
Logo { src, alt? } |
description |
String |
'' |
Brand description |
social |
Array |
[] |
Social links { name, href, icon } |
columns |
Array |
[] |
Link columns { title, links: [{ label, to }] } |
legalLinks |
Array |
[] |
Legal links { label, to } |
copyright |
String |
auto | Copyright text |
hasNewsletter |
Boolean |
false |
Show newsletter section |
XMarkLayoutFooterLegal
Minimal footer with copyright and legal links only.
<XMarkLayoutFooterLegal
copyright="© 2026 Acme Inc. All rights reserved."
:links="[{ label: 'Privacy', to: '/privacy' }]"
/>
Hero & Landing
XMarkHero
Full-screen hero with image/video background and overlay.
<XMarkHero
image-src="https://example.com/hero.jpg"
video-src="https://example.com/hero.mp4"
eyebrow="Welcome"
title="Build something amazing"
subtitle="The modern platform for teams."
align="left"
vertical-align="center"
overlay="gradient"
:show-scroll-indicator="true"
>
<template #actions>
<UButton size="xl" color="white">Get Started</UButton>
</template>
</XMarkHero>
| Prop | Type | Default | Description |
|---|---|---|---|
imageSrc |
String |
'' |
Background image URL |
videoSrc |
String |
'' |
Background video URL |
eyebrow |
String |
'' |
Small text above title |
title |
String |
required | Main headline |
subtitle |
String |
'' |
Supporting text |
align |
String |
'left' |
left, center, right |
verticalAlign |
String |
'center' |
center, bottom |
overlay |
String |
'gradient' |
light, heavy, gradient, none |
showScrollIndicator |
Boolean |
true |
Show scroll arrow |
Content Sections
XMarkFeatures
Feature grid with icons, images, and optional links.
<XMarkFeatures
:features="[
{ icon: 'i-lucide-zap', title: 'Fast', description: 'Lightning fast performance.' },
{ icon: 'i-lucide-shield', title: 'Secure', description: 'Enterprise security.' },
]"
layout="grid"
:columns="3"
/>
| Prop | Type | Default | Description |
|---|---|---|---|
features |
Array |
required | Features { icon?, image?, title, description, link? } |
layout |
String |
'grid' |
grid, list, alternating |
columns |
Number |
3 |
Grid columns (2, 3, or 4) |
XMarkTestimonials
Testimonial cards in grid or carousel layout.
<XMarkTestimonials
:testimonials="[
{
quote: 'Amazing product!',
name: 'John Doe',
title: 'CEO',
company: 'Acme Inc',
avatar: 'https://example.com/avatar.jpg',
},
]"
layout="grid"
/>
XMarkPricing
Pricing cards with billing toggle and popular badge.
<XMarkPricing
:plans="[
{
name: 'Starter',
price: '$19',
period: 'month',
description: 'Perfect for small teams.',
features: ['5 team members', 'Basic analytics'],
cta: 'Start Free Trial',
},
{
name: 'Pro',
price: '$49',
period: 'month',
features: ['25 team members', 'Advanced analytics'],
cta: 'Start Free Trial',
popular: true,
},
]"
:show-billing-toggle="true"
:yearly-discount="20"
@select="handlePlanSelect"
/>
| Prop | Type | Default | Description |
|---|---|---|---|
plans |
Array |
required | Pricing plans |
highlighted |
String |
'' |
Plan name to highlight |
showBillingToggle |
Boolean |
false |
Show monthly/yearly toggle |
yearlyDiscount |
Number |
20 |
Yearly discount percentage |
XMarkComparison
Feature comparison table across plans.
<XMarkComparison
:plans="['Starter', 'Pro', 'Enterprise']"
:highlighted="'Pro'"
:feature-groups="[
{
name: 'Core Features',
features: [
{ name: 'Users', values: ['5', '25', 'Unlimited'] },
{ name: 'Storage', values: ['1GB', '10GB', 'Unlimited'] },
],
},
]"
/>
XMarkNewsletter
Email signup form with variants.
<XMarkNewsletter
title="Subscribe to our newsletter"
description="Get the latest updates."
:button="{ label: 'Subscribe' }"
placeholder="Enter your email"
variant="default"
@submit="handleSubmit"
/>
| Prop | Type | Default | Description |
|---|---|---|---|
title |
String |
'Subscribe...' |
Form title |
description |
String |
'' |
Form description |
button |
Object |
{ label: 'Subscribe' } |
Button config { label, color? } |
variant |
String |
'default' |
default, minimal, inline |
Blog Components
XMarkBlogCard
Blog post card with image, title, excerpt, and author.
<XMarkBlogCard
:post="{
title: 'Getting Started with Nuxt',
slug: 'getting-started',
excerpt: 'Learn how to build modern web apps.',
image: '/blog/cover.jpg',
date: '2024-01-15',
author: { name: 'John Doe', avatar: '/avatars/john.jpg' },
category: 'Tutorial',
}"
variant="default"
/>
XMarkBlogList
Blog listing grid with optional featured post.
<XMarkBlogList
:posts="posts"
:columns="3"
:show-featured="true"
/>
XMarkBlogDetail
Full blog post view with author, share buttons, and navigation.
<XMarkBlogDetail
:post="post"
:author="author"
:related-posts="relatedPosts"
/>
XMarkBlogSidebar
Blog sidebar with search, categories, tags, and recent posts.
<XMarkBlogSidebar
:categories="['Tutorials', 'News', 'Updates']"
:tags="['vue', 'nuxt', 'javascript']"
:recent-posts="recentPosts"
:show-search="true"
@search="handleSearch"
@category-click="handleCategoryClick"
/>
XMarkBlogAuthor
Author bio with social links.
<XMarkBlogAuthor
:author="{
name: 'John Doe',
title: 'Senior Developer',
avatar: '/avatars/john.jpg',
bio: 'Passionate about building great software.',
social: { twitter: 'https://twitter.com/johndoe' },
}"
variant="full"
/>
| Prop | Type | Default | Description |
|---|---|---|---|
author |
Object |
required | Author data |
variant |
String |
'inline' |
inline, sm, full, card |
XMarkBlogNavigation
Previous/next post navigation.
<XMarkBlogNavigation
:previous="{ title: 'Previous Post', slug: 'prev-post' }"
:next="{ title: 'Next Post', slug: 'next-post' }"
base-path="/blog"
/>
XMarkBlogCTA
In-article newsletter signup.
<XMarkBlogCTA
title="Enjoyed this article?"
description="Subscribe for more content."
variant="featured"
@submit="handleSubmit"
/>
UI Elements
XMarkBadge
Trust and feature badges with presets.
<XMarkBadge preset="no-credit-card" variant="subtle" />
<XMarkBadge preset="cancel-anytime" />
<XMarkBadge icon="i-lucide-star" label="5-star rated" />
| Prop | Type | Default | Description |
|---|---|---|---|
preset |
String |
'' |
no-credit-card, cancel-anytime, money-back, free-trial, secure |
icon |
String |
'' |
Custom icon (if no preset) |
label |
String |
'' |
Custom label (if no preset) |
variant |
String |
'default' |
default, subtle, outline |
XMarkGlassCard
Glassmorphism card with blur effect.
<XMarkGlassCard :blur="10" :opacity="0.1">
<h3>Card Content</h3>
</XMarkGlassCard>
XMarkPromoCard
Promotional card with image and CTA.
<XMarkPromoCard
title="Special Offer"
description="Get 50% off your first month."
image="/promo.jpg"
cta-text="Claim Offer"
cta-link="/pricing"
/>
XMarkGlowDivider
Glowing section divider.
<XMarkGlowDivider color="primary" :intensity="0.5" />
XMarkPatternBg
SVG background patterns.
<XMarkPatternBg pattern="dots" :opacity="0.05" />
| Prop | Type | Default | Description |
|---|---|---|---|
pattern |
String |
'dots' |
dots, grid, diagonal, topography, circuit, waves |
opacity |
Number |
0.05 |
Pattern opacity |
XMarkSectionStitch
Section divider shapes.
<XMarkSectionStitch shape="wave" position="top" :flip="false" />
| Prop | Type | Default | Description |
|---|---|---|---|
shape |
String |
'wave' |
angle, wave, curve, triangle, zigzag |
position |
String |
'bottom' |
top, bottom |
flip |
Boolean |
false |
Flip horizontally |
Modals & Overlays
XMarkVideoModal
Video lightbox supporting YouTube, Vimeo, and direct URLs.
<XMarkVideoModal
v-model="showVideo"
url="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
title="Product Demo"
/>
XMarkImageLightbox
Image gallery lightbox with keyboard navigation.
<XMarkImageLightbox
v-model="showLightbox"
:images="[
{ src: '/gallery/1.jpg', alt: 'Image 1', caption: 'First image' },
{ src: '/gallery/2.jpg', alt: 'Image 2' },
]"
:start-index="0"
/>
XMarkFeatureModal
Feature detail modal.
<XMarkFeatureModal
v-model="showFeature"
:feature="{
icon: 'i-lucide-zap',
title: 'Lightning Fast',
description: 'Detailed description...',
image: '/features/speed.jpg',
}"
/>
Notifications & Banners
XMarkAnnouncementBar
Dismissible top announcement banner.
<XMarkAnnouncementBar
message="New feature available!"
link-text="Learn more"
link-url="/features"
variant="primary"
:dismissible="true"
@dismiss="handleDismiss"
/>
| Prop | Type | Default | Description |
|---|---|---|---|
message |
String |
required | Announcement text |
linkText |
String |
'' |
Optional link text |
linkUrl |
String |
'' |
Optional link URL |
variant |
String |
'primary' |
primary, neutral, success, warning, error |
dismissible |
Boolean |
true |
Show dismiss button |
XMarkCookieBanner
Cookie consent banner.
<XMarkCookieBanner
message="We use cookies to improve your experience."
accept-text="Accept All"
decline-text="Decline"
:show-preferences="true"
@accept="handleAccept"
@decline="handleDecline"
@preferences="handlePreferences"
/>
XMarkCookieToast
Cookie toast notification.
<XMarkCookieToast
message="We use cookies"
@accept="handleAccept"
/>
XMarkPrivacyCookieConsent
Consent-aware cookie banner + preferences modal that auto-fires tracking scripts. Drop your GTM/GA4/Clarity IDs into app.config.ts, drop <XMarkPrivacyCookieConsent /> into your layout, and the component handles banner display, consent storage, and dynamic script injection.
<!-- app.vue -->
<template>
<div>
<NuxtPage />
<XMarkPrivacyCookieConsent
policy-url="/cookies"
privacy-url="/privacy"
/>
</div>
</template>
// app.config.ts
export default defineAppConfig({
xMarketing: {
tracking: {
gtmId: 'GTM-XXXXXXX',
ga4Id: 'G-XXXXXXXX',
clarityId: 'abc123def4',
// Optional escape hatch for anything else (Meta Pixel, Hotjar, etc.)
scripts: [
{
id: 'meta-pixel',
src: 'https://connect.facebook.net/en_US/fbevents.js',
category: 'marketing',
attrs: { async: '' },
},
],
autoInject: true, // default
},
},
})
Scripts only fire after the visitor grants consent for the matching category (analytics or marketing). On revisit, the client plugin auto-loads stored scripts immediately — no flash of banner.
| Prop | Type | Default | Description |
|---|---|---|---|
title |
String |
'We use cookies' |
Banner heading |
message |
String |
(see source) | Banner body text |
acceptLabel |
String |
'Accept all' |
Accept button text |
rejectLabel |
String |
'Reject all' |
Reject button text |
saveLabel |
String |
'Save preferences' |
Save button text (modal) |
policyLabel |
String |
'Read our policy' |
Policy link text |
policyUrl |
String |
— | Cookie policy URL |
privacyUrl |
String |
— | Privacy policy URL |
prefsTitle |
String |
'Cookie preferences' |
Modal title |
prefsDescription |
String |
(see source) | Modal description |
showCustomize |
Boolean |
true |
Show the Customize button |
categories |
Category[] |
(4 standard) | Categories shown in the modal |
storageKey |
String |
'xMarketing.consent' |
localStorage key |
forceShow |
Boolean |
false |
Force the banner open (e.g. from a "Manage cookies" link) |
| Emit | Payload | When |
|---|---|---|
@accept |
Record<CategoryId, boolean> |
Visitor accepted all |
@reject |
Record<CategoryId, boolean> |
Visitor rejected all |
@save |
Record<CategoryId, boolean> |
Visitor saved preferences |
Underlying composable — useConsentTracking() is auto-imported. Use it directly if you need to programmatically grant consent or read state:
const consent = useConsentTracking()
consent.acceptAll() // grant every category
consent.rejectAll() // grant only necessary
consent.hasConsent('analytics')
consent.state.value // reactive { necessary, analytics, marketing, preferences }
XMarkGDPR
GDPR cookie preference modal.
<XMarkGDPR
v-model="showGDPR"
:categories="[
{ id: 'necessary', name: 'Necessary', description: 'Required for the site to work.', required: true },
{ id: 'analytics', name: 'Analytics', description: 'Help us improve.', default: false },
]"
@save="handleSavePreferences"
/>
XMarkSocialProofToast
Social proof notification toasts.
<XMarkSocialProofToast
:notifications="[
{ name: 'John', location: 'New York', action: 'signed up', time: '2 minutes ago' },
]"
:interval="5000"
position="bottom-left"
/>
Utilities
XMarkBackToTop
Scroll to top button.
<XMarkBackToTop :show-after="300" :smooth="true" />
XMarkPopupChat
Chat widget trigger.
<XMarkPopupChat
provider="intercom"
:config="{ app_id: 'your-app-id' }"
/>
Affiliate & Review Components
Removed in favour of @xenterprises/nuxt-x-affiliate.
XMarkAffiliateDisclosure, XMarkAffiliateProductCard, XMarkAffiliateProductGrid,
XMarkAffiliateProductDetail, and XMarkAffiliateComparisonTable duplicated components
the affiliate layer already ships — without its per-merchant tagging
(xAffiliateContent.merchants), impression tracking, or Product/Offer structured data.
Use <XAFDisclosure>, <XAFProductCard>, <XAFRelatedProducts>, <XAFBuyButton>,
and <XAFComparisonTable> instead.
Configuration
Configure the layer in your app.config.js:
export default defineAppConfig({
xMarketing: {
name: "X Enterprises",
config: {
markerProjectId: "your-marker-project-id", // Optional: Marker.io integration
},
},
});
Testing
Unit Tests
Run unit tests with Vitest:
npm run test:unit
E2E Tests
Run end-to-end tests with Playwright:
npm run test:e2e
Composables
| Composable | Description |
|---|---|
useScrollReveal(options?) |
Intersection Observer scroll animations. Auto-adds is-visible class to [data-reveal], .xFadeUp, .xFadeIn, .xFadeLeft, .xFadeRight, .xScale, .xFadeUp-stagger elements. |
useStaggerReveal(selector, delay?) |
Adds incremental transition-delay to [data-reveal] children inside a container. |
useParallax(options?) |
Parallax scroll effect for .xParallax[data-parallax-speed] elements. Uses requestAnimationFrame for performance. |
useElementParallax(speed?) |
Individual element parallax via template ref. Returns { elementRef }. |
useXBlog() |
Nuxt Content blog helpers (getPosts, getPostByPath, getSurround, normalizeBlogPost). Expects a blog collection and markdown under content/blog/. |
All composables are SSR-safe — they guard lifecycle hooks with getCurrentInstance() and import.meta.client checks.
Environment Variables
| Name | Required | Description |
|---|---|---|
| Marker.io Project ID | No | Set via appConfig.xMarketing.config.markerProjectId (not env var) |
| Newsletter Org ID | No | Set via appConfig.xMarketing.config.emailMarketingNewsletters.organizationId |
The layer itself has no required environment variables. Blog content is file-based via Nuxt Content (not Builder.io). All site config is done via app.config.ts.
CSS Classes
Typography
| Class | Description |
|---|---|
xText-display |
Display heading — clamp(3rem, 8vw, 6rem), weight 700, tight tracking |
xText-headline |
Section headline — clamp(2rem, 5vw, 3.5rem), weight 600 |
xText-title |
Card/feature title — clamp(1.25rem, 3vw, 1.75rem), weight 600 |
xText-body |
Body text — 1.125rem, line-height 1.7 |
xText-small |
Captions/labels — 0.875rem |
xText-eyebrow |
Uppercase label — 0.75rem, 0.1em tracking |
xText-balance |
Applies text-wrap: balance |
xText-gradient |
Gradient text using primary color |
Scroll Animations
| Class | Description |
|---|---|
xFadeUp |
Fade in + slide up (24px) on scroll |
xFadeIn |
Simple fade in on scroll |
xFadeLeft |
Fade in from left (-24px) on scroll |
xFadeRight |
Fade in from right (24px) on scroll |
xScale |
Scale in (0.95 → 1) on scroll |
xFadeUp-stagger |
Stagger children with 100ms delay increments (up to 6 children) |
[data-reveal] |
Legacy fade up (40px) on scroll |
Hover Effects
| Class | Description |
|---|---|
xHover-lift |
Lift up 4px + shadow on hover |
xHover-grow |
Scale to 1.02 on hover |
xHover-glow |
Primary color glow shadow on hover |
xHover-glow-neutral |
Neutral glow shadow on hover |
xHover-glow-subtle |
Subtle glow shadow on hover |
xHover-zoom |
Zoom child <img> to 1.08 on hover |
Glass & Glow
| Class | Description |
|---|---|
xGlass |
Glassmorphism — 20px blur, white/70 bg, border, shadow |
xGlass-subtle |
Light glassmorphism — 8px blur |
xGlass-heavy |
Heavy glassmorphism — 40px blur |
xGlow-divider |
Glowing horizontal divider line |
xGlow-border |
Glowing gradient border |
xGlow-text |
Text glow shadow |
Overlays
| Class | Description |
|---|---|
xOverlay-light |
30% black overlay |
xOverlay-heavy |
60% black overlay |
xOverlay-gradient |
Bottom-to-top gradient overlay |
xOverlay-vignette |
Radial vignette overlay |
Parallax
| Class | Description |
|---|---|
xParallax |
JS-driven parallax (use with data-parallax-speed="0.3") |
xParallax-bg |
CSS-only parallax (background-attachment: fixed) |
All animations respect prefers-reduced-motion: reduce.
How It Works
The layer provides a complete marketing website toolkit built on Nuxt UI v4:
-
Component Registration: All components in
app/components/X/Mark/are auto-imported by Nuxt with theXMarkprefix (e.g.,X/Mark/Hero/index.vue→<XMarkHero>). Branded X Enterprises components live underX/X/with theXXprefix. -
Design System:
app/assets/css/x-marketing.cssdefines CSS custom properties for typography scale, spacing, colors, shadows, and motion. It uses Tailwind CSS v4 with@theme staticfor custom color palettes ("brand" and "deep"). Dark mode overrides use.darkselector. -
Animations: A client-side plugin (
marketing.client.ts) auto-initializesuseScrollReveal()anduseParallax()globally on mount. Components that need scroll animations can also calluseScrollReveal()directly. -
Configuration:
app.config.tsprovides thexMarketingnamespace with header/footer/blog configuration and Nuxt UI theme overrides. Consumer apps merge their ownapp.config.tsto customize. -
Type System:
app/types/marketing.d.tsexports interfaces for all data structures (BlogPost, Feature, PricingPlan, Testimonial, etc.) used across components.
Layer Architecture
| Path | Purpose |
|---|---|
nuxt.config.ts |
Registers @nuxt/ui + @nuxt/content, loads CSS, enables SSR |
content.config.ts |
Default Nuxt Content blog collection schema |
app/app.config.ts |
Default xMarketing config + Nuxt UI theme overrides + type augmentation |
app/app.vue |
Default app shell with navbar, newsletter, footer (override in consumer app) |
app/assets/css/x-marketing.css |
Full design system: colors, typography, animations, effects |
app/components/X/Mark/ |
Generic marketing components (auto-imported as XMark*) |
app/components/X/X/ |
X Enterprises branded components (auto-imported as XX*) |
app/components/X/Footer/ |
Legacy footer components |
app/components/X/Header/ |
Legacy header components |
app/composables/ |
Composables: useScrollReveal, useParallax, useXBlog |
app/plugins/marketing.client.ts |
Client plugin: auto-initializes scroll/parallax globally |
app/types/marketing.d.ts |
TypeScript interfaces for all data structures |
app/pages/blog/ |
Default blog index + slug detail (Nuxt Content, not Builder.io) |
Blog (Nuxt Content)
Breaking (Builder.io removed): default /blog pages no longer call the Builder CDN.
Posts come from markdown in the consumer app.
- Peer-install
@nuxt/contentandbetter-sqlite3(already required by Content v3). - Ensure the layer is extended so
content.config.tsdefines theblogcollection (or copy/adapt it). - Add posts under
content/blog/*.md:
---
title: Getting Started
description: First post on the marketing site.
date: 2025-01-15
author: Tim
image: /blog/cover.jpg
category: Tutorial
tags: [nuxt, marketing]
published: true
readingTime: 5
---
## Hello
Markdown body rendered via `ContentRenderer`.
useXBlog().getPosts()/getPostByPath()feedXMarkBlogListandXMarkBlogDetail.
Overriding in Consumer Apps
- nuxt.config.ts: Consumer config merges with layer config. Add modules, runtime config, etc.
- app.config.ts: Deep-merges with layer defaults. Set
xMarketing.header,xMarketing.footer, etc. - app.vue: Override entirely by creating your own
app.vuein the consumer app. - Pages: Consumer pages take precedence. Override
/blogby creatingpages/blog/index.vue. - Content: Own the markdown under
content/blog/; do not put secrets in frontmatter.
License
UNLICENSED - Proprietary to X Enterprises.
Related Packages
A comprehensive Nuxt layer providing production-ready admin dashboard components...
A premium card component library for Nuxt 4 with cinematic image filters, warm s...
Version History
| Version | Released | License |
|---|---|---|
| 1.15.5 | Custom | |
| 1.15.4 | Custom | |
| 1.15.3 | Custom | |
| 1.15.2 | Custom | |
| 1.15.1 | Custom | |
| 1.15.0 | Custom | |
| 1.14.0 | Custom | |
| 1.13.0 | Custom | |
| 1.12.0 | Custom | |
| 1.11.0 | Custom | |
| 1.10.0 | Custom | |
| 1.9.0 | Custom | |
| 1.8.0 | Custom | |
| 1.7.0 | Custom | |
| 1.6.0 | Custom | |
| 1.5.2 | Custom | |
| 1.5.1 | Custom | |
| 1.5.0 | Custom | |
| 1.4.15 | Custom | |
| 1.4.14 | Custom | |
| 1.4.13 | Custom | |
| 1.4.12 | Custom | |
| 1.4.11 | Custom | |
| 1.4.10 | Custom | |
| 1.4.9 | Custom | |
| 1.4.8 | Custom | |
| 1.4.7 | Custom | |
| 1.4.6 | Custom | |
| 1.4.5 | Custom | |
| 1.4.4 | Custom |
Showing the latest 30 of 67. See every release on npm