Charted Data: Complete Blog Platform & CMS Documentation

Introduction

Charted Data is far more than a charting tool—it's a complete, professional blog platform with a full-featured CMS, advanced content management, lightning-fast performance, and enterprise-grade features. This guide covers everything from writing and publishing content to SEO optimization and site customization.

Whether you're a solo blogger, content team, or organization, you have the tools to create, manage, and distribute beautiful, high-performing blog content.


Table of Contents

  1. Professional Blog Platform Overview
  2. MDX: Markdown + React Power
  3. Rich Text Editing & Components
  4. Smart Content Management
  5. Admin CMS Dashboard
  6. Search & Discovery
  7. SEO & Social Sharing
  8. Performance & Speed
  9. Design & Theming
  10. Configuration & Personalization
  11. Best Practices

Professional Blog Platform Overview

What Makes Charted Data Special

Charted Data is built on a modern, cloud-native architecture designed for today's content creators:

AspectCharted DataTraditional Blogs
Content FormatMDX (Markdown + React)Basic Markdown/HTML
Interactive ContentNative charts, componentsRequires plugins/embeds
PerformanceSub-second loads2-5 second typical
SEOServer-rendered, optimizedPlugin-dependent
CustomizationCode-based, no limitsTheme limited
SecurityModern auth (no passwords)Password vulnerable
OwnershipFull source codePlatform dependent
CostOnly hosting (free tier available)$0-300/month
ScalabilityCDN-ready, serverlessLimited by platform

Who Should Use Charted Data

Perfect for:

  • Technical bloggers (code-focused content)
  • Data journalists (data visualization stories)
  • SaaS/Product companies (feature announcements, metrics)
  • Educators (interactive learning content)
  • Researchers (data-driven articles)
  • Anyone valuing speed & customization

Not ideal for:

  • Casual bloggers wanting zero setup
  • Non-technical users (requires some code comfort)
  • Content-only needs without data/charts

MDX: Markdown + React Power

What is MDX?

MDX = Markdown + JSX

Write articles in familiar Markdown, but embed React components directly:

# My Blog Post
 
This is regular **Markdown** with *emphasis*.
 
<Alert type="info">
  But I can also use React components inline!
</Alert>
 
## Charts Too!
 
<BarChart
  title="My Data"
  data={[...]}
/>
 
Back to Markdown for text.

Why MDX is Powerful

Markdown simplicity — Easy to write, fast to read ✅ React power — Dynamic, interactive elements ✅ Component reuse — Write once, use anywhere ✅ Type-safe — TypeScript support for components ✅ No lock-in — MDX files are portable ✅ SEO-friendly — Content is server-rendered

MDX Basics

Standard Markdown Still Works

# Heading 1
## Heading 2
### Heading 3
 
Regular paragraph text with **bold** and *italic*.
 
- Bullet point 1
- Bullet point 2
- Bullet point 3
 
1. Numbered item
2. Numbered item
3. Numbered item
 
> Blockquote text here
> Can span multiple lines
 
[Link text](https://example.com)

Embedding React Components

# Blog Post Title
 
Regular markdown here.
 
<BarChart
  title="Sales Data"
  data={[...]}
/>
 
More markdown.
 
<Video src="/my-video.mp4" />
 
Conclusion.

Using Variables in Components

export const data = [
  { month: "Jan", sales: 45000 },
  { month: "Feb", sales: 52000 },
  { month: "Mar", sales: 61000 },
];
 
<LineChart
  data={data}
  title="Monthly Sales"
/>

Importing External Data

import { salesData } from "@/data/sales";
 
# Q4 Performance Report
 
<BarChart
  title="Q4 Sales"
  data={salesData}
/>

MDX vs Regular Markdown

FeatureMarkdownMDX
Headers
Text formatting
Lists
Links
React components
Interactive elements
Charts
Dynamic data
Variables
Conditionals

Rich Text Editing & Components

Overview

Charted Data includes a comprehensive library of pre-built components for every content need. No custom coding required—just use them in your MDX.

Code Blocks & Syntax Highlighting

Basic Code Block

function HelloWorld() {
  return <h1>Hello, World!</h1>;
}

With Language Specification

def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
 
print(fibonacci(10))

Line Highlighting (Expressive Code)

function processData(items) {
  return items
    .map(item => item.value)  // Line 3: highlight
    .filter(v => v > 10)      // Line 4: highlight
    .reduce((sum, v) => sum + v, 0);
}

Multiple Language Examples

React Component
export function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}
SQL Query
SELECT users.name, COUNT(posts.id) as post_count
FROM users
LEFT JOIN posts ON users.id = posts.user_id
GROUP BY users.id
ORDER BY post_count DESC;

Features

Language detection — Automatic syntax highlighting ✅ Line numbers — Optional line numbering ✅ Line highlighting — Emphasis key lines ✅ Titles — Label code blocks ✅ Diff highlighting — Show changes ✅ Tabs — Multiple code examples ✅ Copy button — One-click copy ✅ Theme-aware — Dark/light mode

Tables

Simple Table

| Feature | Free | Pro | Enterprise |
|---------|------|-----|------------|
| Posts | 50 | Unlimited | Unlimited |
| Users | 1 | 5 | Unlimited |
| Storage | 1 GB | 100 GB | 1 TB |
| Support | Email | Priority | 24/7 |

Rendered Output

FeatureFreeProEnterprise
Posts50UnlimitedUnlimited
Users15Unlimited
Storage1 GB100 GB1 TB
SupportEmailPriority24/7

Usage Tips

✅ Use for data comparison ✅ Pricing tables ✅ Feature matrices ✅ Specifications ✅ Results/data presentation

Callout Boxes

Info Box

<Info>
This is useful information that readers should know.
It's highlighted but not a warning.
</Info>

Note Box

<Note>
A note is similar to info but slightly different.
Use for side observations or optional context.
</Note>

Tip Box

<Tip>
💡 This is a pro tip! Use this to share best practices,
shortcuts, or valuable advice for readers.
</Tip>

Warning Box

<Warning>
⚠️ Watch out! This warning highlights potential pitfalls,
common mistakes, or important cautions.
</Warning>

Danger Box

<Danger>
🚨 Critical! This is serious—use for breaking changes,
security issues, or critical warnings.
</Danger>

Visual Appearance

┌────────────────────────────────────┐
│ ℹ️  Info Box                        │
│ Light blue background with icon    │
└────────────────────────────────────┘

┌────────────────────────────────────┐
│ 💡 Tip Box                         │
│ Green background with lightbulb    │
└────────────────────────────────────┘

┌────────────────────────────────────┐
│ ⚠️  Warning Box                     │
│ Yellow background with warning     │
└────────────────────────────────────┘

┌────────────────────────────────────┐
│ 🚨 Danger Box                      │
│ Red background with alert icon     │
└────────────────────────────────────┘

Videos & Media

Video Embed (Self-Hosted)

