Shipflash logoDocs

Configuration Guide

Configuration is split between public env values, server-only secrets, app settings, branding, navigation, pricing, email, SEO, and rate-limit policy.

On this page

Configuration source map

App identity and public env

Central config normalizes site URL, brand name, support email, and production URL safety.

  • src/lib/config.ts
  • src/config/app-identity.ts

Database-backed settings

Website, SEO, billing, waitlist, and localization settings are validated before writes and normalized before reads.

  • src/features/settings/server/schemas/settings.ts
  • src/features/settings/server/queries/settings.ts
  • src/features/settings/server/actions/website-settings.ts

Navigation and access

Dashboard navigation is tied to RBAC feature gates so visible links and route access share the same source of truth.

  • src/lib/auth/rbac/nav-config.ts
  • src/lib/auth/rbac/server.ts
  • src/lib/auth/rbac/features.ts

Pricing, email, SEO, and limits

Provider pricing, email delivery config, metadata builders, and route limits are each owned near the runtime boundary that uses them.

  • src/features/billing/server/catalog/configuration.ts
  • src/features/notifications/server/delivery/transport/resend/sender-config.ts
  • src/lib/seo/metadata/builders.ts
  • src/lib/security/rate-limit/policy.ts

Production URL guard

Source: src/lib/config.ts

Production deployments must use HTTPS and cannot point the canonical public URL at localhost.

ts
function assertProductionUrl(name: string, value: string) {
  const parsed = new URL(value);

  if (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1") {
    throw new Error(`${name} must not use localhost in production.`);
  }

  if (parsed.protocol !== "https:") {
    throw new Error(`${name} must use HTTPS in production.`);
  }
}

Rate-limit policy resolver

Source: src/lib/security/rate-limit/policy.ts

Limits have safe defaults and optional env overrides at the policy boundary.

ts
export function getRateLimitPolicy(name: RateLimitPolicyName): RateLimitPolicy {
  const base = DEFAULT_POLICIES[name];
  const envPrefix = `RATE_LIMIT_${name.toUpperCase()}`;
  const limit = readNumberEnv(`${envPrefix}_LIMIT`, base.limit);
  const windowSeconds = readNumberEnv(`${envPrefix}_WINDOW_SECONDS`, base.windowSeconds);
  return { ...base, limit, windowSeconds };
}