AI SaaS Template Docs
AI SaaS Template Docs
IntroductionQuick StartArchitecture
Vercel DeploymentDocker Deployment
ConfigurationProject StructureDatabase GuideAPI Guide
AuthenticationFile ManagementPayment & Billing
Theme Customization
Developer Guide

Configuration

AI SaaS Template uses a centralized configuration system that manages application settings, feature flags, environment variables, and runtime configuration with type safety and validation.

Overview

The configuration system provides:

  • Environment Management: Development, staging, and production environments
  • Feature Flags: Dynamic feature toggling and A/B testing
  • Type Safety: TypeScript validation for all configuration
  • Runtime Configuration: Dynamic settings without rebuilding
  • Validation: Zod schemas for configuration validation
  • Centralized Management: Single source of truth for settings

Environment Variables

Environment Files Structure

.env.local          # Local development (not committed)
.env.example        # Template for environment variables
.env.production     # Production environment variables
.env.staging        # Staging environment variables

Core Environment Variables

# Application
NODE_ENV=development
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_APP_NAME="AI SaaS Template"

# Database
DATABASE_URL=postgresql://user:password@localhost:5432/AI SaaSrsaas

# Authentication
AI SaaSR_AUTH_SECRET=your-super-secret-key-here
AI SaaSR_AUTH_URL=http://localhost:3000
AI SaaSR_AUTH_TRUSTED_ORIGINS=http://localhost:3000

# OAuth Providers
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret

# Payment (Stripe)
STRIPE_SECRET_KEY=sk_test_your-test-secret-key
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your-test-publishable-key
STRIPE_WEBHOOK_SECRET=whsec_your-webhook-secret

# File Storage (Cloudflare R2)
CLOUDFLARE_R2_ACCESS_KEY_ID=your-access-key-id
CLOUDFLARE_R2_SECRET_ACCESS_KEY=your-secret-access-key
CLOUDFLARE_R2_BUCKET_NAME=your-bucket-name
CLOUDFLARE_R2_ENDPOINT=https://your-account-id.r2.cloudflarestorage.com
NEXT_PUBLIC_CLOUDFLARE_R2_PUBLIC_URL=https://your-domain.com

# Email (Resend)
RESEND_API_KEY=your-resend-api-key
[email protected]

# Analytics (Optional)
NEXT_PUBLIC_GOOGLE_ANALYTICS_ID=GA_MEASUREMENT_ID
NEXT_PUBLIC_POSTHOG_KEY=your-posthog-key
NEXT_PUBLIC_POSTHOG_HOST=https://app.posthog.com

# Monitoring (Optional)
SENTRY_DSN=your-sentry-dsn
SENTRY_ORG=your-sentry-org
SENTRY_PROJECT=your-sentry-project

# Feature Flags
NEXT_PUBLIC_ENABLE_ANALYTICS=true
NEXT_PUBLIC_ENABLE_BLOG=true
NEXT_PUBLIC_ENABLE_DOCS=true
NEXT_PUBLIC_ENABLE_PAYMENTS=true

Environment Validation

// src/env.ts
import { z } from 'zod'

