## Table of Contents
- [Overview](#overview)
- [Features](#features)
- [Tech Stack](#tech-stack)
- [Quickstart](#quickstart)
- [Core Modules](#core-modules)
- [Environment Variables](#environment-variables)
- [Scripts](#scripts)
- [Routes & APIs](#routes--apis)
- [Developer Notes](#developer-notes)
## Overview
- Frontend uses Next.js App Router with Tailwind + shadcn, and fumadocs layout pieces for navigation, pagination, and search.
- Content is managed by Payload CMS (`payload.config.ts`), supporting rich text, tags, cover images, and publish states.
_- Authentication via better-auth (Google/GitHub), sessions and comments stored in Postgres through Drizzle ORM._
- Comments are powered by `@fuma-comment`, and the site generates both `/rss.xml` feeds and `/api/search` indexes.
## Features
- Post management: Payload admin (`/admin`) creates drafts/published posts with cover image, tags, and scheduled publish time.
- Blog UX: paginated lists, tag hub, rich post detail rendering, share button, one-click copy link.
- Social & interaction: Google/GitHub login, better-auth session management, Fuma Comment stored locally.
- Enhancements: RSS feed, on-the-fly search index, automatic Open Graph/OG banners, sitemap via `next-sitemap`.
- Email template: `emails/newsletter-welcome.tsx` using React Email + Tailwind, ready for Resend.
- Ops-friendly: `.env` validation, `start-database.sh` to boot local Postgres, unified Drizzle/Payload scripts for schema.
## Tech Stack
| Area |
Choice |
Notes |
| Framework |
Next.js 15 (App Router) |
Server Components with hybrid static/dynamic rendering |
| UI |
Tailwind CSS 4 + shadcn + fumadocs-ui |
Navigation, pagination, sections, theming |
| Content |
Payload CMS |
Posts/Users/Media collections, Lexical rich text |
| Data |
PostgreSQL + Drizzle ORM |
Auth and comments tables (prefix blog_*) |
| Auth |
better-auth + OAuth (Google/GitHub) |
Social login, sessions, extra role field |
| Email |
Resend + React Email |
Welcome template, Tailwind styling |
## Quickstart
1) Install toolchain
- Node 20+ recommended, use `pnpm` (locked by `pnpm-lock.yaml`).
2) Set environment variables
- Copy `.env.example` to `.env`; fill `DATABASE_URL`, `PAYLOAD_SECRET`, `BETTER_AUTH_SECRET`, and OAuth keys if needed.
3) Start Postgres locally
- `./start-database.sh` (Docker/Podman) or your own Postgres instance.
4) Install deps and build schema
- `pnpm install`
- `pnpm db:generate && pnpm db:migrate` (Drizzle auth/comments tables)
- `pnpm payload:migrate` (Payload CMS tables)
5) Run dev server
- `pnpm dev` (default :3000; Payload Admin `/admin`, blog `/`).
6) Optional extras
- `pnpm payload:generate` (types)
- `pnpm email:dev -p 3001` (preview email template).
> In development, Payload pre-fills `admin@example.com` / `admin123` on the login form.
## Core Modules
- Content model: `payload.config.ts` defines Posts/Users/Media with cover uploads, tag arrays, publish time, and status.
- Data fetching: `src/lib/payload-posts.ts` wraps post queries, tag stats, pagination, and slug helpers for pages.
- Pages & layout: `src/app/(main)` hosts the site; `_components` includes Hero, CTA, and post list UI.
- Auth & comments: `src/server/auth` (better-auth + Drizzle) and `src/server/comments` storing into `blog_comments` tables.
- Search & feed: `src/app/(main)/api/search/route.ts` builds indexes; `src/app/(main)/rss.xml/route.ts` emits Atom/RSS.
- Email: `emails/newsletter-welcome.tsx` React Email template that accepts a posts array.
Project structure (excerpt):
```text
src/
├── app/
│ ├── (main)/(home)/page.tsx # Home: hero, recent posts, CTA
│ ├── (main)/(home)/posts/[slug]/page.tsx # Post detail + comments + share
│ ├── (main)/(home)/posts/page.tsx # Paginated posts list
│ ├── (main)/(home)/tags/page.tsx # Tag hub
│ ├── (main)/api/search/route.ts # Search index API
│ ├── (main)/rss.xml/route.ts # Atom/RSS feed
│ └── (payload)/admin/... # Payload CMS admin
├── lib/ # Data + utilities (payload-posts, metadata, auth-client)
├── server/ # better-auth + Drizzle schema + comment storage
└── emails/ # React Email templates
```
## Environment Variables