<Video
  src="/videos/my-tutorial.mp4"
  title="My Tutorial"
/>

YouTube Embed

<YouTube
  id="dQw4w9WgXcQ"
  title="YouTube Video"
/>

Rendered Player

Features: ✅ Play/pause controls ✅ Volume control ✅ Fullscreen support ✅ Responsive sizing ✅ Mobile-friendly ✅ Autoplay options

Internal & External Links

Markdown Links

[Link text](https://example.com)
 
[Internal post](/blog/my-other-post)
 
[External site](https://github.com)

Features

Internal links — Fast navigation ✅ External links — Open in new tab with icon ✅ No broken links — Next.js validates ✅ SEO-friendly — Proper link structure

Link Styling

  • Internal links appear blue
  • External links have icon indicator: 🔗
  • Hover effects show the link target
  • Keyboard accessible (Tab + Enter)

Images

Basic Image

![Alt text](/images/my-image.jpg)

With Next.js Image Component

<Image
  src="/images/screenshot.png"
  alt="Screenshot description"
  width={800}
  height={600}
/>

Features

Lazy loading — Images load only when visible ✅ Optimization — Automatic WebP/modern formats ✅ Responsive — Scales to container ✅ Blur placeholder — Loading skeleton ✅ Fast delivery — CDN-optimized ✅ Accessible — Required alt text

Image Best Practices

<!-- ❌ DON'T: Missing alt text -->
![](/images/chart.png)
 
<!-- ✅ DO: Descriptive alt text -->
![Q4 Sales Chart showing 45% growth](/images/q4-sales.png)
 
<!-- ✅ DO: Use next Image for optimization -->
<Image
  src="/images/dashboard.png"
  alt="Analytics dashboard with KPIs"
  width={1200}
  height={800}
/>

Accordions

Expandable Content

<Accordion>
  <AccordionItem title="Question 1">
    Answer to question 1 goes here.
    Can contain **Markdown** and HTML.
  </AccordionItem>
  
  <AccordionItem title="Question 2">
    Answer to question 2 goes here.
  </AccordionItem>
  
  <AccordionItem title="Question 3">
    Answer to question 3 goes here.
  </AccordionItem>
</Accordion>

Use Cases

✅ FAQ sections ✅ Detailed explanations ✅ Nested content ✅ Save vertical space ✅ Improve readability

Tabs

Tabbed Content

<Tabs>
  <TabsContent label="React">
    ```jsx
    function App() {
      return <div>React code here</div>
    }
    ```
  </TabsContent>
  
  <TabsContent label="Vue">
    ```vue
    <template>
      <div>Vue code here</div>
    </template>
    ```
  </TabsContent>
  
  <TabsContent label="Angular">
    ```typescript
    export class AppComponent {
      // Angular code here
    }
    ```
  </TabsContent>
</Tabs>

Use Cases

✅ Multi-language code examples ✅ Different implementation approaches ✅ Comparative content ✅ Platform-specific instructions

Badges & Labels

<Badge>New Feature</Badge>
<Badge variant="secondary">Beta</Badge>
<Badge variant="destructive">Deprecated</Badge>
<Badge variant="outline">Coming Soon</Badge>

Variants

  • default — Blue/primary color
  • secondary — Gray/secondary
  • destructive — Red warning
  • outline — Bordered style

Hover Cards

Tooltip/Popover Content

<HoverCard>
  <HoverCardTrigger>Hover over me</HoverCardTrigger>
  <HoverCardContent>
    This content appears on hover!
    Can contain **markdown** and links.
  </HoverCardContent>
</HoverCard>

Use Cases

✅ Glossary definitions ✅ Acronym explanations ✅ Additional context ✅ Inline help

Separators

---
 
Regular markdown horizontal rule creates a separator.
Useful for visual breaks between sections.
 
---
 
Create visual breathing room in long articles.

Complete Example: Rich Article

# Advanced React Patterns
 
## Introduction
 
Learn about advanced React patterns with **interactive examples**.
 
<Tip>
This guide assumes you know React basics.
New to React? [Start here](/blog/react-basics).
</Tip>
 
## Render Props Pattern
 
### What are Render Props?
 
Render props is a technique for sharing code between components.
 
```jsx title="Example"
<DataFetcher
  render={data => (
    <div>Data: {data}</div>
  )}
/>
```
 
### When to Use
 
<Accordion>
  <AccordionItem title="Advantages">
    - Flexible component composition
    - Easier to understand than HOCs
    - No wrapper hell
  </AccordionItem>
  
  <AccordionItem title="Disadvantages">
    - Can lead to deep nesting
    - Performance overhead
    - Harder to debug
  </AccordionItem>
</Accordion>
 
## Implementation Guide
 
<Tabs>
  <TabsContent label="Class Component">
    ```jsx
    class DataFetcher extends React.Component {
      // Implementation...
    }
    ```
  </TabsContent>
  
  <TabsContent label="Function Component">
    ```jsx
    function DataFetcher({ render }) {
      // Implementation...
    }
    ```
  </TabsContent>
</Tabs>
 
## Performance Comparison
 
| Pattern | Reusability | Performance | Complexity |
|---------|------------|-------------|-----------|
| Render Props | High | Medium | Medium |
| HOC | High | Low | High |
| Hooks | High | High | Low |
 
## Summary
 
<Warning>
Always measure performance in your specific use case.
Different patterns work best in different scenarios.
</Warning>
 
[See the full example](/blog/react-render-props-deep-dive)

Smart Content Management

Frontmatter Metadata

Every article includes YAML frontmatter:

---
title: "My Blog Post"
description: "A brief description for SEO and sharing"
date: "2024-01-15"
author: "Your Name"
category: "Technology"
tags: ["React", "JavaScript", "Web Development"]
featured: false
draft: false
---
 
# Article Content Starts Here

What's in Frontmatter

FieldPurposeExample
titleArticle title"Advanced React Patterns"
descriptionSEO description"Learn advanced React techniques..."
datePublication date"2024-01-15"
authorContent creator"Sarah Chen"
categoryTopic category"Technology"
tagsMicro-categories["React", "JavaScript"]
featuredHomepage highlighttrue or false
draftPublishing statustrue (hidden) / false (published)

Auto-Generated Features

1. Reading Time Estimates

Automatically calculated from word count:

📖 12 min read

Calculation:

  • Average reading speed: 200 words/minute
  • Displayed on article and in listings
  • Helps readers decide whether to read

2. Category Filtering

Posts automatically tagged by category:

Browse by Category:
[ All ] [ Technology ] [ Business ] [ Design ]

Benefits:

  • Readers find related content easily
  • Organized browsing experience
  • Better content discovery

3. Tag System

Multiple tags per post for fine-grained categorization:

Tags: React | JavaScript | Web Development

Features:

  • Click to see all posts with tag
  • Multiple tags per post
  • Hierarchical organization
  • Tag cloud on homepage

4. Featured Posts

Highlighted on homepage and archive:

---
featured: true
---

Where they appear:

  • Homepage banner
  • "Featured Articles" section
  • Special styling/highlighting
  • Social media promotion

5. Related Posts

Automatically suggested based on:

  • Same category → +2 points
  • Shared tags → +1 point per tag
  • Sorted by relevance score
Related Articles:
1. "Building Web Apps with React" (2 tags match)
2. "JavaScript Best Practices" (1 tag match)
3. "Modern Frontend Development" (category match)

6. SEO Metadata

Automatically generated for each post:

<!-- Page Title -->
<title>Advanced React Patterns | My Blog</title>
 
<!-- Meta Description -->
<meta name="description" content="Learn advanced React techniques including render props, HOCs, and custom hooks...">
 
<!-- Keywords -->
<meta name="keywords" content="React, JavaScript, Web Development, Patterns">
 
<!-- Open Graph -->
<meta property="og:title" content="Advanced React Patterns">
<meta property="og:description" content="...">
<meta property="og:image" content="...">
 
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Advanced React Patterns">

Automatic Excerpt Generation

If you don't provide description, it's auto-generated:

---
title: "Article Title"
# No description provided
---
 
# Article Title
 
This is the first paragraph of your article.
It will be used as the excerpt/description...

Generated excerpt:

"This is the first paragraph of your article. It will be used as the excerpt/description..."

Publishing Workflow

Draft Status

---
draft: true
---
  • Post hidden from public
  • Only visible to admin
  • Previewing before publish
  • Scheduling content

Publishing

---
draft: false
---
  • Post goes live immediately
  • Indexed by search engines
  • Appears in feeds/listings
  • Shareable

Updating Published Posts

---
title: "Updated Post Title"
# Updated date automatically
---
  • Changes apply immediately
  • Search engines notified
  • Social shares updated
  • Reading time recalculated

Content Organization

By Category

Technology (28 posts)
├── React (12)
├── JavaScript (8)
└── Web Dev (8)

Business (15 posts)
├── Startups (7)
├── Marketing (5)
└── Sales (3)

Design (10 posts)
├── UI/UX (6)
└── Branding (4)

By Tags

React (12 posts)
JavaScript (18 posts)
Web Development (25 posts)
Performance (8 posts)
SEO (5 posts)

Admin CMS Dashboard

Accessing the Dashboard

Navigate to /admin:

https://yourdomain.com/admin

Authentication Flow

First-Time Setup

  1. Configure Admin Email in .env:

    ADMIN_EMAIL="your@email.com"
  2. Visit /admin — Redirects to login

  3. Sign in with email — Passwordless authentication:

    Enter your email → Receive verification link → Click link → Logged in
    
  4. Stay logged in — Session persists in secure cookie

Logging Out

Click Sign Out in admin panel → Redirected to blog homepage

Dashboard Overview

┌─────────────────────────────────────────┐
│  📝 Admin Dashboard          [Sign Out]  │
├─────────────────────────────────────────┤
│                                         │
│  Quick Stats:                           │
│  • Total Posts: 42                      │
│  • Published: 38                        │
│  • Drafts: 4                            │
│  • Featured: 3                          │
│                                         │
├─────────────────────────────────────────┤
│                                         │
│  Recent Posts:                          │
│  ✏️  [New Post] [Edit] [View] [Delete]  │
│  ✏️  [New Post] [Edit] [View] [Delete]  │
│  ✏️  [New Post] [Edit] [View] [Delete]  │
│                                         │
├─────────────────────────────────────────┤
│  [+ New Post]  [Archive]  [Manage Tags]  │
└─────────────────────────────────────────┘

Creating a New Post

Step 1: Click "New Post"

Button appears in dashboard or top navigation:

[+ New Post]

Step 2: Fill in Metadata

Title:              [Advanced React Patterns     ]
Description:       [Learn advanced React...     ]
Category:          [Technology                  ]
Author:            [Your Name                   ]
Publication Date:  [2024-01-15]

Step 3: Write Content

Full MDX editor with:

  • Syntax highlighting
  • Live preview
  • Component autocomplete
  • Formatting toolbar
# Article Title
 
Your **Markdown** content here.
 
<BarChart
  title="My Data"
  data={[...]}
/>

Step 4: Manage Tags

Add tags for categorization:

Tags: [React] [JavaScript] [Web] [+Add Tag]

Step 5: Set Status

[ ] Draft        (Hide from public)
[x] Featured     (Highlight on homepage)
[ ] Publish      (Make public)

Step 6: Save & Publish

[Save Draft]  [Preview]  [Publish]

Editing Existing Posts

From Dashboard

  1. Find post in recent list
  2. Click [Edit] button
  3. Make changes
  4. Click [Update]

From Blog

  1. View published post
  2. If logged in, [Edit] button appears
  3. Click to edit in CMS
  4. Make changes
  5. Publish updates

Editor Interface

┌──────────────────────────────────────┐
│ Title: [                           ] │
├──────────────────────────────────────┤
│ Description: [                     ] │
│ Category: [Technology ▼]            │
│ Tags: [React] [JavaScript] [+]      │
├──────────────────────────────────────┤
│ Content Editor (with preview):       │
│                                      │
│ # Title                │ ## Preview  │
│ Your **content** here  │ Title       │
│                        │             │
│ <BarChart ... />       │ Your content │
│                        │ here        │
├──────────────────────────────────────┤
│ Publishing Status:                   │
│ ○ Draft  ○ Ready  ○ Published       │
│                                      │
│ [Save Draft]  [Preview]  [Publish]  │
└──────────────────────────────────────┘

Post Management Features

Bulk Actions

Select Posts: [✓] Post 1  [✓] Post 2  [✓] Post 3

Bulk Actions:
[ Archive ] [ Publish ] [ Make Featured ] [ Delete ]

Search Posts

Search: [article title...] 🔍

Results:
• "Advanced React Patterns" by Sarah Chen
• "React Performance Optimization" by John Doe
• "React Hooks Deep Dive" by Maria Garcia

Sort & Filter

Sort by:     [Most Recent ▼]
Category:    [All ▼]
Status:      [All ▼]

View Post

From admin panel, click [View] to see published post:

Opens in new tab → https://yourdomain.com/blog/post-slug

Post Metadata Fields

Required Fields

  • Title — Article headline (1-100 characters)
  • Content — Article body (MDX format)

Optional but Recommended

  • Description — SEO description (50-160 characters)
  • Category — Primary topic (one category per post)
  • Author — Content creator (defaults to config)
  • Tags — Multiple tags for detailed categorization

Publishing Fields

  • Publication Date — When post was/will be published
  • Draft Flag — Hidden until ready
  • Featured Flag — Highlighted on homepage

Content Preview

Live Preview

While editing, see real-time preview:

MDX Editor          Live Preview
┌─────────────┐    ┌─────────────┐
│ # Title     │    │ # Title     │
│             │    │ Rendered    │
│ <Chart />   │    │ [Chart]     │
│             │    │ displayed   │
└─────────────┘    └─────────────┘

Full Page Preview

Before publishing, see how post looks:

[Preview] → Opens in new tab with full blog styling
           → All CSS/themes applied
           → See mobile appearance
           → Test responsiveness

Mobile Preview

Toggle mobile view while editing:

[🖥️ Desktop] [📱 Mobile] [📱 Tablet]

Shows how content appears on different devices

Autosave & Recovery

Automatic Saving — Every 30 seconds ✅ Draft Backup — Never lose work ✅ Version History — See previous edits ✅ Recovery — Restore from backup

Post Validation

System checks before publishing:

✓ Title is not empty
✓ Description is 50-160 characters
✓ Category is selected
✓ At least one tag added
✓ Content has at least 100 words
✗ Warning: Featured post should have header image

[Fix Issues] [Publish Anyway]

Search & Discovery

Full-Text Blog Search

How Search Works

Built on Pagefind—a lightweight, zero-bandwidth search engine:

1. User types query: "React performance"
2. Client-side search (no server request)
3. Instantly returns matching posts
4. Zero latency (vs traditional search)

Search Features

Instant results — Results as you type ✅ No tracking — Privacy-first ✅ Zero server cost — Client-side only ✅ Offline capable — Works without internet ✅ Fuzzy matching — Typo-tolerant ✅ Highlighting — Shows matched terms

Using Search

┌────────────────────────────────┐
│ 🔍 Search blog...             │
└────────────────────────────────┘

As you type:
"React" → Shows all posts mentioning React
"React performance" → Posts about React + performance
"hooks" → Posts about hooks

Results show:
• Post title (with matched terms highlighted)
• Excerpt (preview of matching content)
• Reading time & date

Search Scope

Search includes: ✅ Post titles ✅ Post descriptions ✅ Post content (full text) ✅ Post tags ✅ Post categories

Example Search Scenarios

Search: "authentication"
Results:
1. "User Authentication Best Practices"
2. "OAuth 2.0 Implementation Guide"
3. "Session Management in Node.js"

Search: "performance optimization"
Results:
1. "React Performance Tips"
2. "Database Query Optimization"
3. "Image Optimization Strategies"

Search: "REST API"
Results:
1. "Building REST APIs with Express"
2. "REST vs GraphQL: A Comparison"
3. "API Authentication Patterns"

Category Filtering

Browse by Category

Homepage and blog archive show categories:

All Categories:
[All] [Technology] [Business] [Design] [How-To]

Click to filter posts by category

Category Pages

Each category has dedicated page:

https://yourdomain.com/blog?category=technology

Shows:
• Category title
• Post count (12 posts)
• All posts in category
• Sort options (recent first, A-Z, etc.)

Category Organization

In config/site.ts:

blog: {
  categories: [
    "Development",
    "Design",
    "Technology",
    "Tutorials",
    "News",
  ],
}

Benefits

✅ Helps readers navigate by topic ✅ Improved content discoverability ✅ Better SEO (category pages indexed) ✅ Organized browsing experience

Tag System

What Are Tags?

Tags are micro-categories for detailed content classification:

Post: "React Hooks Deep Dive"

Category: Development (broad)
Tags: React, JavaScript, Hooks, Advanced (specific)

Using Tags

---
tags: ["React", "Hooks", "JavaScript", "Advanced"]
---

Tag Cloud

Visual representation of all tags:

react (12)  javascript (18)  web-dev (25)
performance (8)  seo (5)  tailwind (10)
next.js (14)  typescript (9)  graphql (6)

Larger text = more posts with that tag

Browsing by Tag

Click any tag to see all posts:

Tag: "React"
12 posts tagged with "React":

1. "React Hooks Deep Dive"
2. "Advanced React Patterns"
3. "React Performance Optimization"
... more results

Tag Filtering

Filter by multiple tags:

Tags: [React] [JavaScript] + Add more

Shows posts tagged with BOTH React AND JavaScript

Tag vs Category

AspectCategoryTags
Number per post1 onlyMultiple
GranularityBroadFine-grained
Use caseTopic groupingDetailed classification
ExamplesTechnology, DesignReact, JavaScript, Hooks
NavigationBrowse by categorySearch/filter by tag

Pagination

How Pagination Works

Posts Per Page: 10 (configurable)

Page 1 (posts 1-10):
[← Prev] [1] 2 3 4 [Next →]

Page 2 (posts 11-20):
[← Prev] 1 [2] 3 4 [Next →]

Page 3 (posts 21-30):
[← Prev] 1 2 [3] 4 [Next →]

Page 4 (posts 31-40):
[← Prev] 1 2 3 [4] [Next →]

Configuration

In config/site.ts:

blog: {
  postsPerPage: 10,  // Posts per page
  featuredPostsCount: 3,  // Featured on homepage
  relatedPostsCount: 3,   // Related suggestions
}

Benefits

✅ Cleaner page loads ✅ Better performance (fewer posts to render) ✅ Improved UX (not overwhelming) ✅ Faster navigation

Related Posts

How It Works

System calculates relevance score:

Same category: +2 points
Shared tag: +1 point per tag

Example:
Post: "React Hooks"
Category: Development
Tags: React, JavaScript, Hooks

Other posts:
1. "React Patterns" (Dev + React + JavaScript + Hooks) → 2+3 = 5 points
2. "JavaScript Tips" (Dev + JavaScript) → 2+1 = 3 points
3. "Node.js Guide" (Dev) → 2+0 = 2 points

Top 3 shown as "Related Posts"

Display

At bottom of article:

📖 Related Articles

1. "Advanced React Patterns" (4 tags match)
2. "JavaScript Best Practices" (2 tags match)
3. "Web Development Tools" (1 tag match, same category)

Benefits

✅ Increase time on site ✅ Improve content discoverability ✅ Automatic, no manual curation ✅ Personalized recommendations


SEO & Social Sharing

OpenGraph Support

What is OpenGraph?

Metadata that controls how your content appears when shared:

<meta property="og:title" content="Article Title">
<meta property="og:description" content="Article summary...">
<meta property="og:image" content="https://...og-image.jpg">
<meta property="og:url" content="https://yourdomain.com/blog/post">
<meta property="og:type" content="article">

When Shared on Social Media

Twitter/X Preview:
┌─────────────────────────────────┐
│ Article Title                   │
│                                 │
│ [OG Image - 1200x630]          │
│                                 │
│ Article summary text...         │
│ yourdomain.com                  │
└─────────────────────────────────┘

LinkedIn Preview:
┌─────────────────────────────────┐
│ Article Title                   │
│ yourdomain.com                  │
│                                 │
│ Article summary...              │
│                                 │
│ [OG Image - Square or Wide]     │
└─────────────────────────────────┘

Facebook Preview:
┌─────────────────────────────────┐
│ [Large OG Image]                │
│ Article Title                   │
│ yourdomain.com                  │
│ Article summary...              │
└─────────────────────────────────┘

Automatic Generation

Charted Data automatically generates OpenGraph tags:

---
title: "My Article"
description: "Article summary for sharing"
---
 
Auto-generated:
✓ og:title → Article title
✓ og:description → Article description
✓ og:url → Canonical URL
✓ og:image → Default or custom image
✓ og:type → "article"
✓ article:published_time → Publication date
✓ article:author → Author name

JSON-LD Structured Data

What is JSON-LD?

Machine-readable metadata that helps Google understand your content:

{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Advanced React Patterns",
  "description": "Learn advanced React techniques...",
  "image": "https://yourdomain.com/og-image.jpg",
  "author": {
    "@type": "Person",
    "name": "Sarah Chen"
  },
  "datePublished": "2024-01-15",
  "dateModified": "2024-01-20"
}

Google Search Results

JSON-LD enables rich snippets in search:

Google Search Result:

Advanced React Patterns
yourdomain.com › blog › react-patterns

Learn advanced React techniques including render props, HOCs, and custom hooks...

⭐⭐⭐⭐⭐ (4.8) • By Sarah Chen • Jan 15, 2024 • 12 min read

Structured Data Types

Charted Data includes:

BlogPosting — Article schema ✅ Article — Generic article metadata ✅ Person — Author information ✅ Organization — Site/company info ✅ WebSite — Site-wide schema ✅ ItemList — Article listings

Verification

Check if structured data is correct:

Google Search Console:
1. Go to "Rich Results" section
2. See if articles are marked as "valid"
3. View how Google interprets your site

Structured Data Tester:
1. Go to schema.org validator
2. Paste your blog post URL
3. Check JSON-LD is correctly formatted

Meta Tags

Automatically Generated

<!-- Page Title (appears in browser tab) -->
<title>Advanced React Patterns | My Blog</title>
 
<!-- Description (appears in Google results) -->
<meta name="description" 
      content="Learn advanced React techniques...">
 
<!-- Keywords (used by search engines) -->
<meta name="keywords" 
      content="React, JavaScript, Web Development">
 
<!-- Robots (indexing instructions) -->
<meta name="robots" content="index, follow">
 
<!-- Canonical (preferred URL for duplicates) -->
<link rel="canonical" 
      href="https://yourdomain.com/blog/react-patterns">
 
<!-- Viewport (mobile optimization) -->
<meta name="viewport" 
      content="width=device-width, initial-scale=1">

Best Practices

Title (50-60 chars)

Advanced React Patterns - Build Better Apps

Description (150-160 chars)

Learn advanced React techniques including render props, HOCs, 
and custom hooks. Build scalable, maintainable applications.

Keywords (4-6 relevant terms)

React, JavaScript, Web Development, Hooks, Patterns, Advanced

Automatic Sitemaps

What is a Sitemap?

XML file telling search engines about all your content:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://yourdomain.com/</loc>
    <lastmod>2024-01-20</lastmod>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>https://yourdomain.com/blog</loc>
    <lastmod>2024-01-20</lastmod>
    <priority>0.8</priority>
  </url>
  <url>
    <loc>https://yourdomain.com/blog/react-patterns</loc>
    <lastmod>2024-01-15</lastmod>
    <priority>0.7</priority>
  </url>
  ...
</urlset>

Automatic Generation

Your sitemap updates automatically:

✓ New posts added automatically
✓ Updates when you publish/unpublish
✓ Includes modification date
✓ Sets priority based on post age
✓ Updates every 24 hours minimum

How Google Uses It

1. Google bot crawls sitemap.xml
2. Discovers all your articles
3. Indexes new content faster
4. Tracks when content changes
5. Prioritizes important pages

Accessing Your Sitemap

https://yourdomain.com/sitemap.xml
https://yourdomain.com/robots.txt

Google Search Console Setup

1. Go to Google Search Console
2. Add property (your domain)
3. Submit sitemap: https://yourdomain.com/sitemap.xml
4. Monitor indexing status
5. See search analytics

RSS Feed

What is RSS?

"Really Simple Syndication" — allows readers to subscribe to your blog:

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>My Blog</title>
    <link>https://yourdomain.com</link>
    <description>Articles about web development</description>
    <item>
      <title>Advanced React Patterns</title>
      <link>https://yourdomain.com/blog/react-patterns</link>
      <description>Learn advanced React techniques...</description>
      <pubDate>Mon, 15 Jan 2024 10:00:00 GMT</pubDate>
    </item>
    ...
  </channel>
</rss>

How Readers Use RSS

1. Copy your RSS feed URL: https://yourdomain.com/feed.xml
2. Paste into RSS reader (Feedly, Apple News, etc.)
3. Receive new posts automatically
4. Read offline
5. Sync across devices

Benefits

✅ Readers subscribe to updates ✅ Direct distribution (no algorithm) ✅ Increased readership ✅ Email newsletter integration

Enabling RSS

In config/site.ts:

features: {
  rss: true,  // Enable RSS feed
}

RSS Feed URL

https://yourdomain.com/feed.xml

Promote it:

  • Add RSS link in header/footer
  • Include in email newsletters
  • Share in documentation

Canonical URLs

What is Canonical?

Tells Google which version of a page is "preferred":

<!-- Blog Post -->
<link rel="canonical" 
      href="https://yourdomain.com/blog/react-patterns">
 
<!-- Prevents duplicate content issues -->
<!-- If accidentally duplicated, Google knows which is original -->

Why It Matters

Issue: Same article at multiple URLs
https://yourdomain.com/blog/react-patterns
https://yourdomain.com/post/react-patterns
https://yourdomain.com/articles/react-patterns

Google doesn't know which to rank.
Canonical tells Google: "This one is correct"

Automatic Management

Charted Data automatically sets canonical URLs:

---
title: "My Post"
---
 
Generated canonical:
<link rel="canonical" 
      href="https://yourdomain.com/blog/my-post">

Twitter/X Cards

What are Twitter Cards?

Special formatting for tweets that preview your content:

Twitter Timeline Preview:

Sarah Chen @sarahchen
Just published: Advanced React Patterns

[Card Image - 1200x630]
Advanced React Patterns
Learn advanced React techniques including render props...
yourdomain.com

↩️ 234  🔄 456  ♥️ 1.2K  📤

Card Types

Charted Data uses: Summary Large Image

┌─────────────────────────────────┐
│ [Large Image - 1200x630]        │
│                                 │
│ Article Title                   │
│ Brief description               │
│ yourdomain.com                  │
└─────────────────────────────────┘

Auto-Generated Meta Tags

<meta name="twitter:card" 
      content="summary_large_image">
<meta name="twitter:title" 
      content="Advanced React Patterns">
<meta name="twitter:description" 
      content="Learn advanced React techniques...">
<meta name="twitter:image" 
      content="https://yourdomain.com/og-image.jpg">
<meta name="twitter:site" 
      content="@yourtwitterhandle">
<meta name="twitter:creator" 
      content="@authorhandle">

Configuration

In config/site.ts:

author: {
  twitter: "@yourtwitterhandle",
}
 
seo: {
  twitterCardType: "summary_large_image",
}

Performance & Speed

Ultra-Fast Loading

Next.js Optimization

Built on Next.js 16 for production-grade performance:

Traditional Blog:
DOM Ready:     2.5s
Fully Loaded:  5.2s
Time to Paint: 3.1s

Charted Data Blog:
DOM Ready:     0.3s ⚡
Fully Loaded:  0.8s ⚡
Time to Paint: 0.2s ⚡

What Makes It Fast

Server-Side Rendering — HTML ready on first request ✅ Code Splitting — Only load code needed for current page ✅ Image Optimization — Automatic WebP, lazy loading ✅ CSS Optimization — Minimal CSS sent to client ✅ Caching — Intelligent browser/CDN caching ✅ Bun Runtime — 3x faster than Node.js

Image Optimization

Next.js Image Component

<Image
  src="/images/screenshot.png"
  alt="Screenshot"
  width={1200}
  height={800}
/>
 
Automatically provides:
✓ WebP format (smaller files)
✓ Multiple resolutions (responsive)
✓ Lazy loading (load when visible)
✓ Blur placeholder (visual feedback)
✓ Optimized for each device

Results

Original JPEG:     850 KB
Optimized WebP:    120 KB (86% reduction!)
Lazy loaded:       Not loaded until visible
On mobile:         Scaled to device width

Best Practices

✅ Use <Image> component instead of <img> ✅ Always provide width/height ✅ Compress images before uploading ✅ Use descriptive alt text

CSS Efficiency

Tailwind CSS 4

Minimal runtime CSS overhead:

Traditional CSS Framework:
Generated CSS:   285 KB
Runtime overhead: 15 KB JS

Tailwind CSS 4:
Generated CSS:   18 KB (94% smaller!)
Runtime overhead: 0 KB (zero-runtime)

How It Works

// You write:
<div className="flex items-center justify-between p-4">
  Content
</div>
 
// Tailwind generates ONLY the CSS you use
.flex { display: flex; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.p-4 { padding: 1rem; }
 
// Unused CSS is completely removed

Benefits

✅ Smaller CSS files ✅ Faster page loads ✅ Better caching ✅ Perfect for performance budgets

Server-Side Rendering

What is SSR?

Render HTML on server, send ready-to-display page to client:

Traditional SPA:
1. Browser requests page
2. Server sends empty HTML + JavaScript
3. Browser downloads JavaScript
4. Browser executes JavaScript
5. Page renders (slow!)

Server-Side Rendering:
1. Browser requests page
2. Server renders to HTML
3. Browser receives complete HTML
4. Page displays immediately (fast!)

Performance Impact

SSR Blog:
First Contentful Paint: 0.2s
Fully Interactive: 0.8s
Time to Interaction: 0.5s

Non-SSR Blog:
First Contentful Paint: 1.8s
Fully Interactive: 3.2s
Time to Interaction: 2.1s

SEO Benefit

Search Engine Bot crawling:
SSR: "Page ready immediately" → Full content indexed
CSR: "Page mostly empty JS" → Limited content indexed

Global CDN Ready

Edge Caching

Deploy to Vercel for automatic CDN distribution:

User in New York:
  Request → CDN in NYC (0.05s) ✓

User in London:
  Request → CDN in London (0.05s) ✓

User in Tokyo:
  Request → CDN in Tokyo (0.05s) ✓

Traditional single-server:
  All users connect to one server
  Sydney user: 200ms+ latency

Deployment

# One-click deployment
git push origin main
 
Vercel automatically:
 Builds site
 Optimizes for edge
 Deploys globally
 Provides CDN
 Manages SSL/HTTPS
 Auto-scales

Performance Metrics

Core Web Vitals

Google's three key metrics:

Largest Contentful Paint (LCP): < 2.5s ✓
First Input Delay (FID): < 100ms ✓
Cumulative Layout Shift (CLS): < 0.1 ✓

Charted Data typically achieves:
LCP: 0.4s (target: 2.5s)
FID: 0.02ms (target: 100ms)
CLS: 0.01 (target: 0.1)

Measuring Performance

Google PageSpeed Insights:
https://pagespeed.web.dev

Lighthouse (in browser DevTools):
1. Open site in Chrome
2. Press F12 (DevTools)
3. Go to Lighthouse tab
4. Click "Analyze page load"
5. Get detailed metrics

Caching Strategy

Browser Caching

User visits blog:
1. First visit: Download all assets (slower)
2. Assets cached locally (30 days)
3. Second visit: Load from cache (much faster)

CDN Caching

First visitor in region:
  1. Request → CDN (miss)
  2. CDN gets from origin
  3. Caches for 1 hour
  
Next 1000 visitors:
  1. Request → CDN (hit) - instant ✓

Stale-While-Revalidate

Cached content expires:
  1. Serve stale version immediately (fast)
  2. Revalidate in background
  3. Update cache for next user
  
Result: Always fast, always fresh

Design & Theming

Beautiful Default Design

Philosophy

Typographic-first, minimalist, professional:

✓ Clean white/dark backgrounds
✓ Legible fonts (readable at all sizes)
✓ Ample whitespace (not cramped)
✓ Hierarchy through size/weight (not color)
✓ Calm color palette (not flashy)
✓ Professional aesthetic (not playful)

Default Color Palette

Primary:      #0066CC (Blue)
Secondary:    #6B7280 (Gray)
Success:      #10B981 (Green)
Warning:      #F59E0B (Amber)
Danger:       #EF4444 (Red)
Background:   #FFFFFF / #1F2937 (dark)
Text:         #111827 / #F3F4F6 (dark)

Typography

Headings:    Geist Sans (sans-serif)
Body:        Geist Sans (sans-serif)
Code:        Geist Mono (monospace)

Font Scale:
h1: 32px
h2: 24px
h3: 20px
p:  16px
small: 14px
code: 14px (monospace)

Dark/Light Mode Toggle

How It Works

Button in header:
🌞 Light Mode ←→ 🌙 Dark Mode

Click to toggle → Theme updates instantly

Automatic Detection

First visit:
✓ Detects system preference
✓ Uses system dark/light mode
✓ No jarring theme change

User override:
✓ Click theme toggle
✓ Override system preference
✓ Preference saved locally

Implementation

// Automatic dark mode detection
<ThemeProvider
  attribute="class"
  defaultTheme="system"
  enableSystem
/>

What Changes

Light Mode:
- White background
- Dark text
- Light borders

Dark Mode:
- Dark (#1F2937) background
- Light text
- Darker borders
- All colors inverted appropriately

Fully Customizable

With Tailwind CSS

Complete styling control via classes:

// Default button
<Button>Click Me</Button>
 
// Custom styling
<Button className="bg-gradient-to-r from-purple-500 to-pink-500 text-white text-lg px-8 py-4 rounded-full">
  Custom Button
</Button>

With CSS Overrides

/* Global styling */
:root {
  --primary: #0066CC;
  --secondary: #6B7280;
  --accent: #F59E0B;
}
 
/* Component styling */
.blog-card {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 12px;
  box-shadow: 0 8px 16px rgba(0,0,0,0.1);
}

Configuration File

Main customization through config/site.ts:

export const siteConfig = {
  // Branding
  name: "My Blog",
  logo: {
    text: "My Blog",
    image: "/logo.svg",
  },
  
  // Colors (in CSS)
  theme: {
    defaultTheme: "system",
    enableToggle: true,
  },
  
  // Fonts (in globals.css)
  // Navigation (in site.ts)
  mainNav: [
    { title: "Home", href: "/" },
    { title: "Blog", href: "/blog" },
  ],
}

Professional UI Kit

50+ Pre-Built Components

Navigation:

  • Header/Footer
  • Navigation menu
  • Breadcrumbs
  • Sidebar

Content:

  • Cards
  • Badges
  • Separators
  • Dividers

Forms:

  • Buttons
  • Inputs
  • Checkboxes
  • Dropdowns

Interactive:

  • Modals/Dialogs
  • Tabs
  • Accordions
  • Tooltips
  • Popovers

Data:

  • Tables
  • Lists
  • Pagination

Component Examples

// Button
<Button>Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
 
// Card
<Card>
  <CardHeader>
    <CardTitle>Card Title</CardTitle>
    <CardDescription>Subtitle</CardDescription>
  </CardHeader>
  <CardContent>Content here</CardContent>
  <CardFooter>Footer actions</CardFooter>
</Card>
 
// Badge
<Badge>New</Badge>
<Badge variant="secondary">Beta</Badge>
<Badge variant="destructive">Deprecated</Badge>
 
// Dialog
<Dialog>
  <DialogTrigger>Open</DialogTrigger>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Dialog Title</DialogTitle>
    </DialogHeader>
    Dialog content here
  </DialogContent>
</Dialog>

Customization

Each component fully themeable:

// With props
<Button size="lg" variant="gradient">Large Gradient Button</Button>
 
// With className
<Button className="bg-blue-600 hover:bg-blue-700">Custom</Button>
 
// With CSS
<style>{`
  .custom-button {
    background: linear-gradient(...);
    border-radius: 20px;
  }
`}</style>

Micro-interactions

Powered by Framer Motion

Smooth, delightful animations:

// Page entrance
<motion.div
  initial={{ opacity: 0 }}
  animate={{ opacity: 1 }}
  transition={{ duration: 0.5 }}
>
  Page content
</motion.div>
 
// Card hover
<motion.div
  whileHover={{ scale: 1.05 }}
  transition={{ type: "spring" }}
>
  Interactive card
</motion.div>
 
// List item stagger
<motion.ul>
  {items.map((item) => (
    <motion.li
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ delay: 0.1 }}
    >
      {item}
    </motion.li>
  ))}
</motion.ul>

Built-In Animations

✅ Page transitions (fade in/out) ✅ Hover effects (scale, color change) ✅ Loading animations (spinner) ✅ Toast notifications (slide in/out) ✅ Modal entrances (scale up) ✅ Button states (press effect)

Performance

All animations: ✓ GPU-accelerated (60fps) ✓ Non-blocking (don't interrupt interaction) ✓ Accessible (reduced-motion respected) ✓ Smooth on all devices

Icon Library

Lucide React

560+ professional icons:

import { Heart, Star, Share2, Download, Settings } from 'lucide-react';
 
<Heart />
<Star size={24} strokeWidth={3} />
<Share2 color="blue" />
<Download className="animate-bounce" />
<Settings size={32} />

Common Icons

Navigation:     ChevronDown, Menu, X, ArrowLeft, ArrowRight
Social:         Github, Twitter, Linkedin, Facebook, Mail
Status:         CheckCircle, AlertCircle, Clock, Loader
Content:        Edit, Trash2, Copy, Download, Share2
Objects:        Home, Heart, Star, Settings, Search

Customization

<Heart 
  size={32}           // Size
  color="red"         // Color
  strokeWidth={2}     // Thickness
  className="animate-bounce"  // CSS class
/>

Configuration & Personalization

Single Config File

The Master Control Panel

config/site.ts controls everything about your site:

export const siteConfig = {
  // Core branding
  name: "Charted Data",
  title: "Charted Data Blog",
  tagline: "Beautiful data visualizations in your blog",
  description: "...",
  url: "https://yourdomain.com",
  
  // Author/Owner
  author: {
    name: "Your Name",
    bio: "Bio here",
    email: "you@example.com",
    avatar: "/avatar.png",
    twitter: "@yourhandle",
    github: "yourgithub",
  },
  
  // Navigation
  mainNav: [
    { title: "Home", href: "/" },
    { title: "Blog", href: "/blog" },
    { title: "Charts", href: "/charts" },
    { title: "About", href: "/about" },
  ],
  
  // Blog settings
  blog: {
    postsPerPage: 10,
    featuredPostsCount: 2,
    latestPostsCount: 5,
    showReadingTime: true,
    showTableOfContents: false,
    showRelatedPosts: true,
    relatedPostsCount: 3,
    categories: ["Development", "Design", "Business"],
  },
  
  // Features
  features: {
    search: true,
    rss: true,
    sitemap: true,
    codeHighlighting: true,
    pageTransitions: true,
    readingProgress: true,
  },
  
  // SEO
  seo: {
    keywords: ["blog", "technology", "development"],
    twitterCardType: "summary_large_image",
    allowIndexing: true,
  },
  
  // Social
  social: {
    twitter: "https://twitter.com/...",
    github: "https://github.com/...",
    linkedin: "https://linkedin.com/...",
    rss: "/feed.xml",
  },
}

Branding Customization

Site Identity

siteConfig: {
  name: "My Blog",                    // Site name
  title: "My Blog - Articles",        // Browser tab title
  tagline: "Thoughts on tech",        // Homepage tagline
  description: "Articles about...",   // Default description
  url: "https://myblog.com",          // Site URL
  
  logo: {
    text: "My Blog",                  // Text logo fallback
    image: "/logo.svg",               // Logo image
    width: 120,
    height: 40,
  },
}

Apply Changes

// Restart dev server after changes
bun run dev
 
// Or for production
bun run build
bun start

Navigation Configuration

Main Navigation

mainNav: [
  { title: "Home", href: "/" },
  { title: "Blog", href: "/blog" },
  { title: "Charts", href: "/charts" },
  { title: "About", href: "/about" },
  { title: "Contact", href: "/contact" },
],

Footer Navigation

footerNav: {
  main: [
    { title: "Home", href: "/" },
    { title: "Blog", href: "/blog" },
    { title: "Charts", href: "/charts" },
  ],
  legal: [
    { title: "Privacy", href: "/privacy" },
    { title: "Terms", href: "/terms" },
  ],
},

Result

Header:
[Logo] Home Blog Charts About Contact [🌙]

Footer:
Main Links:  Home | Blog | Charts
Legal:       Privacy | Terms
Copyright:   © 2024 My Blog

Social Links

Configuration

social: {
  twitter: "https://twitter.com/yourhandle",
  github: "https://github.com/yourname",
  linkedin: "https://linkedin.com/in/yourname",
  youtube: "https://youtube.com/@yourchannel",
  instagram: "https://instagram.com/yourhandle",
  discord: "https://discord.gg/yourserver",
  rss: "/feed.xml",
},

Where They Appear

  • Header (top navigation)
  • Footer (contact section)
  • About page (social profiles)
  • JSON-LD schema (for Google)
  • Share buttons (on articles)

Auto-Linking

// In footer, creates clickable icons
<SocialLink href={config.social.twitter} icon={Twitter} />
<SocialLink href={config.social.github} icon={Github} />

Blog Settings

Post Display

blog: {
  postsPerPage: 10,           // Posts per page (pagination)
  featuredPostsCount: 2,      // Featured on homepage
  latestPostsCount: 5,        // Recent posts section
  showReadingTime: true,      // "5 min read" indicator
  showTableOfContents: false, // TOC for posts
  showRelatedPosts: true,     // Related suggestions
  relatedPostsCount: 3,       // Number to show
}

Categories

blog: {
  categories: [
    "Development",
    "Design",
    "Business",
    "Tutorials",
    "News",
  ],
}

Analytics Integration

Google Analytics

analytics: {
  googleAnalyticsId: "G-XXXXXXXXXX",  // GA4 ID
  plausibleDomain: null,              // Or Plausible
  umamiWebsiteId: null,               // Or Umami
  umamiUrl: null,
}

Setup

1. Create Google Analytics 4 property
2. Get Measurement ID (G-...)
3. Add to config
4. Verify tracking in GA console

Feature Flags

Control Functionality

features: {
  search: true,              // Enable Pagefind search
  rss: true,                 // Enable RSS feed
  sitemap: true,             // Generate sitemap.xml
  codeHighlighting: true,    // Syntax highlighting
  pageTransitions: true,     // Page animations
  readingProgress: true,     // Progress bar on posts
}

Toggling Features

// Disable search temporarily
features: { search: false }
 
// Disable RSS feed
features: { rss: false }
 
// Disable animations for accessibility
features: { pageTransitions: false }

Footer Customization

footer: {
  copyright: "© {year} My Blog. All rights reserved.",
  showBuiltWith: true,
  builtWithText: "Built with Next.js and MDX",
  showNewsletter: false,
  newsletterHeading: "Subscribe",
  newsletterDescription: "Get updates...",
}

Theme Configuration

theme: {
  defaultTheme: "system",  // "light" | "dark" | "system"
  enableToggle: true,      // Show theme toggle button
}

Environment Variables

Setup File

Create .env.local:

# Database
DATABASE_URL="postgresql://user:pass@host/db"
 
# Authentication
NEON_AUTH_BASE_URL="https://auth.region.neon.tech"
NEON_AUTH_COOKIE_SECRET="your-secret-key-here"
 
# Admin
ADMIN_EMAIL="admin@yourdomain.com"
 
# Site
NEXT_PUBLIC_SITE_URL="https://yourdomain.com"
 
# Analytics (optional)
NEXT_PUBLIC_GA_ID="G-XXXXXXXXXX"
NEXT_PUBLIC_PLAUSIBLE_DOMAIN="yourdomain.com"

Where to Get Values

Database URL:

  • Neon.tech → Create project → Connection string

Auth credentials:

  • Neon Auth dashboard → Generate keys

Admin email:

  • Your email (only one gets CMS access)

Best Practices

Writing for Web

DO:

  • Front-load the most important information
  • Use short paragraphs (2-3 sentences)
  • Break up text with headings
  • Use bullet points for lists
  • Link to related content
  • Include visual breaks (images, charts)

DON'T:

  • Write long paragraphs (hard to scan)
  • Bury the lede (important info at end)
  • Use walls of text (overwhelming)
  • Forget to proofread (reduces credibility)

Content Strategy

Publish regularly — Consistent schedule (weekly, biweekly) ✅ Build series — Multi-part deep dives ✅ Update evergreen content — Keep old posts fresh ✅ Link internally — Build content webs ✅ Track analytics — See what resonates

SEO Best Practices

Titles — 50-60 characters, include keyword ✅ Descriptions — 150-160 characters, compelling preview ✅ Headings — One H1 per page, proper hierarchy ✅ Keywords — 3-5 per post, naturally distributed ✅ Links — Internal links to related content ✅ Images — Descriptive alt text ✅ Length — 800+ words for rankings ✅ Freshness — Update dates when modified

Performance Best Practices

✅ Optimize images before upload ✅ Limit charts per page (3-5 optimal) ✅ Use lazy loading for below-fold content ✅ Test on mobile devices ✅ Monitor Core Web Vitals ✅ Remove unused components ✅ Keep dependencies updated

Accessibility Best Practices

✅ Use semantic HTML ✅ Include alt text for images ✅ Sufficient color contrast ✅ Keyboard-navigable charts ✅ Screen reader tested ✅ Descriptive link text (not "click here") ✅ Video captions

Content Organization

Consistent naming — Post slugs follow convention ✅ Logical categories — Max 8-10 categories ✅ Meaningful tags — Specific, not generic ✅ Clear hierarchy — Related posts connect ✅ Featured strategically — Showcase best content


Summary

FeatureBenefitWhen to Use
MDX ContentWrite with power of ReactComplex articles with charts
Code HighlightingBeautiful code examplesTechnical tutorials
Rich ComponentsInteractive contentAll articles
Admin CMSEasy publishingNon-technical authors
SearchContent discoverabilityBlogs with 20+ posts
Categories/TagsOrganized browsingAny blog
SEOSearch engine rankingsAll content
PerformanceFast loadingAll users
Dark ModeComfortable readingAll time periods
RSSReader subscriptionsEngaged audience

Next Steps

  1. Fork the repository on GitHub
  2. Configure config/site.ts with your branding
  3. Set up environment variables (database, auth)
  4. Deploy to Vercel (1-click deployment)
  5. Create first blog post in Admin CMS
  6. Add your content in MDX format
  7. Optimize for SEO (title, description, keywords)
  8. Promote your blog (social media, RSS)
  9. Monitor analytics (Google Search Console, Vercel)
  10. Build an audience through consistency

You now have a complete, professional blog platform. 🚀

Go create amazing content! 📝✨