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

FileWhat it does
vite.config.tsCalls 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.tsRegisters the engine's request middleware (twilightMiddleware, earlyHintsMiddleware) so every request knows its store and visitor.
app/client.tsxThe 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.tsxExports hydrate(), which hydrates the page with React's hydrateRoot.
app/router.tsxCreates the router and registers your replacements for home blocks and your hooks.
app/routes/__root.tsxThe page shell: the <html> and <body>, the provider and your layout component.
app/routes.tsLists 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/*.jsonYour translation overrides, one file per language.
twilight.jsonThe 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.ts is generated.
  • Route files in app/routes/ that start with // @auto-generated are generated from the engine's routes and are overwritten on the next build. Your own page files, the ones you point to from app/routes.ts, do not have that line and are yours.
  • The product listings (/products, /search, a category, a tag, a brand's products) and /reviews are not generated into app/routes/ at all: the engine serves them from its own copy. A file of the same name without the // @auto-generated line 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.

On this page