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
Navegación de la cuenta personal
// 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" />,
},
];
Navegación de la cuenta de equipo
// 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
- Usa variables de entorno para los secretos
- Tipa tus configuraciones para obtener autocompletado y seguridad
- Documenta las opciones con comentarios
- Valida al arrancar para detectar errores de forma temprana
- Mantén las configuraciones simples - evita la lógica compleja
- Usa feature flags para despliegues graduales
- 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);
}