Settings

Settings owns website settings, SEO settings, billing settings, waitlist settings, localization defaults, normalization, and public settings reads.

On this page

Where to look

AreaMaintainer reference
Routes
Implementation referencesrc/app/(dashboard)/settings, /settings/website, /settings/seo
Actions
Implementation referencesrc/features/settings/server/actions/website-settings.ts, seo-settings.ts, billing-settings.ts, waitlist-settings.ts, settings-json.ts
Guards and results
Implementation referencesrc/features/settings/server/actions/guards.ts, result.ts
Queries
Implementation referencesrc/features/settings/server/queries/settings.ts
Persistence
Implementation referencesrc/features/settings/server/persistence/settings.ts
Schemas and defaults
Implementation referencesrc/features/settings/server/schemas/settings.ts, src/features/settings/server/config/defaults.ts
UI
Implementation referencesrc/features/settings/ui/website-form.tsx, seo-form.tsx, section.tsx
Implementation reference3 areas

These Product code locations explain how the documented behavior is implemented. Expand them when you are ready to customize or maintain this area.

Settings surfaces

Website and SEO settings routes delegate form rendering and server mutations to the settings feature.

  • src/app/(dashboard)/settings/page.tsx
  • src/app/(dashboard)/settings/website/page.tsx
  • src/app/(dashboard)/settings/seo/page.tsx
  • src/features/settings/ui/website-form.tsx
  • src/features/settings/ui/seo-form.tsx

Schemas, defaults, and normalization

Settings schemas, default config, and normalizers keep app settings safe before they reach public pages or provider behavior.

  • src/features/settings/server/schemas/settings.ts
  • src/features/settings/server/config/defaults.ts
  • src/features/settings/server/normalizer/settings-normalizer.ts

Actions, queries, and persistence

Settings actions validate writes, queries return normalized settings, and persistence owns database access.

  • src/features/settings/server/actions/website-settings.ts
  • src/features/settings/server/actions/seo-settings.ts
  • src/features/settings/server/actions/billing-settings.ts
  • src/features/settings/server/queries/settings.ts
  • src/features/settings/server/persistence/settings.ts

Reference paths are relative to the Shipflash-Product checkout.

Settings update flow

  1. 1

    Guard the mutation

    Settings actions use shared guards and action result helpers before writing database-backed settings.

    Relevant Product code
    • src/features/settings/server/actions/guards.ts
    • src/features/settings/server/actions/result.ts
  2. 2

    Validate and normalize

    Schemas and normalizers make settings safe for website, SEO, billing, waitlist, and localization use.

    Relevant Product code
    • src/features/settings/server/schemas/settings.ts
    • src/features/settings/server/normalizer/settings-normalizer.ts
  3. 3

    Persist canonical settings

    Settings persistence owns the database write path and queries expose normalized public reads.

    Relevant Product code
    • src/features/settings/server/persistence/settings.ts
    • src/features/settings/server/queries/settings.ts
  4. 4

    Revalidate affected surfaces

    Settings actions revalidate related routes so public metadata, website copy, and provider settings update predictably.

    Relevant Product code
    • src/features/settings/server/actions/website-settings.ts
    • src/features/settings/server/actions/seo-settings.ts
    • src/features/settings/server/actions/billing-settings.ts

Website settings validation

Use this example as a starting point, then adapt it to your product's rules and configuration.

Public identity and regional defaults are validated before settings JSON is persisted.

ts
const WebsiteSettingsSchema = z.object({
  brandName: z.string().min(2, "Business name must be at least 2 characters"),
  marketingBaseUrl: marketingBaseUrlSchema,
  publicEmail: z
    .string()
    .email("Must be a valid email")
    .optional()
    .nullable()
    .transform((val) => val || null),
  supportUrl: z
    .string()
    .url("Must be a valid URL")
    .optional()
    .nullable()
    .transform((val) => val || null),
  defaultLocale: z.string().trim().min(1, "Default locale is required").refine(isValidLocale, "Must be a valid locale"),
  defaultTimeZone: z.string().trim().min(1, "Default timezone is required").refine(isValidTimeZone, "Must be a valid IANA timezone"),
  defaultCurrency: z.string().trim().transform(normalizeCurrencyCode).refine(isValidCurrency, "Must be a valid ISO 4217 currency code"),
});
Source reference
  • src/features/settings/server/actions/website-settings.ts

Settings rules

  • Validate settings before writing them.
  • Keep public settings reads server-safe.
  • Keep env defaults explicit near the runtime boundary.
  • Do not add fallback env names unless a migration plan requires them.