Project Structure

What each directory owns, and where to make changes

Last updated October 21, 2026


This page is a map. When you cannot find something, look here first, then read the code.

Directory map

text
src/
├── routes/              File routes. `{-$locale}` is the optional locale prefix
├── config/              Site configuration
│   ├── website.ts       Global switches: name, logo, module and feature flags
│   ├── navigation.ts    Menu types and filtering rules
│   ├── navbar-config.ts Navbar
│   ├── footer-config.ts Footer
│   └── settings.ts      Dashboard sections
├── components/
│   ├── sections/        Reusable content blocks (Hero / Features / Pricing…)
│   ├── marketing/       Page-level assembly (LandingPage / MarketingLayout / Navbar)
│   ├── docs/            Docs layout, sidebar, search
│   ├── dashboard/       Dashboard shell
│   ├── layout/          Cross-page pieces (Logo / locale switcher / user menu)
│   ├── blog/  auth/  contact/  mdx/  theme/  icons/
│   └── ui/              shadcn upstream originals, never edited locally
├── auth/                Authentication (Better Auth)
├── cache/               KV cache and rate limiting
├── contact/             Contact form delivery
├── db/                  Drizzle schema and migrations
├── env/                 Two-layer env validation
├── lib/                 Pure logic: locale, seo, module-access, rate-limit…
├── locale/              Paraglide output and middleware
├── mail/  newsletter/  notification/  payment/  storage/
│                        Service modules: provider registry + interface
├── styles/              globals.css (design tokens), mdx.css
├── server.ts            Custom server entry (CSP nonce, env injection)
└── router.tsx           Router instance

content/                 Docs / blog / changelog / legal (Markdown)
messages/                zh.json / en.json UI copy
public/docs/screenshots/ UI screenshots referenced from docs
scripts/                 Build and validation scripts
tests/                   unit / components / workers
e2e/                     Playwright

Where to change things

Want to changeGo to
Site name, logo, module switchessrc/config/website.ts
Home / about / pricing copyThe route component, e.g. src/routes/{-$locale}/index.tsx
Button labels and UI copymessages/zh.json, messages/en.json
Navbar and footer linkssrc/config/navbar-config.ts, footer-config.ts
Docs contentcontent/docs/*.md (Chinese uses .zh)
Colors, fonts, radiisrc/styles/globals.css, rules in Design System
Add a pageCreate a file under src/routes/; the router picks it up
Add an API routesrc/routes/api/<name>/$ or src/routes/api/<name>.ts
Change a tablesrc/db/schema.ts, then pnpm db:generate
Add a service moduleMirror src/mail/: types.ts + provider + index.ts
Add a UI screenshot to docsPut the image in public/docs/screenshots/, reference it as ![alt](/docs/screenshots/x.png "caption")

Two boundaries that are easy to confuse

`components/sections/` vs `components/marketing/`

  • sections/ holds reusable content blocks: a Hero, a set of Features. Given props,

they render; they do not care which page they are on.

  • marketing/ holds page-level assembly: LandingPage composes sections in order,

MarketingLayout owns the navbar and footer.

Route components vs `config/website.ts`

  • website.ts is global switches and identity: what the site is called, which modules

are on.

  • Page copy lives in the route component, right next to the block that renders it.

Always call m.*() during render, never at module top level: Paraglide reads the current locale at call time, so a top-level constant freezes the language of the first request for every later one (SSR renders the whole page in the wrong language, the client then derives another language from the URL, and hydration mismatches).

Generated files — do not edit

PathGenerated by
src/routeTree.gen.tsTanStack Router plugin
src/locale/paraglide/**pnpm locale:compile
.content-collections/generated/**pnpm content:build

All three are rewritten at build time; manual edits are overwritten.

References

What's next