Project structure
The few files a theme owns and what each one does.
Read this when you open your new theme and wonder which files to touch.
Framework: TanStack Start
This page is written for TanStack Start, the default and currently supported framework. See what depends on the framework.
A new theme is a copy of Salla's Raed theme, so you start from a full storefront. These are the parts that matter.
__root.tsx
client.tsx
hydrate.tsx
router.tsx
routes.ts
routeTree.gen.ts
start.ts
twilight.json
vite.config.ts
package.json
The files you edit
| File | What it does |
|---|---|
vite.config.ts | Calls twilightReact() from @salla.sa/twilight-theme-engine/vite, which sets up rendering, routes and translations. You rarely change it. See the Vite plugin. |
app/start.ts | Registers the engine's request middleware (twilightMiddleware, earlyHintsMiddleware) so every request knows its store and visitor. |
app/client.tsx | The first script the browser runs. It calls bootClient from @salla.sa/twilight-theme-engine/boot, which loads app/hydrate.tsx; on the home and product pages it first waits for the main image to paint. See Performance. |
app/hydrate.tsx | Exports hydrate(), which hydrates the page with React's hydrateRoot. |
app/router.tsx | Creates the router and registers your replacements for home blocks and your hooks. |
app/routes/__root.tsx | The page shell: the <html> and <body>, the provider and your layout component. |
app/routes.ts | Lists your custom routes. A path here adds a page or replaces the engine's page for that path. See Routes and pages. |
app/components/, app/hooks/ | Your components, and the code that places UI into hook slots. See Layout and components and Hooks and slots. |
app/styles/ | Tailwind and SCSS. See Styling. |
locales/*.json | Your translation overrides, one file per language. |
twilight.json | The manifest: theme name, features, merchant settings and home blocks. See Settings. |
public/ | Static files served as they are. |
The files you do not edit
app/routeTree.gen.tsis generated.- Route files in
app/routes/that start with// @auto-generatedare generated from the engine's routes and are overwritten on the next build. Your own page files, the ones you point to fromapp/routes.ts, do not have that line and are yours. - The product listings (
/products,/search, a category, a tag, a brand's products) and/reviewsare not generated intoapp/routes/at all: the engine serves them from its own copy. A file of the same name without the// @auto-generatedline replaces the engine's.
Do not hand-edit generated files. They are rewritten on the next build.
Next
How it works: what happens between a customer's request and the page they see.