const envSchema = z.object({
  // Application
  NODE_ENV: z.enum(['development', 'staging', 'production']).default('development'),
  NEXT_PUBLIC_APP_URL: z.string().url(),
  NEXT_PUBLIC_APP_NAME: z.string().default('AI SaaS Template'),

  // Database
  DATABASE_URL: z.string().url(),

  // Authentication
  AI SaaSR_AUTH_SECRET: z.string().min(32),
  AI SaaSR_AUTH_URL: z.string().url(),
  AI SaaSR_AUTH_TRUSTED_ORIGINS: z.string().optional(),

  // OAuth
  GITHUB_CLIENT_ID: z.string().optional(),
  GITHUB_CLIENT_SECRET: z.string().optional(),
  GOOGLE_CLIENT_ID: z.string().optional(),
  GOOGLE_CLIENT_SECRET: z.string().optional(),

  // Payment
  STRIPE_SECRET_KEY: z.string().optional(),
  NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: z.string().optional(),
  STRIPE_WEBHOOK_SECRET: z.string().optional(),

  // File Storage
  CLOUDFLARE_R2_ACCESS_KEY_ID: z.string().optional(),
  CLOUDFLARE_R2_SECRET_ACCESS_KEY: z.string().optional(),
  CLOUDFLARE_R2_BUCKET_NAME: z.string().optional(),
  CLOUDFLARE_R2_ENDPOINT: z.string().url().optional(),
  NEXT_PUBLIC_CLOUDFLARE_R2_PUBLIC_URL: z.string().url().optional(),

  // Email
  RESEND_API_KEY: z.string().optional(),
  RESEND_FROM_EMAIL: z.string().email().optional(),

  // Analytics
  NEXT_PUBLIC_GOOGLE_ANALYTICS_ID: z.string().optional(),
  NEXT_PUBLIC_POSTHOG_KEY: z.string().optional(),
  NEXT_PUBLIC_POSTHOG_HOST: z.string().url().optional(),

  // Monitoring
  SENTRY_DSN: z.string().url().optional(),
  SENTRY_ORG: z.string().optional(),
  SENTRY_PROJECT: z.string().optional(),

  // Feature Flags
  NEXT_PUBLIC_ENABLE_ANALYTICS: z.string().transform(val => val === 'true').default('false'),
  NEXT_PUBLIC_ENABLE_BLOG: z.string().transform(val => val === 'true').default('true'),
  NEXT_PUBLIC_ENABLE_DOCS: z.string().transform(val => val === 'true').default('true'),
  NEXT_PUBLIC_ENABLE_PAYMENTS: z.string().transform(val => val === 'true').default('true'),
})

export const env = envSchema.parse(process.env)

export type Env = z.infer<typeof envSchema>

Application Configuration

Core App Configuration

// src/config/app.config.ts
import { env } from '@/env'

export const APP_CONFIG = {
  name: env.NEXT_PUBLIC_APP_NAME,
  url: env.NEXT_PUBLIC_APP_URL,
  description: 'Modern SaaS application built with Next.js',
  
  // Application metadata
  meta: {
    title: 'AI SaaS Template - Modern SaaS Template',
    description: 'Build your SaaS application with Next.js, TypeScript, and modern tools',
    keywords: ['SaaS', 'Next.js', 'TypeScript', 'React', 'Tailwind CSS'],
    author: 'AI SaaS Template Team',
    version: '1.0.0',
  },

  // Social media and branding
  social: {
    twitter: '@AI SaaSrsaas',
    github: 'https://github.com/yourusername/AI SaaSr-saas',
    discord: 'https://discord.gg/yourinvite',
  },

  // Contact information
  contact: {
    email: 'hello@AI SaaSrsaas.com',
    support: 'support@AI SaaSrsaas.com',
  },

  // Legal
  legal: {
    company: 'AI SaaS Template Inc.',
    address: '123 Main St, San Francisco, CA 94105',
    privacyPolicy: '/privacy',
    termsOfService: '/terms',
  },

  // Default settings
  defaults: {
    locale: 'en',
    theme: 'light',
    currency: 'USD',
    timezone: 'UTC',
  },
} as const

export type AppConfig = typeof APP_CONFIG

Feature Configuration

// src/config/features.config.ts
import { env } from '@/env'

export const FEATURES_CONFIG = {
  // Core features
  authentication: {
    enabled: true,
    providers: {
      email: true,
      github: !!env.GITHUB_CLIENT_ID,
      google: !!env.GOOGLE_CLIENT_ID,
    },
    features: {
      registration: true,
      emailVerification: false,
      twoFactorAuth: false,
      passwordReset: true,
    },
  },

  // Payment features
  payments: {
    enabled: env.NEXT_PUBLIC_ENABLE_PAYMENTS,
    provider: 'stripe',
    features: {
      subscriptions: true,
      oneTimePayments: true,
      invoices: true,
      refunds: true,
    },
    plans: {
      basic: {
        id: 'basic',
        name: 'Basic',
        price: 9.99,
        interval: 'month',
        features: ['5 projects', '10GB storage', 'Email support'],
      },
      pro: {
        id: 'pro',
        name: 'Pro',
        price: 29.99,
        interval: 'month',
        features: ['Unlimited projects', '100GB storage', 'Priority support'],
      },
    },
  },

  // File management
  fileManagement: {
    enabled: true,
    provider: 'r2',
    limits: {
      maxFileSize: 10 * 1024 * 1024, // 10MB
      maxFiles: 1000,
      allowedTypes: ['image/jpeg', 'image/png', 'application/pdf'],
    },
    features: {
      thumbnails: true,
      sharing: true,
      folders: true,
      search: true,
    },
  },

  // Analytics
  analytics: {
    enabled: env.NEXT_PUBLIC_ENABLE_ANALYTICS,
    providers: {
      googleAnalytics: !!env.NEXT_PUBLIC_GOOGLE_ANALYTICS_ID,
      posthog: !!env.NEXT_PUBLIC_POSTHOG_KEY,
    },
  },

  // Content features
  content: {
    blog: {
      enabled: env.NEXT_PUBLIC_ENABLE_BLOG,
      features: {
        comments: false,
        rss: true,
        search: true,
        categories: true,
      },
    },
    docs: {
      enabled: env.NEXT_PUBLIC_ENABLE_DOCS,
      features: {
        search: true,
        feedback: true,
        editOnGithub: true,
      },
    },
  },

  // Admin features
  admin: {
    enabled: true,
    features: {
      userManagement: true,
      analytics: true,
      systemSettings: true,
      auditLog: true,
    },
  },

  // Internationalization
  i18n: {
    enabled: true,
    defaultLocale: 'en',
    locales: ['en', 'zh'],
    features: {
      autoDetect: true,
      localizedRouting: true,
    },
  },
} as const

