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
- Professional Blog Platform Overview
- MDX: Markdown + React Power
- Rich Text Editing & Components
- Smart Content Management
- Admin CMS Dashboard
- Search & Discovery
- SEO & Social Sharing
- Performance & Speed
- Design & Theming
- Configuration & Personalization
- 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:
| Aspect | Charted Data | Traditional Blogs |
|---|---|---|
| Content Format | MDX (Markdown + React) | Basic Markdown/HTML |
| Interactive Content | Native charts, components | Requires plugins/embeds |
| Performance | Sub-second loads | 2-5 second typical |
| SEO | Server-rendered, optimized | Plugin-dependent |
| Customization | Code-based, no limits | Theme limited |
| Security | Modern auth (no passwords) | Password vulnerable |
| Ownership | Full source code | Platform dependent |
| Cost | Only hosting (free tier available) | $0-300/month |
| Scalability | CDN-ready, serverless | Limited 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
| Feature | Markdown | MDX |
|---|---|---|
| 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
export function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}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
| Feature | Free | Pro | Enterprise |
|---|---|---|---|
| Posts | 50 | Unlimited | Unlimited |
| Users | 1 | 5 | Unlimited |
| Storage | 1 GB | 100 GB | 1 TB |
| Support | Priority | 24/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
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 -->

<!-- ✅ DO: Descriptive alt text -->

<!-- ✅ 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 colorsecondary— Gray/secondarydestructive— Red warningoutline— 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 HereWhat's in Frontmatter
| Field | Purpose | Example |
|---|---|---|
| title | Article title | "Advanced React Patterns" |
| description | SEO description | "Learn advanced React techniques..." |
| date | Publication date | "2024-01-15" |
| author | Content creator | "Sarah Chen" |
| category | Topic category | "Technology" |
| tags | Micro-categories | ["React", "JavaScript"] |
| featured | Homepage highlight | true or false |
| draft | Publishing status | true (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
-
Configure Admin Email in
.env:ADMIN_EMAIL="your@email.com" -
Visit
/admin— Redirects to login -
Sign in with email — Passwordless authentication:
Enter your email → Receive verification link → Click link → Logged in -
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
- Find post in recent list
- Click [Edit] button
- Make changes
- Click [Update]
From Blog
- View published post
- If logged in, [Edit] button appears
- Click to edit in CMS
- Make changes
- 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
| Aspect | Category | Tags |
|---|---|---|
| Number per post | 1 only | Multiple |
| Granularity | Broad | Fine-grained |
| Use case | Topic grouping | Detailed classification |
| Examples | Technology, Design | React, JavaScript, Hooks |
| Navigation | Browse by category | Search/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 nameJSON-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 deviceResults
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 removedBenefits
✅ 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-scalesPerformance 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 startNavigation 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
| Feature | Benefit | When to Use |
|---|---|---|
| MDX Content | Write with power of React | Complex articles with charts |
| Code Highlighting | Beautiful code examples | Technical tutorials |
| Rich Components | Interactive content | All articles |
| Admin CMS | Easy publishing | Non-technical authors |
| Search | Content discoverability | Blogs with 20+ posts |
| Categories/Tags | Organized browsing | Any blog |
| SEO | Search engine rankings | All content |
| Performance | Fast loading | All users |
| Dark Mode | Comfortable reading | All time periods |
| RSS | Reader subscriptions | Engaged audience |
Next Steps
- Fork the repository on GitHub
- Configure
config/site.tswith your branding - Set up environment variables (database, auth)
- Deploy to Vercel (1-click deployment)
- Create first blog post in Admin CMS
- Add your content in MDX format
- Optimize for SEO (title, description, keywords)
- Promote your blog (social media, RSS)
- Monitor analytics (Google Search Console, Vercel)
- Build an audience through consistency
You now have a complete, professional blog platform. 🚀
Go create amazing content! 📝✨