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).
/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)
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]/confirmacionSi
/checkin/new aparece como ƒ bajo [id] o no aparece como ruta propia,
el bug ha vuelto.
Si vuelve a pasar (checklist rápido)
- Confirma que no hay
generateStaticParamsdevolviendo ids literales enapp/checkin/[id]/**:grep -rn 'generateStaticParams\|id: "new"' packages/webcheckin/src/app - Comprueba en vivo el chunk que sirve
/checkin/new/: si esapp/checkin/[id]/page-*.js→ la ruta estática está siendo pisada. - Recuerda: en Next App Router una ruta estática gana a una dinámica
hermana; si no gana, casi siempre es un
generateStaticParamsque prerenderiza ese literal. - El backend y la caché del navegador no son la causa: el 404 es del build de Next.
Contexto relacionado
- Fix navegación welcome → pasos (commit
2c4671ad): el botón "Empezar" apuntaba a la página de debug/checkin/test(eliminada). - Fix de este bug: commit
88025b63. - Opción C (QR lookup por REST en el backend, sin Server Actions): commit
050b9271.