export type FeaturesConfig = typeof FEATURES_CONFIG

Theme Configuration

// src/config/theme.config.ts
export const THEME_CONFIG = {
  // Color schemes
  colors: {
    light: {
      primary: 'hsl(221, 83%, 53%)',
      secondary: 'hsl(210, 40%, 98%)',
      accent: 'hsl(210, 40%, 96%)',
      background: 'hsl(0, 0%, 100%)',
      foreground: 'hsl(222, 84%, 5%)',
      muted: 'hsl(210, 40%, 96%)',
      border: 'hsl(214, 32%, 91%)',
    },
    dark: {
      primary: 'hsl(221, 83%, 53%)',
      secondary: 'hsl(217, 33%, 17%)',
      accent: 'hsl(217, 33%, 17%)',
      background: 'hsl(222, 84%, 5%)',
      foreground: 'hsl(210, 40%, 98%)',
      muted: 'hsl(217, 33%, 17%)',
      border: 'hsl(217, 33%, 17%)',
    },
  },

  // Typography
  typography: {
    fontFamily: {
      sans: ['Inter', 'system-ui', 'sans-serif'],
      mono: ['Fira Code', 'monospace'],
    },
    fontSize: {
      xs: '0.75rem',
      sm: '0.875rem',
      base: '1rem',
      lg: '1.125rem',
      xl: '1.25rem',
      '2xl': '1.5rem',
      '3xl': '1.875rem',
      '4xl': '2.25rem',
    },
  },

  // Layout
  layout: {
    containerMaxWidth: '1200px',
    sidebarWidth: '240px',
    headerHeight: '64px',
    footerHeight: '80px',
  },

  // Animation
  animation: {
    duration: {
      fast: '150ms',
      normal: '300ms',
      slow: '500ms',
    },
    easing: {
      default: 'cubic-bezier(0.4, 0, 0.2, 1)',
      in: 'cubic-bezier(0.4, 0, 1, 1)',
      out: 'cubic-bezier(0, 0, 0.2, 1)',
    },
  },

  // Breakpoints
  breakpoints: {
    sm: '640px',
    md: '768px',
    lg: '1024px',
    xl: '1280px',
    '2xl': '1536px',
  },
} as const

export type ThemeConfig = typeof THEME_CONFIG

Navigation Configuration

// src/config/navbar.config.ts
import { FEATURES_CONFIG } from './features.config'

