CommitView on GitHub →

Content System Refactor - Docs/Posts Separation

By Claude Sonnet 4.5  ·  January 17, 2026
Project: jaygriffFeature: Navigator
🏷️ Tags:refactorroutingmetadata

Complete refactor of content infrastructure: separated docs from posts with type-based routing, added comprehensive metadata system, improved Navigator UX, and created ContentHeader component.

This commit represents a major refactor of how content is organized, routed, and displayed on the site. What started as a simple Navigator tweak evolved into a complete rethinking of the content system architecture.

Summary of Changes

  • Separated documentation from blog posts using type-based routing (/docs/ vs /posts/)
  • Removed URL paths from Navigator search results for cleaner UX
  • Added comprehensive metadata system with author, feature, and type fields
  • Created ContentHeader component for consistent metadata display across all content
  • Updated Container component with proper vertical spacing
  • Created multiple documentation pages explaining the system

The Problem

1. Navigator Showed Too Much Implementation Detail

The Navigator was displaying full URL paths like /posts/navigator-feature in search results. This violated a core UX principle: users don't care about URL structures. They just want to navigate to content. As the saying goes, "only nerds care about URLs."

2. Docs Were Masquerading as Posts

Technical documentation was being served at /posts/ URLs, which was misleading. Documentation isn't really a "post" - it's reference material. The URL structure didn't reflect the content type.

3. No Consistent Metadata Display

Content files had metadata but no standard way to display it. Important context like author, feature, and project associations wasn't visible to readers.

The Solution

1. Type-Based Content Routing

Added a type field to the PostMeta interface:

.ts
export interface PostMeta {
  title: string;
  slug: string;
  date: string;
  description: string;
  type?: 'post' | 'doc'; // Default is 'post'
  // ...other fields
}

Files with type: 'doc' are now served at /docs/[slug], while regular posts (no type specified) remain at /posts/[slug]. This keeps the authoring simple - most content doesn't need to specify a type.

2. Parallel Route Handlers

Created separate but parallel routing infrastructure:

  • src/app/posts/[slug]/page.tsx - Renders posts
  • src/app/docs/[slug]/page.tsx - Renders docs
  • src/app/api/posts/[slug]/route.ts - API for post lookups
  • src/app/api/docs/[slug]/route.ts - API for doc lookups

Both work identically - they fetch the filename via API, dynamically import the TSX file, and render it. The only difference is which type they filter for.

3. Enhanced Metadata System

Extended PostMeta with new fields for better organization:

.ts
export interface PostMeta {
  // ...existing fields
  author?: string;      // "Jay Griffin", "Claude Sonnet 4.5"
  feature?: string;     // "Navigator", "Theme Editor"
  projectId?: string;   // "jaygriff", "locus"
  type?: 'post' | 'doc';
}

Removed relatedPosts field as it was redundant - you can already filter by feature, project, topics, and tags to find related content.

4. ContentHeader Component

Created a standardized header component (src/components/ContentHeader.tsx) that displays:

  • Title (large, prominent)
  • Author and publication date (traditional text format)
  • Last updated date (when applicable)
  • Metadata badges (docs badge, feature, project) as pill-style tags
  • Description (larger, readable format)

This gives every page a Notion-like feel with clear, consistent metadata presentation.

5. Cleaned Up Navigator UX

Removed URL path display from Navigator search results. Now users just see:

  • Title
  • Description

No more /posts/navigator-feature cluttering the interface. Users don't need to understand our URL scheme to navigate the site.

Files Changed

New Files

  • src/app/docs/[slug]/page.tsx - Doc page handler
  • src/app/api/docs/[slug]/route.ts - Doc API endpoint
  • src/components/ContentHeader.tsx - Metadata display component
  • src/posts/docs-routing.tsx - Documentation explaining the routing system
  • src/posts/commit-2026-01-17-content-system.tsx - This commit doc

Modified Files

  • src/types/post.ts - Added author, feature, type fields; removed relatedPosts
  • src/lib/posts.ts - Added getAllDocs() and getDocBySlug() functions
  • src/lib/routes.ts - Updated to handle both /posts/ and /docs/ paths
  • src/app/sitemap.ts - Generate sitemap entries for both posts and docs
  • src/app/posts/[slug]/page.tsx - Integrated ContentHeader
  • src/components/Navigator.tsx - Removed URL path display
  • src/components/Primitives.tsx - Updated Container margins for better spacing
  • src/posts/navigator-feature.tsx - Updated metadata with type, author, feature
  • src/posts/site-summary.tsx - Converted to doc, rewrote content, updated metadata
  • src/posts/programs-not-documents.tsx - Updated metadata

Technical Notes

Code Duplication

The posts and docs page components are nearly identical - they just call different APIs and use different filter functions. This could be refactored into a shared component, but for now the duplication is minimal and keeps things explicit. Each route handler is ~60 lines and easy to understand.

Default Behavior

Posts are "first-class" - they don't need to specify type: 'post'. Only docs need the explicit type: 'doc' marker. This keeps most metadata blocks clean.

Backwards Compatibility

Old content without the new metadata fields continues to work. The system gracefully handles missing author, feature, or type information.

Future Possibilities

  • Filter Navigator results by type, feature, or project
  • Create dedicated feature or project index pages that list all related content
  • Add more content types beyond posts and docs (e.g., projects, demos)
  • Refactor page handlers to reduce duplication
  • Generate commit documentation automatically from git history

Why This Matters

This refactor establishes a scalable content architecture that:

  • Separates concerns properly (docs vs posts have different purposes)
  • Hides implementation details from users (no more URL clutter)
  • Provides rich metadata without complexity
  • Creates a foundation for feature-based organization
  • Maintains the "programs not documents" philosophy while improving UX

The site now has a clear content model that can grow without becoming chaotic. Each piece of content knows what it is, who wrote it, what feature it documents, and where it belongs.