mdxui

BlogSite Specialization

Blog site type with posts, authors, categories, and RSS feeds

BlogSite Specialization

The BlogSite type is optimized for content publishing, articles, and blog posts. It extends the base Site component with specialized components for post listings, author profiles, categories, tags, and RSS feed generation.

Naming Convention

BlogSite follows the ${SiteType}${Component} pattern:

BlogHeader = Header + blog navigation
BlogGrid = Grid + post listing
BlogPost = Post + article layout
BlogSidebar = Sidebar + categories, tags, recent posts
AuthorBio = Bio + author information
RelatedPosts = Posts + recommendation engine

All blog components are the base component enhanced with blog site-specific capabilities.

Type Definition

import type { BlogSite } from 'mdxui'

interface BlogSite extends BaseSite {
  type: 'blog'
  blog?: {
    postsPerPage?: number     // Posts per page (default: 10)
    categories?: boolean      // Enable categories (default: true)
    tags?: boolean           // Enable tags (default: true)
    authors?: boolean        // Enable author pages (default: true)
    rss?: boolean           // Generate RSS feed (default: true)
  }
}

Usage

Basic Example

import { Site, BlogGrid, BlogPost, BlogSidebar } from '@mdxui/beacon'

<Site
  type="blog"
  name="Acme Blog"
  blog={{
    postsPerPage: 10,
    categories: true,
    tags: true,
    rss: true
  }}
>
  <BlogGrid posts={posts} />
</Site>

With Author Pages

<Site
  type="blog"
  name="Tech Insights"
  blog={{
    authors: true,
    categories: true,
    rss: true
  }}
>
  <BlogGrid posts={posts} />
  <AuthorPage author={currentAuthor} />
</Site>

Required Components

BlogSite requires these specialized components:

BlogHeader

Required: Yes

Blog header with navigation and search.

<BlogHeader
  logo={<Logo />}
  navigation={[
    { label: "Home", href: "/" },
    { label: "Blog", href: "/blog" },
    { label: "About", href: "/about" }
  ]}
  search={true}
  rss={true}
/>

BlogGrid

Required: Yes

Grid or list of blog posts.

<BlogGrid
  posts={[
    {
      title: "Getting Started with React",
      excerpt: "Learn the basics of React in this comprehensive guide",
      author: "Jane Doe",
      date: "2024-01-15",
      slug: "getting-started-react",
      image: "/posts/react-intro.jpg",
      categories: ["React", "Tutorial"],
      tags: ["beginner", "javascript"]
    }
  ]}
  layout="grid"  // or "list"
  postsPerPage={10}
/>

BlogPost

Required: Yes

Individual blog post layout.

<BlogPost
  title="Getting Started with React"
  excerpt="Learn the basics of React in this comprehensive guide"
  author={{
    name: "Jane Doe",
    avatar: "/avatars/jane.jpg",
    bio: "Frontend developer and React enthusiast"
  }}
  date="2024-01-15"
  readingTime="5 min read"
  image="/posts/react-intro.jpg"
  categories={["React", "Tutorial"]}
  tags={["beginner", "javascript"]}
>
  {/* Post content */}
</BlogPost>

Optional Components

BlogSidebar

Sidebar with categories, tags, and recent posts.

<BlogSidebar
  categories={[
    { name: "React", count: 25, href: "/blog/category/react" },
    { name: "TypeScript", count: 18, href: "/blog/category/typescript" }
  ]}
  tags={[
    { name: "tutorial", count: 42 },
    { name: "beginner", count: 30 }
  ]}
  recentPosts={[
    { title: "Latest Post", href: "/blog/latest-post", date: "2024-01-20" }
  ]}
/>

AuthorBio

Author biography section at end of post.

<AuthorBio
  name="Jane Doe"
  avatar="/avatars/jane.jpg"
  bio="Frontend developer and React enthusiast. Writing about web development and best practices."
  social={{
    twitter: "https://twitter.com/janedoe",
    github: "https://github.com/janedoe",
    linkedin: "https://linkedin.com/in/janedoe"
  }}
  postsCount={42}
