Settings
Settings owns website settings, SEO settings, billing settings, waitlist settings, localization defaults, normalization, and public settings reads.
On this page
Where to look
| Area | Maintainer 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.tsxsrc/app/(dashboard)/settings/website/page.tsxsrc/app/(dashboard)/settings/seo/page.tsxsrc/features/settings/ui/website-form.tsxsrc/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.tssrc/features/settings/server/config/defaults.tssrc/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.tssrc/features/settings/server/actions/seo-settings.tssrc/features/settings/server/actions/billing-settings.tssrc/features/settings/server/queries/settings.tssrc/features/settings/server/persistence/settings.ts
Reference paths are relative to the Shipflash-Product checkout.
Settings update flow
- 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.tssrc/features/settings/server/actions/result.ts
- 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.tssrc/features/settings/server/normalizer/settings-normalizer.ts
- 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.tssrc/features/settings/server/queries/settings.ts
- 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.tssrc/features/settings/server/actions/seo-settings.tssrc/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.
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.