Configuración

Configura los ajustes de tu aplicación y los feature flags.

Nota: Este es contenido de ejemplo/marcador de posición con fines de demostración.

Personaliza el comportamiento de tu aplicación mediante archivos de configuración.

Archivos de configuración

Todos los archivos de configuración se encuentran en apps/web/config/:

config/
├── paths.config.ts        # Rutas
├── billing.config.ts      # Facturación y precios
├── feature-flags.config.ts # Activación de funcionalidades
├── personal-account-navigation.config.tsx
├── team-account-navigation.config.tsx
└── i18n.settings.ts       # Internacionalización

Feature flags

Controla la disponibilidad de las funcionalidades:

// config/feature-flags.config.ts
export const featureFlags = {
  enableTeamAccounts: true,
  enableBilling: true,
  enableNotifications: true,
  enableFileUploads: false,
  enableAnalytics: true,
  enableChat: false,
};

Uso de los feature flags

import { featureFlags } from '~/config/feature-flags.config';

export function ConditionalFeature() {
  if (!featureFlags.enableChat) {
    return null;
  }

  return <ChatWidget />;
}

Configuración de rutas

Define las rutas de la aplicación:

// config/paths.config.ts
export const pathsConfig = {
  auth: {
    signIn: '/auth/sign-in',
    signUp: '/auth/sign-up',
    passwordReset: '/auth/password-reset',
    callback: '/auth/callback',
  },
  app: {
    home: '/home',
    personalAccount: '/home',
    teamAccount: '/home/[account]',
    settings: '/home/settings',
    billing: '/home/settings/billing',
  },
  admin: {
    home: '/admin',
    users: '/admin/users',
    analytics: '/admin/analytics',
  },
};

Uso de las rutas

import { pathsConfig } from '~/config/paths.config';
import Link from 'next/link';

<Link href={pathsConfig.app.settings}>
  Settings
</Link>

Configuración de la navegación

// config/personal-account-navigation.config.tsx
import { HomeIcon, SettingsIcon } from 'lucide-react';

export default [
  {
    label: 'common:routes.home',
    path: pathsConfig.app.personalAccount,
    Icon: <HomeIcon className="w-4" />,
    end: true,
  },
  {
    label: 'common:routes.settings',
    path: pathsConfig.app.settings,
    Icon: <SettingsIcon className="w-4" />,
  },
];
// config/team-account-navigation.config.tsx
export default [
  {
    label: 'common:routes.dashboard',
    path: createPath(pathsConfig.app.teamAccount, account),
    Icon: <LayoutDashboardIcon className="w-4" />,
    end: true,
  },
  {
    label: 'common:routes.projects',
    path: createPath(pathsConfig.app.projects, account),
    Icon: <FolderIcon className="w-4" />,
  },
  {
    label: 'common:routes.members',
    path: createPath(pathsConfig.app.members, account),
    Icon: <UsersIcon className="w-4" />,
  },
];

Configuración de la facturación

// config/billing.config.ts
export const billingConfig = {
  provider: 'stripe', // 'stripe' | 'paddle'
  enableTrial: true,
  trialDays: 14,

  plans: [
    {
      id: 'free',
      name: 'Free',
      price: 0,
      features: ['5 projects', 'Basic support'],
      limits: {
        projects: 5,
        members: 1,
      },
    },
    {
      id: 'pro',
      name: 'Professional',
      price: 29,
      interval: 'month',
      features: ['Unlimited projects', 'Priority support'],
      limits: {
        projects: -1, // ilimitado
        members: 10,
      },
    },
  ],
};

Internacionalización

// lib/i18n/i18n.settings.ts
export const i18nSettings = {
  defaultLocale: 'en',
  locales: ['en', 'es', 'fr', 'de'],
  defaultNamespace: 'common',
  namespaces: ['common', 'auth', 'billing', 'errors'],
};

Configuración del correo electrónico

// config/email.config.ts
export const emailConfig = {
  from: {
    email: process.env.EMAIL_FROM || 'noreply@example.com',
    name: process.env.EMAIL_FROM_NAME || 'Your App',
  },
  provider: 'resend', // 'resend' | 'sendgrid' | 'postmark'
};

Configuración de SEO

// config/seo.config.ts
export const seoConfig = {
  title: 'Your App Name',
  description: 'Your app description',
  ogImage: '/images/og-image.png',
  twitterHandle: '@yourapp',
  locale: 'en_US',

  // Valores específicos por página
  pages: {
    home: {
      title: 'Home - Your App',
      description: 'Welcome to your app',
    },
    pricing: {
      title: 'Pricing - Your App',
      description: 'Simple, transparent pricing',
    },
  },
};

Configuración del tema

// config/theme.config.ts
export const themeConfig = {
  defaultTheme: 'system', // 'light' | 'dark' | 'system'
  enableColorSchemeToggle: true,

  colors: {
    primary: 'blue',
    accent: 'purple',
  },
};

Configuración de la analítica

// config/analytics.config.ts
export const analyticsConfig = {
  googleAnalytics: {
    enabled: true,
    measurementId: process.env.NEXT_PUBLIC_GA_ID,
  },

  posthog: {
    enabled: false,
    apiKey: process.env.NEXT_PUBLIC_POSTHOG_KEY,
  },

  plausible: {
    enabled: false,
    domain: process.env.NEXT_PUBLIC_PLAUSIBLE_DOMAIN,
  },
};

Limitación de solicitudes

// config/rate-limit.config.ts
export const rateLimitConfig = {
  api: {
    windowMs: 15 * 60 * 1000, // 15 minutos
    max: 100, // solicitudes por ventana
  },

  auth: {
    windowMs: 15 * 60 * 1000,
    max: 5, // intentos de inicio de sesión
  },
};

Configuración de la subida de archivos

// config/upload.config.ts
export const uploadConfig = {
  maxFileSize: 5 * 1024 * 1024, // 5MB
  allowedMimeTypes: [
    'image/jpeg',
    'image/png',
    'image/gif',
    'image/webp',
    'application/pdf',
  ],

  storage: {
    provider: 'supabase', // 'supabase' | 's3' | 'cloudinary'
    bucket: 'uploads',
  },
};

Configuración específica del entorno

// config/app.config.ts
const isDev = process.env.NODE_ENV === 'development';
const isProd = process.env.NODE_ENV === 'production';

export const appConfig = {
  environment: process.env.NODE_ENV,
  apiUrl: isProd
    ? 'https://api.yourapp.com'
    : 'http://localhost:3000/api',

  features: {
    enableDebugTools: isDev,
    enableErrorReporting: isProd,
    enableAnalytics: isProd,
  },
};

Buenas prácticas

  1. Usa variables de entorno para los secretos
  2. Tipa tus configuraciones para obtener autocompletado y seguridad
  3. Documenta las opciones con comentarios
  4. Valida al arrancar para detectar errores de forma temprana
  5. Mantén las configuraciones simples - evita la lógica compleja
  6. Usa feature flags para despliegues graduales
  7. Usa valores específicos por entorno para las diferencias entre desarrollo y producción

Carga de la configuración

Las configuraciones se cargan automáticamente, pero puedes validarlas:

// lib/config/validate-config.ts
import { z } from 'zod';

const ConfigSchema = z.object({
  apiUrl: z.string().url(),
  enableFeatureX: z.boolean(),
});

export function validateConfig(config: unknown) {
  return ConfigSchema.parse(config);
}