Acme Store Docs
Configuration

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.

ExportKindPurpose
siteConfigconst objectStore identity, contact, navigation, currencies, locales, and theme presets.
productCategoriesProductCategory[]The catalog's top-level categories.
CurrencyConfiginterfaceShape of the base store currency (code, locale).
CurrencyOptioninterfaceA switchable currency (code, locale, rate, label).
LocaleOptioninterfaceA switchable UI locale (code, label).
ThemePresetinterfaceA brand color scheme as HSL triplets.
ProductCategoryinterfaceShape 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

src/config/site.ts
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;
FieldTypeShipped valueNotes
namestring"Acme Store"Store name shown in the header, footer, page titles, and emails.
taglinestring"Everything you need to launch your online store"Short marketing line.
descriptionstring"A modular and scalable ecommerce boilerplate…"Long description, used for SEO metadata.
urlstring"https://example.com"Canonical site URL. Point this at your production domain.
src/config/site.ts
  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",
  },
FieldShipped 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"

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.

src/config/site.ts
  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" },
  ],
ArrayRendered inItems (label → href)
mainNavPrimary header/footer navigationProducts → /products, About → /about, Contact → /#contact
legalNavFooter legal linksPrivacy 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.

src/config/site.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: code is an ISO 4217 code and locale is a BCP 47 locale that drives number grouping and the currency symbol.
  • currencies (CurrencyOption[]) lists the switchable options. Each adds rate — the multiplier from the base currency — and label, 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

src/config/site.ts
  defaultLocale: "en",
  locales: [
    { code: "en", label: "English" },
    { code: "es", label: "Español" },
  ] satisfies LocaleOption[],
FieldTypeShipped value
defaultLocalestring"en"
localesLocaleOption[]enEnglish, esEspañ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.

src/config/site.ts
  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 fieldMaps to CSS variableRole
brand--brandDeep brand color — headings, dark surfaces, primary brand buttons.
brandForeground--brand-foregroundReadable text/icon color on top of brand.
brandAccent--brand-accentVivid accent — primary CTA buttons and highlights.
brandAccentForeground--brand-accent-foregroundReadable text/icon color on top of brandAccent.
PresetLook
defaultDeep navy brand + vivid orange accent (ships out of the box).
emeraldGreen-forward alternative.
violetPurple-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>.

src/config/site.ts
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

FieldTypePurpose
namestringDisplay name shown in navigation and cards.
slugstringURL-safe identifier used in query strings: /products?category=<slug>.
iconstringSmall icon shown in the header navigation and hero.
imagestringLarger image shown on category cards.
descriptionstringShort marketing copy for the category card.
secondaryDescriptionstring (optional)Longer supporting copy for the category card.
badgesstring[]Example product types shown as badges on the category card.

Shipped categories

nameslugbadges
AudioaudioHeadphones, Speakers, Microphones
WearableswearablesSmartwatches, Fitness Trackers, Bands
Smart Homesmart-homeLighting, Plugs, Sensors, Hubs
CamerascamerasAction Cams, Security, Lenses
ComputingcomputingLaptops, Keyboards, Monitors, Storage
AccessoriesaccessoriesChargers, 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.

On this page