- New post: 不是所有眼淚,都該被濃縮成重點 - CLAUDE.md: add deployment workflow and content submodule instructions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.2 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
npm run dev- Start dev server (runs Contentlayer2 + Next.js with Turbopack concurrently)npm run build- Full production build: sync-assets → contentlayer2 build → next build → pagefind indexing → copy pagefind to publicnpm run lint- ESLint vianext lintnpm run sync-assets- Copycontent/assets/topublic/assets/(also runs automatically before build)
No test framework is configured.
Architecture
Content pipeline: content/ git submodule (MDX/Markdown) → Contentlayer2 (contentlayer.config.ts) → typed Post/Page objects imported from contentlayer2/generated → consumed by pages and lib/posts.ts helpers.
Routing (App Router):
/— Home page with latest posts/blog— Blog index with search, sort, pagination/blog/[slug]— Single post with TOC, reading progress, prev/next navigation/pages/[slug]— Static content pages (fromcontent/pages/)/tags,/tags/[tag]— Tag index and per-tag post lists/api/og— Dynamic OG image generation (@vercel/og)/feed.xml— RSS feed (route handler)
Key data flow:
lib/config.ts—siteConfigobject built fromNEXT_PUBLIC_*env vars (all site metadata, social links, accent colors, pagination)lib/posts.ts— Query helpers:getAllPostsSorted(),getPostBySlug(),getPageBySlug(),getAllTagsWithCount(),getRelatedPosts(),getPostNeighbors()lib/mastodon.ts— Mastodon API client for sidebar feed widgetlib/rehype-callouts.ts— Custom rehype plugin for GitHub-style[!NOTE]callout blocks
Layout hierarchy: app/layout.tsx (fonts, theme CSS vars, ThemeProvider, JSON-LD) → components/layout-shell.tsx (header, sidebar, footer, back-to-top) → page content.
Markdown processing (configured in contentlayer.config.ts):
- Remark: GFM
- Rehype: callouts → pretty-code (shiki, dual theme) → slug → autolink-headings → image path rewriter (
../assets/→/assets/) - Image paths in markdown are relative (
../assets/foo.jpg); a rehype plugin rewrites them to/assets/foo.jpgat build time
Styling
- Tailwind CSS v3 with
darkMode: 'class'(toggled bynext-themes) - Accent color system via CSS variables set in
app/layout.tsxfrom env vars:--color-accent,--color-accent-soft,--color-accent-text-light,--color-accent-text-dark - Tailwind extends these as
accent,accent-soft,accent-textLight,accent-textDarkintailwind.config.cjs - Typography plugin (
@tailwindcss/typography) with customprose/prose-darkoverrides - English headings use Playfair Display serif (
--font-serif-eng); body uses Inter + CJK fallback stack - Config files use CommonJS (
.cjs):tailwind.config.cjs,postcss.config.cjs
Content Submodule
The content/ directory is a git submodule pointing to a separate personal-blog repository. It contains posts/, pages/, and assets/. After pulling new content, run npm run sync-assets to update public/assets/. The build script does this automatically.
Path Aliases
@/* maps to project root (configured in tsconfig.json). Contentlayer generated types at .contentlayer/generated are aliased as contentlayer2/generated.
Deployment
Push to main on the Gitea remote (git.gbanyan.net) triggers CI/CD automatically (server-side hook). No Dockerfile or workflow file in this repo.
Content-only update (new/edited posts) — both steps are required to trigger deploy:
- Commit and push inside
content/submodule:git -C content add . && git -C content commit -m "..." && git -C content push - Update main repo submodule pointer and push:
git add content && git commit -m "Update content submodule" && git push
Pushing only to content/ (personal-blog) does NOT trigger deployment. The main repo must also be pushed because CI/CD is bound to blog-nextjs, not personal-blog.
Code changes: Commit and push in the main repo as usual — git push to main triggers the pipeline.
Language
The site's default locale is zh-TW. UI text, labels, and timestamps are in Traditional Chinese.