export const NAVBAR_CONFIG = {
  // Main navigation
  main: [
    {
      title: 'Home',
      href: '/',
      icon: 'home',
    },
    {
      title: 'Features',
      href: '/features',
      icon: 'features',
    },
    {
      title: 'Pricing',
      href: '/pricing',
      icon: 'pricing',
    },
    ...(FEATURES_CONFIG.content.blog.enabled ? [{
      title: 'Blog',
      href: '/blog',
      icon: 'blog',
    }] : []),
    ...(FEATURES_CONFIG.content.docs.enabled ? [{
      title: 'Docs',
      href: '/docs',
      icon: 'docs',
    }] : []),
  ],

  // Dashboard navigation
  dashboard: [
    {
      title: 'Overview',
      href: '/dashboard',
      icon: 'dashboard',
    },
    {
      title: 'Projects',
      href: '/dashboard/projects',
      icon: 'projects',
    },
    ...(FEATURES_CONFIG.fileManagement.enabled ? [{
      title: 'Files',
      href: '/dashboard/files',
      icon: 'files',
    }] : []),
    ...(FEATURES_CONFIG.payments.enabled ? [{
      title: 'Billing',
      href: '/dashboard/billing',
      icon: 'billing',
    }] : []),
    {
      title: 'Settings',
      href: '/dashboard/settings',
      icon: 'settings',
    },
  ],

  // Admin navigation
  admin: [
    {
      title: 'Users',
      href: '/admin/users',
      icon: 'users',
      permission: 'manage:users',
    },
    {
      title: 'Analytics',
      href: '/admin/analytics',
      icon: 'analytics',
      permission: 'view:analytics',
    },
    {
      title: 'Settings',
      href: '/admin/settings',
      icon: 'settings',
      permission: 'manage:settings',
    },
  ],

  // Footer navigation
  footer: {
    product: [
      { title: 'Features', href: '/features' },
      { title: 'Pricing', href: '/pricing' },
      { title: 'Changelog', href: '/changelog' },
    ],
    company: [
      { title: 'About', href: '/about' },
      { title: 'Contact', href: '/contact' },
      { title: 'Careers', href: '/careers' },
    ],
    legal: [
      { title: 'Privacy', href: '/privacy' },
      { title: 'Terms', href: '/terms' },
      { title: 'Security', href: '/security' },
    ],
  },
} as const

export type NavbarConfig = typeof NAVBAR_CONFIG

Payment Configuration

// src/config/payment.config.ts
import { env } from '@/env'

export const PAYMENT_CONFIG = {
  // Provider configuration
  provider: 'stripe',
  enabled: env.NEXT_PUBLIC_ENABLE_PAYMENTS,
  
  // Currency settings
  currency: 'USD',
  locale: 'en-US',

  // Subscription plans
  plans: {
    basic: {
      id: 'basic',
      name: 'Basic',
      description: 'Perfect for individuals and small teams',
      price: 9.99,
      interval: 'month',
      stripePriceId: 'price_basic_monthly',
      features: [
        'Up to 5 projects',
        '10GB storage',
        'Email support',
        'Basic analytics',
      ],
      limits: {
        projects: 5,
        storage: 10 * 1024 * 1024 * 1024, // 10GB
        users: 1,
        apiCalls: 1000,
      },
    },
    pro: {
      id: 'pro',
      name: 'Pro',
      description: 'For growing teams and businesses',
      price: 29.99,
      interval: 'month',
      stripePriceId: 'price_pro_monthly',
      features: [
        'Unlimited projects',
        '100GB storage',
        'Priority support',
        'Advanced analytics',
        'Team collaboration',
      ],
      limits: {
        projects: -1, // Unlimited
        storage: 100 * 1024 * 1024 * 1024, // 100GB
        users: 10,
        apiCalls: 10000,
      },
    },
    enterprise: {
      id: 'enterprise',
      name: 'Enterprise',
      description: 'For large organizations with advanced needs',
      price: 99.99,
      interval: 'month',
      stripePriceId: 'price_enterprise_monthly',
      features: [
        'Everything in Pro',
        '1TB storage',
        'Dedicated support',
        'Custom integrations',
        'SLA guarantee',
      ],
      limits: {
        projects: -1, // Unlimited
        storage: 1024 * 1024 * 1024 * 1024, // 1TB
        users: -1, // Unlimited
        apiCalls: -1, // Unlimited
      },
    },
  },

  // Billing settings
  billing: {
    trialPeriod: 14, // days
    gracePeriod: 3, // days
    invoicePrefix: 'INV-',
    taxRate: 0.1, // 10%
  },

  // Feature access by plan
  features: {
    basic: [
      'projects',
      'storage',
      'support',
      'analytics',
    ],
    pro: [
      'projects',
      'storage',
      'support',
      'analytics',
      'collaboration',
      'integrations',
    ],
    enterprise: [
      'projects',
      'storage',
      'support',
      'analytics',
      'collaboration',
      'integrations',
      'sla',
      'custom',
    ],
  },
} as const

export type PaymentConfig = typeof PAYMENT_CONFIG
export type PlanId = keyof typeof PAYMENT_CONFIG.plans
export type Plan = typeof PAYMENT_CONFIG.plans[PlanId]

Configuration Validation

