Site Configuration
Single-file branding: names, contact, navigation, categories, locales, currencies, and theme.
Almost everything that makes the storefront yours — the store name, tagline, contact
details, header and footer navigation, the product categories, the currencies and
locales a shopper can switch into, and the brand color presets — lives in a single
file: src/config/site.ts. Components read from this config instead of hardcoding
copy, so rebranding the boilerplate is mostly an exercise in editing this one file.
This page reflects the values shipped in the boilerplate (the fictional "Acme Store"). Every field name below matches the source exactly — change the values, keep the keys.
What the file exports
src/config/site.ts exports two runtime values plus several TypeScript interfaces
that describe their shape.
| Export | Kind | Purpose |
|---|---|---|
siteConfig | const object | Store identity, contact, navigation, currencies, locales, and theme presets. |
productCategories | ProductCategory[] | The catalog's top-level categories. |
CurrencyConfig | interface | Shape of the base store currency (code, locale). |
CurrencyOption | interface | A switchable currency (code, locale, rate, label). |
LocaleOption | interface | A switchable UI locale (code, label). |
ThemePreset | interface | A brand color scheme as HSL triplets. |
ProductCategory | interface | Shape of one entry in productCategories. |
siteConfig is declared as const, so its values are readonly and their literal
types flow through the rest of the app — TypeScript will flag a typo in a category
slug or a currency code at build time.
siteConfig
Identity
export const siteConfig = {
name: "Acme Store",
tagline: "Everything you need to launch your online store",
description:
"A modular and scalable ecommerce boilerplate built with Next.js, TypeScript, Tailwind CSS, shadcn/ui, and Firebase.",
url: "https://example.com",
// ...
} as const;| Field | Type | Shipped value | Notes |
|---|---|---|---|
name | string | "Acme Store" | Store name shown in the header, footer, page titles, and emails. |
tagline | string | "Everything you need to launch your online store" | Short marketing line. |
description | string | "A modular and scalable ecommerce boilerplate…" | Long description, used for SEO metadata. |
url | string | "https://example.com" | Canonical site URL. Point this at your production domain. |
Contact and social links
contact: {
email: "hello@example.com",
phone: "+1 (555) 000-0000",
address: "123 Commerce St, Suite 100, Springfield, USA",
},
links: {
linkedin: "https://www.linkedin.com/company/your-company",
instagram: "https://www.instagram.com/your-company",
},| Field | Shipped value |
|---|---|
contact.email | "hello@example.com" |
contact.phone | "+1 (555) 000-0000" |
contact.address | "123 Commerce St, Suite 100, Springfield, USA" |
links.linkedin | "https://www.linkedin.com/company/your-company" |
links.instagram | "https://www.instagram.com/your-company" |
Navigation
Two navigation arrays drive the header and footer. Each item is a { label, href }
pair — internal routes are plain paths and hash links (/#contact) jump to a section.
mainNav: [
{ label: "Products", href: "/products" },
{ label: "About", href: "/about" },
{ label: "Contact", href: "/#contact" },
],
legalNav: [
{ label: "Privacy Policy", href: "/privacy-policy" },
{ label: "Terms of Service", href: "/terms-of-service" },
{ label: "Cookie Policy", href: "/cookie-policy" },
],| Array | Rendered in | Items (label → href) |
|---|---|---|
mainNav | Primary header/footer navigation | Products → /products, About → /about, Contact → /#contact |
legalNav | Footer legal links | Privacy Policy → /privacy-policy, Terms of Service → /terms-of-service, Cookie Policy → /cookie-policy |
To add or reorder links, edit these arrays. Make sure any internal href points at a
route that actually exists in the app.
Currencies
The store has one base currency (currency) and a list of currencies the shopper
can switch into (currencies). Prices are stored in the base currency and converted
for display by formatMoney in src/lib/money.ts.
currency: { code: "USD", locale: "en-US" } satisfies CurrencyConfig,
currencies: [
{ code: "USD", locale: "en-US", rate: 1, label: "USD ($)" },
{ code: "EUR", locale: "de-DE", rate: 0.92, label: "EUR (€)" },
{ code: "GBP", locale: "en-GB", rate: 0.79, label: "GBP (£)" },
{ code: "JPY", locale: "ja-JP", rate: 155, label: "JPY (¥)" },
] satisfies CurrencyOption[],currency(CurrencyConfig) is the single source of truth for how prices render across the storefront, admin, and emails:codeis an ISO 4217 code andlocaleis a BCP 47 locale that drives number grouping and the currency symbol.currencies(CurrencyOption[]) lists the switchable options. Each addsrate— the multiplier from the base currency — andlabel, the short text shown in the switcher.
The first entry in currencies must be the base currency with rate: 1 and must
match siteConfig.currency. The shipped rates (0.92, 0.79, 155) are static demo
values — wire a live FX feed before relying on them in production.
See Currency & pricing for how conversion and formatting work end to end.
Locales
defaultLocale: "en",
locales: [
{ code: "en", label: "English" },
{ code: "es", label: "Español" },
] satisfies LocaleOption[],| Field | Type | Shipped value |
|---|---|---|
defaultLocale | string | "en" |
locales | LocaleOption[] | en → English, es → Español |
Each LocaleOption has a code (a BCP 47 code that must also be registered in the
src/lib/i18n dictionaries) and a native label for the switcher. The first entry is
the default. Adding a language is a data change — drop in src/lib/i18n/<locale>.ts,
register it in dictionaries, and add an entry here.
See Internationalization for the full "how to add a locale" walkthrough.
Theme presets
Brand colors live in the --brand* CSS variables in src/app/globals.css; the
theme block mirrors and documents them so you can swap schemes from one place.
theme: {
active: "default",
presets: {
default: {
brand: "226 57% 21%",
brandForeground: "210 40% 98%",
brandAccent: "24.6 95% 53.1%",
brandAccentForeground: "0 0% 100%",
},
emerald: {
brand: "160 84% 20%",
brandForeground: "150 40% 98%",
brandAccent: "160 84% 39%",
brandAccentForeground: "0 0% 100%",
},
violet: {
brand: "263 60% 26%",
brandForeground: "270 40% 98%",
brandAccent: "262 83% 58%",
brandAccentForeground: "0 0% 100%",
},
} satisfies Record<string, ThemePreset>,
},theme.active is informational only — the runtime source of truth is
globals.css. Each preset is a ThemePreset whose four fields are space-separated
HSL triplets ("H S% L%"), so a value drops straight into hsl(var(--brand)) with no
conversion.
ThemePreset field | Maps to CSS variable | Role |
|---|---|---|
brand | --brand | Deep brand color — headings, dark surfaces, primary brand buttons. |
brandForeground | --brand-foreground | Readable text/icon color on top of brand. |
brandAccent | --brand-accent | Vivid accent — primary CTA buttons and highlights. |
brandAccentForeground | --brand-accent-foreground | Readable text/icon color on top of brandAccent. |
| Preset | Look |
|---|---|
default | Deep navy brand + vivid orange accent (ships out of the box). |
emerald | Green-forward alternative. |
violet | Purple-forward alternative. |
To recolor the store you have two options: edit the --brand* values directly in
src/app/globals.css (:root for light mode, .dark for dark mode), or copy a
preset's triplets onto those variables. Because dark mode reads the same tokens,
restyling is a one-place change. Full details in
Branding & theming.
productCategories
productCategories is an array of ProductCategory objects describing the catalog's
top-level categories. They drive the header navigation, the hero, and the category
cards, and their slug powers category filtering via /products?category=<slug>.
export const productCategories: ProductCategory[] = [
{
name: "Audio",
slug: "audio",
icon: "/categories/audio.svg",
image: "/categories/audio.svg",
description:
"Headphones, speakers, and studio gear engineered for rich, accurate sound.",
secondaryDescription:
"From everyday earbuds to reference monitors, our audio lineup covers listening, recording, and everything in between.",
badges: ["Headphones", "Speakers", "Microphones"],
},
// ...five more
];ProductCategory fields
| Field | Type | Purpose |
|---|---|---|
name | string | Display name shown in navigation and cards. |
slug | string | URL-safe identifier used in query strings: /products?category=<slug>. |
icon | string | Small icon shown in the header navigation and hero. |
image | string | Larger image shown on category cards. |
description | string | Short marketing copy for the category card. |
secondaryDescription | string (optional) | Longer supporting copy for the category card. |
badges | string[] | Example product types shown as badges on the category card. |
Shipped categories
name | slug | badges |
|---|---|---|
| Audio | audio | Headphones, Speakers, Microphones |
| Wearables | wearables | Smartwatches, Fitness Trackers, Bands |
| Smart Home | smart-home | Lighting, Plugs, Sensors, Hubs |
| Cameras | cameras | Action Cams, Security, Lenses |
| Computing | computing | Laptops, Keyboards, Monitors, Storage |
| Accessories | accessories | Chargers, Cables, Cases |
All shipped icon and image paths point at SVGs under public/categories/ (for
example /categories/audio.svg). Replace these files, or point the fields at your own
assets, to re-illustrate the categories.
Rebranding checklist
Set your identity. Update name, tagline, description, and url to your
brand and production domain.
Fill in contact and social. Replace every value under contact and links with
real details — these render in the footer and contact section.
Adjust navigation. Edit mainNav and legalNav so every href points at a route
that exists in your app.
Define your catalog structure. Rewrite productCategories — set each name,
slug, description, badges, and drop matching artwork into
public/categories/. Keep slugs URL-safe; they appear in
/products?category=<slug>.
Pick currencies and locales. Set the base currency, list switchable
currencies (base first, rate: 1), and register your locales and defaultLocale
alongside their i18n dictionaries.
Choose a color scheme. Apply a theme preset — or your own triplets — to the
--brand* variables in src/app/globals.css.
None of this depends on Stripe, Resend, or a SQL backend. Branding applies to the default quote-based store and stays exactly the same when you later enable those optional, env-gated integrations.