X Enterprises
nuxt-x-marketing

Blog

A complete blog component suite — post cards, filterable list grid, full-article detail layout, author bio, post navigation, sidebar, and in-blog newsletter CTA.

Blog

The blog component suite covers every layer of a content-driven site: listing, discovery, reading, and conversion. Components are designed to compose — XMarkBlogList renders XMarkBlogCard internally; XMarkBlogDetail embeds XMarkBlogAuthor, XMarkBlogNavigation, and a sidebar slot that defaults to XMarkNewsletterForm.

Components

<XMarkBlogCard />

A single post preview. Links to /blog/[slug] automatically. Shows cover image, category badge, formatted date, reading time, excerpt, and author avatar.

<XMarkBlogCard
  :post="{
    title: 'Getting Started with Nuxt 4',
    slug: 'getting-started-nuxt-4',
    description: 'A practical walkthrough of the new Nuxt 4 directory structure.',
    date: '2025-03-01',
    readingTime: 5,
    category: 'Tutorials',
    img: { src: '/blog/nuxt4.jpg' },
    author: { name: 'Jane Doe', avatar: '/avatars/jane.jpg' },
  }"
  :has-category="true"
  :has-author="true"
  :has-excerpt="true"
  :button="{ label: 'Read More' }"
/>

Props

PropTypeDefaultDescription
postObjectExample postPost object { title, slug, img?, description?, date?, readingTime?, category?, author?, tags? }
hasCategoryBooleantrueShow category badge
hasAuthorBooleantrueShow author avatar and name
hasExcerptBooleantrueShow post description
buttonObjectnullFull-width CTA button { label, color?, variant?, icon? }

<XMarkBlogList />

A paginated grid of post cards with optional search input and category dropdown filter.

<XMarkBlogList
  :posts="allPosts"
  :columns="3"
  :per-page="9"
  :has-filters="true"
  :has-categories="true"
  :has-authors="true"
  :categories="['Tutorials', 'News', 'Case Studies']"
  :card-button="{ label: 'Read More' }"
/>

Props

PropTypeDefaultDescription
postsArray[]Array of post objects
columnsNumber3Grid columns: 1, 2, 3
perPageNumber9Posts per page
hasFiltersBooleanfalseShow search and category filter bar
hasCategoriesBooleantrueShow category badges on cards
hasAuthorsBooleantrueShow author info on cards
categoriesArray[]Available categories for filter dropdown
cardButtonObjectnullButton config passed to every card

<XMarkBlogDetail />

Full article reading layout. Place your prose content in the default slot. Automatically renders a sticky sidebar on desktop with a table of contents and a newsletter CTA (overridable via the sidebar slot).

<XMarkBlogDetail
  :post="post"
  :previous-post="previousPost"
  :next-post="nextPost"
  :toc="[
    { id: 'intro', text: 'Introduction', depth: 2 },
    { id: 'setup', text: 'Setup', depth: 2 },
    { id: 'config', text: 'Configuration', depth: 3 },
  ]"
>
  <!-- Rendered prose content -->
  <ContentRenderer :value="post" />

  <template #sidebar>
    <XMarkNewsletterForm variant="compact" title="Weekly digest" />
  </template>
</XMarkBlogDetail>

Props

PropTypeDefaultDescription
postObjectExample postFull post object including title, description, date, readingTime, category, author, img, tags
previousPostObjectnullPrevious post { title, slug }
nextPostObjectnullNext post { title, slug }
tocArray[]Table of contents [{ id, text, depth }]

Slots

SlotDescription
defaultThe article prose content
sidebarOverride the sticky sidebar content

<XMarkBlogAuthor />

Renders author information in three sizes: inline / sm for attribution lines, full for a boxed bio at the end of an article, and card for centered profile cards.

<XMarkBlogAuthor
  :author="{
    name: 'Jane Doe',
    title: 'Senior Engineer',
    bio: 'Jane writes about web performance and developer experience.',
    avatar: '/avatars/jane.jpg',
    social: { twitter: 'https://twitter.com/jane', github: 'https://github.com/jane' },
  }"
  variant="full"