Runtime Configuration Validation

// src/lib/config-validation.ts
import { z } from 'zod'

// Configuration schemas
const appConfigSchema = z.object({
  name: z.string().min(1),
  url: z.string().url(),
  description: z.string().min(1),
  meta: z.object({
    title: z.string().min(1),
    description: z.string().min(1),
    keywords: z.array(z.string()),
    author: z.string().min(1),
    version: z.string().min(1),
  }),
})

const featuresConfigSchema = z.object({
  authentication: z.object({
    enabled: z.boolean(),
    providers: z.object({
      email: z.boolean(),
      github: z.boolean(),
      google: z.boolean(),
    }),
  }),
  payments: z.object({
    enabled: z.boolean(),
    provider: z.enum(['stripe', 'paddle']),
  }),
  fileManagement: z.object({
    enabled: z.boolean(),
    provider: z.enum(['r2', 's3']),
    limits: z.object({
      maxFileSize: z.number().positive(),
      maxFiles: z.number().positive(),
      allowedTypes: z.array(z.string()),
    }),
  }),
})

// Validation functions
export function validateAppConfig(config: unknown) {
  return appConfigSchema.parse(config)
}

export function validateFeaturesConfig(config: unknown) {
  return featuresConfigSchema.parse(config)
}

// Configuration loader with validation
export function loadConfig<T>(
  configLoader: () => T,
  validator: (config: unknown) => T
): T {
  try {
    const config = configLoader()
    return validator(config)
  } catch (error) {
    console.error('Configuration validation failed:', error)
    throw new Error('Invalid configuration')
  }
}

Configuration Hooks

useConfig Hook

// src/hooks/use-config.ts
import { useContext, createContext, ReactNode } from 'react'
import { APP_CONFIG, AppConfig } from '@/config/app.config'
import { FEATURES_CONFIG, FeaturesConfig } from '@/config/features.config'
import { THEME_CONFIG, ThemeConfig } from '@/config/theme.config'

interface ConfigContextType {
  app: AppConfig
  features: FeaturesConfig
  theme: ThemeConfig
}

const ConfigContext = createContext<ConfigContextType | undefined>(undefined)

export function ConfigProvider({ children }: { children: ReactNode }) {
  const config = {
    app: APP_CONFIG,
    features: FEATURES_CONFIG,
    theme: THEME_CONFIG,
  }

  return (
    <ConfigContext.Provider value={config}>
      {children}
    </ConfigContext.Provider>
  )
}

export function useConfig() {
  const context = useContext(ConfigContext)
  if (!context) {
    throw new Error('useConfig must be used within a ConfigProvider')
  }
  return context
}

// Specific config hooks
export function useAppConfig() {
  const { app } = useConfig()
  return app
}

export function useFeaturesConfig() {
  const { features } = useConfig()
  return features
}

export function useThemeConfig() {
  const { theme } = useConfig()
  return theme
}

Feature Flags

Feature Flag System

// src/lib/feature-flags.ts
import { FEATURES_CONFIG } from '@/config/features.config'

export type FeatureFlag = keyof typeof FEATURES_CONFIG

export function isFeatureEnabled(feature: FeatureFlag): boolean {
  const config = FEATURES_CONFIG[feature]
  return typeof config === 'object' && 'enabled' in config 
    ? config.enabled 
    : Boolean(config)
}

export function getFeatureConfig<T extends FeatureFlag>(
  feature: T
): typeof FEATURES_CONFIG[T] {
  return FEATURES_CONFIG[feature]
}

// Feature flag component
export function FeatureFlag({ 
  feature, 
  children, 
  fallback = null 
}: {
  feature: FeatureFlag
  children: React.ReactNode
  fallback?: React.ReactNode
}) {
  if (!isFeatureEnabled(feature)) {
    return <>{fallback}</>
  }
  
  return <>{children}</>
}

// Feature flag hook
export function useFeatureFlag(feature: FeatureFlag) {
  return isFeatureEnabled(feature)
}

Configuration Management

Dynamic Configuration

// src/lib/dynamic-config.ts
import { useState, useEffect } from 'react'

interface DynamicConfig {
  maintenance: boolean
  announcements: string[]
  experimentalFeatures: Record<string, boolean>
}