/>

Related posts recommendation.

<RelatedPosts
  posts={[
    {
      title: "Advanced React Patterns",
      slug: "advanced-react-patterns",
      image: "/posts/advanced-react.jpg"
    },
    {
      title: "React Hooks Explained",
      slug: "react-hooks-explained",
      image: "/posts/hooks.jpg"
    }
  ]}
  algorithm="tags"  // or "categories", "author"
  limit={3}
/>

Newsletter

Newsletter signup form.

<Newsletter
  title="Subscribe to our newsletter"
  description="Get the latest posts delivered to your inbox"
  placeholder="Enter your email"
  buttonText="Subscribe"
  provider="mailchimp"  // or "convertkit", "substack"
/>

Comments

Comments section.

<Comments
  provider="disqus"  // or "utterances", "giscus"
  identifier={post.slug}
/>

Component Specializations

BlogHeader

Base Header component + blog features.

// Enhanced with:
- Blog-specific navigation
- Search across posts
- RSS feed link
- Category dropdown
- Mobile-responsive menu

BlogGrid

Post listing with filtering and pagination.

// Enhanced with:
- Grid or list layout
- Category filtering
- Tag filtering
- Search filtering
- Pagination
- Load more
- Featured posts

BlogPost

Article layout with reading experience.

// Enhanced with:
- Reading time estimate
- Progress indicator
- Social sharing buttons
- Author bio
- Related posts
- Table of contents
- Code syntax highlighting

BlogSidebar

Sidebar with blog navigation.

// Enhanced with:
- Category list with counts
- Tag cloud
- Recent posts
- Popular posts
- Archive by date
- Newsletter signup

Post Metadata

Frontmatter Schema

---
title: Getting Started with React
excerpt: Learn the basics of React in this comprehensive guide
author: jane-doe
date: 2024-01-15
updated: 2024-01-20
image: /posts/react-intro.jpg
categories:
  - React
  - Tutorial
tags:
  - beginner
  - javascript
featured: true
---

# Getting Started with React

Your post content here...

Type Definition

interface PostFrontmatter {
  title: string
  excerpt: string
  author: string
  date: string
  updated?: string
  image?: string
  categories?: string[]
  tags?: string[]
  featured?: boolean
  draft?: boolean
}

Categories and Tags

Category Pages

<CategoryPage
  category="React"
  posts={postsInCategory}
  description="All posts about React"
/>

Tag Pages

<TagPage
  tag="tutorial"
  posts={postsWithTag}
  relatedTags={["beginner", "guide", "howto"]}
/>

Category Navigation

<CategoryNav
  categories={[
    { name: "React", slug: "react", count: 25 },
    { name: "TypeScript", slug: "typescript", count: 18 },
    { name: "CSS", slug: "css", count: 12 }
  ]}
  current="react"
/>

RSS Feed

Auto-Generated RSS

<Site
  type="blog"
  blog={{
    rss: true  // Automatically generates RSS feed
  }}
>
  {/* Feed available at /rss.xml */}
</Site>

Custom RSS Configuration

<Site
  type="blog"
  blog={{
    rss: {
      enabled: true,
      path: "/feed.xml",
      limit: 20,
      fullContent: false  // Include full post or just excerpt
    }
  }}
>
<BlogHeader
  rss={true}
  rssUrl="/rss.xml"
/>

Author Pages

Author Profile

<AuthorPage
  author={{
    name: "Jane Doe",
    slug: "jane-doe",
    avatar: "/avatars/jane.jpg",
    bio: "Frontend developer and React enthusiast",
    role: "Senior Developer",
    social: {
      twitter: "https://twitter.com/janedoe",
      github: "https://github.com/janedoe"
    }
  }}
  posts={authorPosts}
  totalPosts={42}
/>

Multiple Authors

<BlogPost
  authors={[
    { name: "Jane Doe", slug: "jane-doe" },
    { name: "John Smith", slug: "john-smith" }
  ]}
>

Search and Filtering

Post Search