/>

Props

PropTypeDefaultDescription
authorObjectRequiredAuthor object { name, title?, bio?, avatar?, social?: { [platform]: url } }
variantString'inline'Display variant: 'inline', 'sm', 'full', 'card'

<XMarkBlogNavigation />

A two-column previous/next navigation bar with post titles. Supports Nuxt Content _path or standard slug routing.

<XMarkBlogNavigation
  :previous="{ title: 'Deploying to Vercel', slug: 'deploying-to-vercel' }"
  :next="{ title: 'Edge Functions Deep Dive', slug: 'edge-functions' }"
  base-path="/blog"
  previous-label="Previous Article"
  next-label="Next Article"
/>

Props

PropTypeDefaultDescription
previousObjectnullPrevious post { title, slug } or { title, _path }
nextObjectnullNext post { title, slug } or { title, _path }
basePathString'/blog'Base URL path for slug-based routing
previousLabelString'Previous'Label above previous post title
nextLabelString'Next'Label above next post title

<XMarkBlogSidebar />

Sticky blog sidebar. Renders a search input, category links (with active highlighting), tag cloud, recent posts, and a newsletter CTA. Emit search to handle the search query in the parent.

<XMarkBlogSidebar
  :has-search="true"
  :categories="[
    { name: 'Tutorials', slug: 'tutorials', count: 12 },
    { name: 'News', slug: 'news', count: 5 },
  ]"
  :tags="[
    { name: 'Vue', slug: 'vue' },
    { name: 'Nuxt', slug: 'nuxt' },
  ]"
  :recent-posts="recentPosts"
  category-base-path="/blog/category"
  tag-base-path="/blog/tag"
  :has-cta="true"
  @search="handleSearch"
/>

Props

PropTypeDefaultDescription
hasSearchBooleantrueShow search input
categoriesArray[]Category list [{ name, slug, count }]
tagsArray[]Tag list [{ name, slug }]
recentPostsArray[]Recent posts [{ title, slug, img?, date? }]
categoryBasePathString'/blog/category'URL prefix for category links
tagBasePathString'/blog/tag'URL prefix for tag links
hasCtaBooleantrueShow newsletter CTA at bottom

Slots

SlotDescription
ctaOverride the newsletter CTA section

<XMarkBlogCTANewsletter />

An inline newsletter signup widget designed to sit inside blog posts or the sidebar. Supports four size/layout variants.

<XMarkBlogCTANewsletter
  title="Never miss a post"
  description="Get the latest articles delivered to your inbox every week."
  :button="{ label: 'Subscribe', color: 'primary' }"
  placeholder="your@email.com"
  variant="compact"
  :has-privacy="true"
  privacy-text="No spam. Unsubscribe anytime."
/>

Props

PropTypeDefaultDescription
titleString'Subscribe to our newsletter'Widget heading
descriptionString'Get the latest posts delivered right to your inbox.'Supporting text
buttonObject{ label: 'Subscribe' }Button config { label, color? }
placeholderString'Enter your email'Input placeholder
variantString'default'Layout variant: 'default', 'featured', 'inline', 'compact'
iconString'i-lucide-mail'Icon shown in featured variant
hasPrivacyBooleantrueShow privacy note
privacyTextString'No spam. Unsubscribe anytime.'Privacy note text

AI Context

category: Blog
package: "@xenterprises/nuxt-x-marketing"
components:
  - XMarkBlogCard
  - XMarkBlogList
  - XMarkBlogDetail
  - XMarkBlogAuthor
  - XMarkBlogNavigation
  - XMarkBlogSidebar
  - XMarkBlogCTANewsletter
use-when: >
  Building a content marketing blog. Use XMarkBlogList on the index page,
  XMarkBlogDetail on individual post pages, and XMarkBlogSidebar alongside
  both for navigation and discovery.
typical-page-section: >
  XMarkBlogList: /blog index. XMarkBlogDetail: /blog/[slug].
  XMarkBlogSidebar: right column of list and detail pages.
  XMarkBlogCTANewsletter: within post content or sidebar.
Copyright © 2026