Return

Blog System Migration

ARCHITECTURE

Situation

The blog system used file-based routes with TSX components (/blog/[slug]/page.tsx). I had to rebuild the whole project to publish an article. It was inefficient, and most of all, inconvenient. Then, I realized markdown syntax could be applicable to this project, as many platforms support it.

Tasks

  • Database Integration: Leverage existing Neon PostgreSQL + Prisma infrastructure
  • Content Pipeline: Design markdown processing pipeline with consistent styling
  • Custom Components: Map markdown elements to Next.js optimized components (Image, Link)
  • Routing Strategy: Migrate from slug-based to ID-based URLs
  • Backward Compatibility: Maintain old URLs via redirects (SEO preservation)
  • Security & Performance: Implement URL sanitization, image optimization, lazy loading

Actions

Phase 1: Infrastructure Preparation

  1. Designed normalized schema: post table with many-to-many tag relations via junction table
  2. Created the @juun/db package: a framework-agnostic database client with namespace pattern
  3. Added caching layer using next/cache to reduce database queries by ~99%
  4. Structured both DB and cache APIs with consistent namespace pattern (post.get.all(), post.get.byId())

Phase 2: Content Pipeline Development

  1. Designed markdown processing pipeline using unified/remark/rehype ecosystem:
    • gray-matter: Extract frontmatter metadata
    • remark-parseremark-gfmremark-rehype: Markdown to HTML AST
    • rehype-raw: Parse raw HTML nodes
    • rehype-unwrap-images: Prevent hydration errors
    • rehype-react: Convert AST to React elements
  2. Implemented custom component mappings:
    • <a> → Next.js Link (client-side navigation) / secure external links
    • <img> → Next.js Image + auto-dimension detection + AspectRatio wrapper
    • <pre> → Custom CodeBlock with syntax highlighting (PrismJS)
  3. Added security layer: URL sanitization to prevent XSS attacks
  4. Integrated Prose typography component for consistent content styling

Phase 3: Migration Execution

  1. Changed routing from /blog/[slug] to /blog/[id] (simpler queries, no collision handling)
  2. Converted 7 blog articles from TSX to markdown, stored in PostgreSQL
  3. Implemented 7 permanent redirects (301) in next.config.ts for SEO preservation
  4. Updated breadcrumb component to handle numeric IDs intelligently
  5. Configured ISR with 1-hour revalidation for content freshness

Results

Technical Achievements

  • Content Management: Write markdown → publish instantly (no rebuild required)
  • Performance: Database queries reduced ~99% via caching, images optimized automatically
  • Developer Experience: Clean separation between content (markdown) and presentation (components)
  • Scalability: Architecture supports future features (search, filtering, admin interface)

Architecture Quality

  • Framework-agnostic database layer (reusable beyond Next.js)
  • Production-grade error handling (fallbacks for optimization failures)
  • AST-level transformations (transferable to any content processing)
  • Security hardening (URL sanitization, XSS prevention)

Skills Demonstrated

  • Data transformation pipelines (input → process → output architecture)
  • AST manipulation (unified/remark/rehype ecosystem)
  • Multi-library integration (coordinating 8+ libraries coherently)
  • Migration considerations (backward compatibility)

Challenges

  • Image optimization required auto-dimension detection with fallback strategies
  • Hydration errors needed rehype-unwrap-images plugin to prevent React mismatches
  • Balancing automatic optimization with markdown authoring flexibility