Routing, Layouts y Middleware
File-Based Routing
Section titled “File-Based Routing”Las rutas se generan automáticamente desde la estructura de app/pages/. No hay archivo de router manual.
| Archivo | Ruta |
|---|---|
pages/index.vue | / |
pages/courses/index.vue | /courses |
pages/courses/[slug].vue | /courses/:slug (dinámica) |
pages/account/settings.vue | /account/settings |
Para crear una nueva ruta, solo crea el archivo .vue en la ubicación correcta.
Rutas dinámicas
Section titled “Rutas dinámicas”El nombre [slug] crea un parámetro de ruta:
const route = useRoute()const slug = route.params.slug // 'odontologia-avanzada'
const { data } = useServices('getCourseBySlug', { slug })Páginas del proyecto (32 rutas)
Section titled “Páginas del proyecto (32 rutas)”| Sección | Rutas | Descripción |
|---|---|---|
| Home | / | Landing principal con sliders, destacados |
| Channels | /channels, /channels/[slug] | Canales de contenido por marca/partner |
| Courses | /courses, /courses/[slug] | Listado y detalle de cursos |
| Lives | /lives, /lives/[slug] | Eventos en vivo y grabaciones |
| Books | /books, /books/[slug] | Biblioteca digital (PDFs) |
| Presentials | /presentials, /presentials/[slug] | Cursos presenciales |
| Series | /series/[slug] | Series de video episódicas |
| Account | /account/* | Dashboard: perfil, historial, suscripción |
| Auth | /iniciar-sesion, /registro, /recuperar-contrasena | Login, registro, recovery |
| Osteocom | /osteocom/* | Productos de partners |
| Legal | /aviso-legal, /politica-privacidad, /cookies | Páginas legales |
| Otros | /empresa, /protagonistas, /faq, /soporte | Company, expertos, ayuda |
Layouts
Section titled “Layouts”Los layouts definen la estructura visual que envuelve una página (qué navbar mostrar, si hay footer, sidebars, etc.).
Layouts disponibles
Section titled “Layouts disponibles”| Layout | Cuándo se usa |
|---|---|
default | (implícito) Navbar + contenido + Footer |
baseProductDetail | Detalle de producto con sidebar de acciones |
gradientLayout | Fondo con gradiente de marca (secciones hero) |
emptyLayout | Sin navbar ni footer (auth, landings especiales) |
pages/account | Dashboard del usuario con menú lateral |
pages/login | Layout minimalista de login |
pages/register | Layout de registro con pasos |
pages/subscription | Página de planes de suscripción |
Asignar layout a una página
Section titled “Asignar layout a una página”definePageMeta({ layout: 'gradientLayout'})Si no defines layout, usa el default (navbar + footer).
Middleware
Section titled “Middleware”Guards de navegación que se ejecutan antes de cargar una página. Pueden redirigir, bloquear, o ejecutar lógica.
Global (se ejecutan en TODA navegación)
Section titled “Global (se ejecutan en TODA navegación)”auth.global.ts
Section titled “auth.global.ts”Protege rutas privadas y previene acceso innecesario a login:
- Si visita
/accounto/my-contentssin sesión válida → redirige a/iniciar-sesion+ muestra alerta de sesión expirada - Si visita
/iniciar-sesiono/registroestando logueado → redirige a home
Internamente llama authStore.validateSession() que verifica el JWT y determina el estado de suscripción.
language.global.ts
Section titled “language.global.ts”Establece el idioma en cada navegación:
- Lee idioma guardado en
localStorage - Si no hay → detecta idioma del navegador (
navigator.language) - Normaliza a uno de los 3 soportados:
es,en,pt-BR - Aplica via
languageStore.setLanguage()
Específicos (se asignan por página)
Section titled “Específicos (se asignan por página)”exclusive-pages
Section titled “exclusive-pages”Bloquea páginas que la vertical actual no tiene activas. Cada vertical define exclusivePages: ['books', 'presentials'] — si una vertical no incluye una página, este middleware la bloquea.
definePageMeta({ middleware: ['exclusive-pages']})is-thanks-message
Section titled “is-thanks-message”Asegura que la página de “Gracias” solo se acceda tras completar una compra real (previene acceso directo por URL).
Internacionalización de rutas
Section titled “Internacionalización de rutas”Estrategia de URLs
Section titled “Estrategia de URLs”| Idioma | URL | Prefijo |
|---|---|---|
| Español (default) | /cursos | Ninguno |
| Inglés | /en/courses | /en |
| Portugués | /pt-BR/cursos | /pt-BR |
Estrategia: prefix_except_default — el idioma principal no tiene prefijo en la URL.
Traducciones de rutas
Section titled “Traducciones de rutas”Definidas en app/config/i18n/pages.ts:
{ courses: { es: '/cursos', en: '/courses', 'pt-BR': '/cursos' }, 'courses/[slug]': { es: '/cursos/[slug]', en: '/courses/[slug]', 'pt-BR': '/cursos/[slug]' }}Usar traducciones en templates
Section titled “Usar traducciones en templates”const { t } = useI18n()<h1>{{ t('courses.title') }}</h1><p>{{ t('common.no_results') }}</p>Navegar manteniendo el idioma
Section titled “Navegar manteniendo el idioma”const localePath = useLocalePath()
// Genera la ruta en el idioma actual del usuarionavigateTo(localePath('/courses'))// Si el usuario está en inglés → /en/courses// Si está en español → /cursosArchivos de traducción
Section titled “Archivos de traducción”i18n/ → Globales (compartidas entre verticales)├── es.json├── en.json└── pt-BR.json
app/locales/inspiria/ → Específicas de la vertical Inspiria├── es/├── en/└── pt-BR/definePageMeta
Section titled “definePageMeta”Para configurar metadata de una página:
definePageMeta({ layout: 'gradientLayout', // qué layout usar middleware: ['exclusive-pages'], // middleware adicional})Redirects (rutas legacy)
Section titled “Redirects (rutas legacy)”Configurados en nuxt.config.ts:
routeRules: { '/formacion/**': { redirect: '/channels/normon' }}URLs antiguas se redirigen automáticamente a las nuevas.