<BlogSearch
  placeholder="Search posts..."
  index={allPosts}
  fields={["title", "excerpt", "content", "tags"]}
  onSearch={(results) => {
    // Display search results
  }}
/>

Filter by Category

<CategoryFilter
  categories={categories}
  selected={["React", "TypeScript"]}
  onChange={(selected) => {
    // Filter posts
  }}
/>

Filter by Tag

<TagFilter
  tags={tags}
  selected={["tutorial", "beginner"]}
  onChange={(selected) => {
    // Filter posts
  }}
/>

Best Practices

Content Strategy

  • Publish consistently: Set a regular schedule
  • Quality over quantity: Focus on valuable content
  • Use categories wisely: 5-10 main categories max
  • Tag strategically: 3-5 tags per post
  • Write clear excerpts: Compelling 1-2 sentence summaries
  • Include images: Featured images for every post

SEO Optimization

  • Descriptive titles: Include keywords naturally
  • Meta descriptions: Use excerpts as descriptions
  • Internal linking: Link to related posts
  • Image alt text: Describe all images
  • URL structure: Use clean, readable slugs
  • RSS feeds: Enable for discoverability

Reading Experience

  • Clear typography: Readable font size and line height
  • Break up content: Use headings and paragraphs
  • Add visuals: Images, diagrams, code blocks
  • Include ToC: Table of contents for long posts
  • Estimate reading time: Help readers plan
  • Related content: Recommend similar posts

Real-World Example

Complete blog site:

import {
  Site,
  BlogHeader,
  BlogGrid,
  BlogPost,
  BlogSidebar,
  AuthorBio,
  RelatedPosts,
  Newsletter,
  Comments
} from '@mdxui/beacon'

<Site
  type="blog"
  name="Tech Insights"
  domain="techinsights.com"
  blog={{
    postsPerPage: 10,
    categories: true,
    tags: true,
    authors: true,
    rss: true
  }}
>
  <BlogHeader
    logo={<Logo />}
    navigation={[
      { label: "Home", href: "/" },
      { label: "Blog", href: "/blog" },
      { label: "About", href: "/about" }
    ]}
    search={true}
    rss={true}
  />

  {/* Blog listing page */}
  <div className="blog-layout">
    <main>
      <BlogGrid
        posts={posts}
        layout="grid"
        postsPerPage={10}
        featured={featuredPosts}
      />
    </main>

    <BlogSidebar
      categories={categories}
      tags={tags}
      recentPosts={recentPosts}
    >
      <Newsletter
        title="Stay updated"
        description="Get new posts in your inbox"
      />
    </BlogSidebar>
  </div>

  {/* Individual blog post */}
  <BlogPost
    title="Getting Started with React"
    excerpt="Learn the basics of React in this comprehensive guide"
    author={{
      name: "Jane Doe",
      avatar: "/avatars/jane.jpg",
      slug: "jane-doe"
    }}
    date="2024-01-15"
    readingTime="5 min read"
    image="/posts/react-intro.jpg"
    categories={["React", "Tutorial"]}
    tags={["beginner", "javascript"]}
  >
    <article>
      <h1>Getting Started with React</h1>
      {/* Post content */}
    </article>

    <AuthorBio
      name="Jane Doe"
      avatar="/avatars/jane.jpg"
      bio="Frontend developer and React enthusiast"
      social={social}
    />

    <RelatedPosts
      posts={relatedPosts}
      algorithm="tags"
      limit={3}
    />

    <Comments
      provider="utterances"
      identifier={post.slug}
    />
  </BlogPost>
</Site>

TypeScript

Full type definition:

import { z } from 'zod'
import { BaseSiteSchema } from 'mdxui/zod'

export const BlogSiteSchema = BaseSiteSchema.extend({
  type: z.literal('blog'),
  blog: z.object({
    postsPerPage: z.number().default(10),
    categories: z.boolean().default(true),
    tags: z.boolean().default(true),
    authors: z.boolean().default(true),
    rss: z.boolean().default(true),
  }).optional(),
})

export type BlogSite = z.infer<typeof BlogSiteSchema>

On this page