← Happnest Docs 🐛 Bug resuelto · 2026-06-09

Webcheckin: /checkin/new devuelve 404 (página de prueba / botón "Empezar")

Síntoma: al pulsar "Empezar check-in" en /checkin/welcome, o al abrir /checkin/new directamente, aparece la página 404 de Next ("This page could not be found"), aunque la URL responde HTTP 200. Pasa en cualquier navegador (no es caché) y el backend está sano.

Causa raíz

El layout de la ruta dinámica packages/webcheckin/src/app/checkin/[id]/layout.tsx tenía un generateStaticParams legacy que devolvía ids literales:

// ❌ Lo que causaba el bug
export async function generateStaticParams() {
  return [{ id: "new" }, { id: "demo" }, { id: "test" }];
}

Eso obliga a Next, en tiempo de build, a prerenderizar /checkin/new (y /checkin/demo, /checkin/test) a través de la ruta dinámica [id]. Al resolver el id "new" como si fuera un check-in real, CheckinFlowClient no lo encuentra → notFound() → Next hornea una página 404 estática para /checkin/new que pisa la ruta real /checkin/new/page.tsx (el formulario de datos).

Señales de diagnóstico: /checkin/new/ devuelve 200 pero el HTML es la 404 de Next, con headers x-nextjs-cache: HIT y x-nextjs-prerender: 1, y carga el chunk app/checkin/[id]/page-*.js (la ruta dinámica) en vez de un chunk propio de /checkin/new.

La regla que se violaba

Los ids de check-in son siempre valores de runtime (UUID, código corto o token QR). Nunca deben prerenderizarse con generateStaticParams, y menos con literales que colisionan con rutas estáticas hermanas (new, welcome, test).

La solución

// ✅ packages/webcheckin/src/app/checkin/[id]/layout.tsx
export const dynamic = "force-dynamic";
export const dynamicParams = true;
// (sin generateStaticParams: el subárbol [id] es 100% dinámico)
Verificación con next build — la tabla de rutas debe mostrar:
○ /checkin/new            ← ruta ESTÁTICA propia (el formulario)
ƒ /checkin/[id]           ← dinámica, server-rendered on demand
ƒ /checkin/[id]/paso-1    ← dinámica
ƒ /checkin/[id]/huespedes ← dinámica
ƒ /checkin/[id]/confirmacion
Si /checkin/new aparece como ƒ bajo [id] o no aparece como ruta propia, el bug ha vuelto.

Si vuelve a pasar (checklist rápido)

Contexto relacionado