A personal blog website migrated from Gatsby v2 to a modern Next.js 14+ and FastAPI architecture. The application features blog posts with markdown content, tag-based filtering, and responsive design, optimized for deployment on Vercel.
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Vercel β
βββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββββββββββ ββββββββββββββββββββ β
β β Next.js βββββΊβ FastAPI β β
β β Frontend β β Backend β β
β β β β β β
β β - React Pages β β - REST API β β
β β - Components β β - Markdown β β
β β - Styling β β - Images β β
β ββββββββββββββββββββ ββββββββββββββββββββ β
β β β β
β β β β
β βΌ βΌ β
β Static Assets Blog Content β
β (images, logos) (markdown files) β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
- β Markdown-based blog posts with frontmatter
- β Image support within posts
- β Tag-based categorization
- β Post excerpts and summaries
- β Fast page loads with SSG
- β Responsive mobile-first design
- β Smooth navigation
- β Clean, modern UI
- β TypeScript for type safety
- β Hot reload in development
- β API documentation (FastAPI Swagger)
- β Easy content updates
- β Static site generation
- β Incremental static regeneration
- β Image optimization
- β Metadata and Open Graph tags
willcapio-old/
β
βββ frontend/ # Next.js Application
β βββ app/ # App Router
β β βββ layout.tsx # Root layout with nav/footer
β β βββ page.tsx # Homepage (blog listing)
β β βββ page.module.css
β β βββ globals.css # Global styles
β β β
β β βββ blog/
β β β βββ [slug]/
β β β βββ page.tsx # Individual blog post
β β β βββ page.module.css
β β β
β β βββ tags/
β β β βββ page.tsx # All tags listing
β β β βββ page.module.css
β β β βββ [tag]/
β β β βββ page.tsx # Posts by tag
β β β
β β βββ about/
β β β βββ page.tsx
β β β βββ page.module.css
β β β
β β βββ code/
β β β βββ page.tsx
β β β βββ page.module.css
β β β
β β βββ whereiswill/
β β βββ page.tsx
β β βββ page.module.css
β β
β βββ components/ # React Components
β β βββ NavBar.tsx # Sticky navigation
β β βββ NavBar.module.css
β β βββ Footer.tsx # Footer
β β βββ Footer.module.css
β β βββ Header.tsx # Page headers
β β βββ Header.module.css
β β βββ PostList.tsx # Blog post card
β β βββ PostList.module.css
β β βββ TagsBlock.tsx # Tag display
β β βββ TagsBlock.module.css
β β
β βββ lib/ # Utilities
β β βββ api.ts # API client functions
β β βββ theme.ts # Theme configuration
β β
β βββ public/ # Static assets
β β βββ logo/ # Logos and favicons
β β βββ robots.txt
β β
β βββ package.json
β βββ tsconfig.json
β βββ next.config.ts
β βββ .env.local # Environment variables
β βββ .env.example
β
βββ backend/ # FastAPI Application
β βββ main.py # API server
β βββ requirements.txt # Python dependencies
β β
β βββ content/ # Blog content
β βββ posts/
β βββ 2018-10-08/
β β βββ index.md # Post content
β β βββ *.jpg # Post images
β βββ 2018-10-09/
β βββ .../
β
βββ vercel.json # Vercel deployment config
β
βββ start-dev.sh # Dev startup script
βββ test-api.sh # API test script
β
βββ README-MIGRATION.md # Migration documentation
βββ DEPLOYMENT.md # Deployment guide
βββ MIGRATION-SUMMARY.md # What was changed
βββ QUICK-START.md # Quick start guide
βββ PROJECT-OVERVIEW.md # This file
| Endpoint | Method | Description |
|---|---|---|
/ |
GET | API info |
/api/posts |
GET | List all blog posts |
/api/posts/{slug} |
GET | Get single post by slug |
/api/tags |
GET | Get all unique tags |
/api/posts/tag/{tag} |
GET | Get posts by tag |
/api/site-config |
GET | Get site configuration |
/images/{slug}/{filename} |
GET | Serve post images |
/docs |
GET | API documentation (Swagger) |
| Route | Description |
|---|---|
/ |
Homepage with blog post listing |
/blog/{slug} |
Individual blog post |
/tags |
All tags listing |
/tags/{tag} |
Posts filtered by tag |
/about |
About page |
/code |
Code projects page |
/whereiswill |
Travel log page |
- Framework: Next.js 14+ (App Router)
- Language: TypeScript
- Styling: CSS Modules
- UI Library: React 18
- Fonts: Google Fonts (Open Sans, Candal)
- Image Optimization: Next.js Image component
- Framework: FastAPI
- Language: Python 3.x
- Markdown: python-markdown
- Frontmatter: python-frontmatter
- Image Processing: Pillow
- ASGI Server: Uvicorn
- Platform: Vercel
- CDN: Vercel Edge Network
- SSL: Automatic HTTPS
- Package Manager: npm (frontend), pip (backend)
- Linting: ESLint (frontend)
- Type Checking: TypeScript
- Version Control: Git
Primary Blue: #3498db
Dark Blue: #284187
Light Blue: #3e5fbc
Text: #333438
Light Text: #7f8184
Background: #fff- Headings: Candal (Google Font)
- Body: Open Sans (Google Font)
- xs: 400px
- s: 600px
- m: 900px
- l: 1200px
Blog posts are markdown files with YAML frontmatter:
---
title: "Post Title"
date: "2024-12-19"
path: "/post-slug"
tags: ["tag1", "tag2"]
cover: "./cover-image.jpg"
published: true
---
Post content in markdown...
# Development
./start-dev.sh # Start both servers
./test-api.sh # Test API
# Backend
cd backend
source venv/bin/activate
uvicorn main:app --reload # Start API server
# Frontend
cd frontend
npm run dev # Start Next.js
npm run build # Build for production
npm run start # Run production build
# Deployment
vercel # Deploy to preview
vercel --prod # Deploy to productionExpected metrics:
- First Contentful Paint: < 1.5s
- Time to Interactive: < 3.5s
- Lighthouse Score: 90+
- Bundle Size: Optimized with code splitting
NEXT_PUBLIC_API_URL=http://localhost:8000NEXT_PUBLIC_API_URL=https://your-domain.vercel.appThe architecture supports:
- β Hundreds of blog posts
- β Multiple concurrent users
- β Global CDN distribution
- β Easy content updates
- β Future enhancements (comments, search, etc.)
- Content Updates: Edit markdown in
backend/content/posts/ - Component Changes: Edit React components in
frontend/components/ - Styling: Update CSS Modules
- API Changes: Modify
backend/main.py - Test Locally: Run both servers
- Deploy: Push to Git or use Vercel CLI
Add a new blog post:
mkdir backend/content/posts/YYYY-MM-DD
cd backend/content/posts/YYYY-MM-DD
# Create index.md with frontmatter
# Add imagesUpdate styling:
# Edit component CSS modules in frontend/components/
# Or edit global styles in frontend/app/globals.cssDebug issues:
# Check backend logs
cd backend && source venv/bin/activate && uvicorn main:app --reload --log-level debug
# Check frontend logs
cd frontend && npm run dev
# Build locally
cd frontend && npm run buildPotential additions:
- Search functionality
- Comment system (Giscus/Utterances)
- RSS feed
- Newsletter integration
- Dark mode
- Reading time estimates
- Related posts
- Table of contents
- Code syntax highlighting improvements
- Analytics dashboard
MIT
Author: Will Cap
Twitter: @thinkocapo
GitHub: thinkocapo
Website: WillCap.io