Config System

FeatureCentralized configurationSafer customization

The template centralizes most customization across a small set of config and content files.

This system exists so product teams can change identity, content, translations, and environment-driven defaults without rewriting route components for every adjustment.

Why this matters early

The config layer is one of the safest places to start customizing the project. It works closely with First Customization and Customize Branding.

Why it exists

The config layer exists to make the template easier to adapt without forcing users to rewrite route code, duplicate strings, or scatter product decisions across the app.

In practice, it separates:

  • identity
  • marketing and legal content
  • i18n labels
  • environment-driven defaults

Centralized edits

Important product defaults live in predictable files instead of being scattered across routes and components.

Lower-risk customization

Teams can adapt branding and content quickly without changing deeper application logic too early.

Cleaner route files

Pages stay focused on composition because product decisions are modeled elsewhere.

Easier maintenance

Configuration changes remain easy to find, review, and update as the product grows.

Config surfaces

src/config/site.ts

Use this file for brand-level metadata and contact details.

Examples:

  • site name
  • description
  • support email
  • Resend sender
  • logo paths
  • error image paths

This file defines the product identity seen across metadata, support surfaces, and visual assets.

content/landing/*.json

Use these files for landing-page structure and content, one per locale (en.json, es.json, cn.json).

Examples:

  • hero copy
  • documentation cards
  • testimonials
  • FAQ
  • pricing plans
  • CTA and footer content

These JSON files are validated by Zod schemas in src/content/schemas.ts and loaded by src/content/loaders.ts. This is usually the first place to update when the public site still feels like a starter template.

content/legal/*.json

Use these files for legal page content per locale.

Examples:

  • terms of service
  • privacy policy

Legal content follows the same locale-based JSON pattern as landing content.

messages/<locale>/*.json

Use these directories for i18n UI labels. Each locale directory contains separate JSON files for different areas of the app.

Examples:

  • system.json — global UI strings
  • navbar.json — navigation labels
  • dashboard.json — dashboard section labels and sidebar copy
  • auth.json — authentication flow copy

When you change labels referenced by components, make sure the matching keys exist in all supported locales.

src/env.js

Use this file for environment-driven integration defaults validated with Zod.

Examples:

  • enabled auth providers
  • Stripe price and coupon IDs
  • email API keys (Resend)

This file captures the default assumptions the app makes about auth, billing, and email behavior through environment variables.

How to think about the config layer

Use config when the answer to "what is changing?" is one of these:

  • the product name or brand
  • the marketing or legal content
  • the translated UI labels
  • the environment-driven integration defaults

Do not use config for behavior that is deeply procedural or domain-driven. That belongs in src/server/services, routers, or route files depending on the concern.

Good boundary

Use config for declarative product decisions. Use services, routers, and route files for procedural behavior.

Design goal

The config layer exists so buyers and maintainers can adapt the template without rewriting route components or server logic for every change.