Awesome-omni-skill nextjs-production-debugger
Advanced debugging guide for Next.js App Router production issues including SSR/CSR bugs, hydration errors, runtime mismatches, performance, and caching.
install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/nextjs-production-debugger" ~/.claude/skills/diegosouzapw-awesome-omni-skill-nextjs-production-debugger && rm -rf "$T"
manifest:
skills/development/nextjs-production-debugger/SKILL.mdsource content
Next.js Production Debugger (App Router)
Guía de supervivencia para debuggear aplicaciones Next.js App Router en producción.
1. Bugs SSR (Server) vs CSR (Client)
Síntoma: El bug ocurre solo en la carga inicial (F5) o solo al navegar (SPA transition).
| Escenario | Comportamiento | Diagnóstico |
|---|---|---|
| Bug en SSR | La página carga rota con F5. Al navegar desde otra página funciona bien. | Revisa logs del TERMINAL del servidor. Deshabilita JS en el navegador para ver el HTML crudo. |
| Bug en CSR | La página carga bien con F5, pero falla al interactuar o navegar. | Revisa la consola del NAVEGADOR. Usa React DevTools. |
Técnica de Aislamiento:
- Deshabilitar JavaScript: Si el contenido está mal sin JS, el problema es el Server rendering.
- Hard Refresh (Cmd+Shift+R): Fuerza una nueva petición al servidor, ignorando el Router Cache del cliente.
2. Hydration Errors (The "Uncanny Valley")
Error:
Text content does not match server-rendered HTML o Hydration failed.
Causas Comunes:
- Timestamps/Random: Usar
oDate.now()
directamente en el cuerpo del componente.Math.random()- Solución: Mover a
o usar una prop desde el servidor.useEffect
- Solución: Mover a
- HTML Inválido: Poner un
dentro de un<div>
, o<p>
dentro de<ul>
.<p>- Check: Valida tu HTML. El navegador intenta corregirlo, creando discrepancias.
- Extensiones del Browser: Plugins que inyectan HTML/CSS pueden romper la hidratación.
- Prueba: Abre en modo Incógnito/Privado.
: Chequeos condicionales de renderizado basados entypeof window !== 'undefined'
.window- Solución: Usa
para montar componentes que dependen deuseEffect
.window
- Solución: Usa
Fix Rápido (Solo si es estético):
<div suppressHydrationWarning>{time}</div>
3. Edge vs Node Runtime Mismatch
Error:
Module not found: Can't resolve 'fs' o errores crípticos en Vercel/Middleware.
Diagnóstico:
- Revisa
en tusexport const runtime = 'edge'
opage.tsx
.route.ts - Problema: El Edge Runtime es limitado (no tiene APIs de Node completas).
- Librerías: Algunas librerías npm asumen Node.js y fallan en Edge.
Soluciones:
- Cambiar a
si necesitas compatibilidad total.runtime = 'nodejs' - Si usas Middleware (siempre es Edge), asegúrate de usar APIs Web Standard (
,fetch
,Request
) y no módulos de Node.Response - Usa
package para asegurar que código de servidor no se filtre al cliente.server-only
4. Performance en App Router
Síntoma: "La página tarda mucho en cargar".
Culpables Habituales:
- Waterfalls (Fetch en Cascada):
- Mal: Componente A espera fetch -> Renderiza B -> B espera fetch.
- Bien:
en el padre, o preload patterns.Promise.all([fetchA, fetchB])
- Client Components Gigantes:
- No hagas toda la página
. Mueve la interactividad a las hojas (hojas del árbol de componentes).use client
- No hagas toda la página
- Blocking SSR:
- Una petición de base de datos lenta en el
bloquea todo el HTML.page.tsx - Solución: Envuelve la parte lenta en
para Streaming SSR.<Suspense fallback={<Skeleton />}>
- Una petición de base de datos lenta en el
Herramientas:
- React DevTools Profiler.
- Pestaña "Network" en Chrome (mira el TTFB vs Content Download).
5. Caching Mal Configurado (El enemigo silencioso)
Síntoma: "Actualicé la DB pero la web sigue mostrando datos viejos".
Capas de Cache en Next.js:
- Request Memoization: Dentro del mismo render pass. (Deduplica fetches iguales).
- Data Cache: Persistente entre deploys/requests. (El
nativo lo hace).fetch- Fix:
ofetch(url, { cache: 'no-store' })
.export const dynamic = 'force-dynamic'
- Fix:
- Full Route Cache: Páginas estáticas generadas al build time.
- Fix:
en Server Actions.revalidatePath('/ruta')
- Fix:
- Router Cache (Client): Cache en el navegador al navegar (dura 30s o 5min).
- Fix:
invalida este cache.router.refresh()
- Fix:
Debug Flow:
- ¿Es dato viejo en el cliente? -> Refresca la página.
- ¿Sigue viejo? -> Es Data Cache o Full Route Cache.
- ¿Sigue viejo tras nuevo deploy? -> Revisa
time orevalidate
.no-store
Comando útil: Usa
next build localmente para ver qué páginas se generan como Estáticas (O) o Dinámicas (ƒ).