export function useDynamicConfig() {
  const [config, setConfig] = useState<DynamicConfig>({
    maintenance: false,
    announcements: [],
    experimentalFeatures: {},
  })

  useEffect(() => {
    // Load dynamic configuration from API
    fetch('/api/config')
      .then(res => res.json())
      .then(setConfig)
      .catch(console.error)
  }, [])

  return config
}

// Server-side dynamic config
export async function getDynamicConfig(): Promise<DynamicConfig> {
  // This could fetch from a database, external API, or config service
  return {
    maintenance: process.env.MAINTENANCE_MODE === 'true',
    announcements: process.env.ANNOUNCEMENTS?.split(',') || [],
    experimentalFeatures: {
      newDashboard: process.env.EXPERIMENTAL_NEW_DASHBOARD === 'true',
      betaFeatures: process.env.EXPERIMENTAL_BETA_FEATURES === 'true',
    },
  }
}

Configuration API

// src/app/api/config/route.ts
import { NextResponse } from 'next/server'
import { getDynamicConfig } from '@/lib/dynamic-config'

export async function GET() {
  try {
    const config = await getDynamicConfig()
    return NextResponse.json(config)
  } catch (error) {
    return NextResponse.json(
      { error: 'Failed to load configuration' },
      { status: 500 }
    )
  }
}

Environment-Specific Configuration

Development Configuration

// src/config/development.config.ts
export const DEVELOPMENT_CONFIG = {
  debug: true,
  logging: {
    level: 'debug',
    console: true,
    file: false,
  },
  database: {
    logging: true,
    ssl: false,
  },
  cache: {
    enabled: false,
  },
  rateLimit: {
    enabled: false,
  },
} as const

Production Configuration

// src/config/production.config.ts
export const PRODUCTION_CONFIG = {
  debug: false,
  logging: {
    level: 'error',
    console: false,
    file: true,
  },
  database: {
    logging: false,
    ssl: true,
  },
  cache: {
    enabled: true,
    ttl: 3600,
  },
  rateLimit: {
    enabled: true,
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100,
  },
} as const

Testing Configuration

Test Configuration

// src/config/test.config.ts
export const TEST_CONFIG = {
  database: {
    url: 'postgresql://test:test@localhost:5432/AI SaaSrsaas_test',
    logging: false,
  },
  auth: {
    secret: 'test-secret-key',
    skipVerification: true,
  },
  storage: {
    provider: 'memory',
  },
  email: {
    provider: 'mock',
  },
} as const

Best Practices

Configuration Organization

  1. Separate Concerns: Keep different types of configuration in separate files
  2. Type Safety: Use TypeScript for all configuration
  3. Validation: Validate configuration at startup
  4. Environment Variables: Use environment variables for sensitive data
  5. Defaults: Provide sensible defaults for all configuration

Security Considerations

  1. Secret Management: Never commit secrets to version control
  2. Environment Separation: Use different configurations for different environments
  3. Validation: Validate all configuration inputs
  4. Access Control: Limit access to configuration endpoints

Performance Optimization

  1. Lazy Loading: Load configuration only when needed
  2. Caching: Cache configuration to avoid repeated reads
  3. Bundling: Optimize configuration for client-side bundling

Troubleshooting

Common Issues

  1. Missing Environment Variables: Check .env.example for required variables
  2. Invalid Configuration: Use validation schemas to catch errors early
  3. Type Errors: Ensure all configuration is properly typed
  4. Runtime Errors: Validate configuration at application startup

Debug Tools

// src/lib/config-debug.ts
export function debugConfiguration() {
  if (process.env.NODE_ENV === 'development') {
    console.log('App Config:', APP_CONFIG)
    console.log('Features Config:', FEATURES_CONFIG)
    console.log('Environment Variables:', process.env)
  }
}

Docker Deployment

Previous Page

Project Structure

Next Page

On this page

OverviewEnvironment VariablesEnvironment Files StructureCore Environment VariablesEnvironment ValidationApplication ConfigurationCore App ConfigurationFeature ConfigurationTheme ConfigurationNavigation ConfigurationPayment ConfigurationConfiguration ValidationRuntime Configuration ValidationConfiguration HooksuseConfig HookFeature FlagsFeature Flag SystemConfiguration ManagementDynamic ConfigurationConfiguration APIEnvironment-Specific ConfigurationDevelopment ConfigurationProduction ConfigurationTesting ConfigurationTest ConfigurationBest PracticesConfiguration OrganizationSecurity ConsiderationsPerformance OptimizationTroubleshootingCommon IssuesDebug Tools