Next.js
Modelo mental completo de Next.js
Integra routing, React, servidor, cliente, datos, caché, seguridad, mutaciones, rendimiento y despliegue en un modelo mental completo de Next.js.
- Última actualización
- Actualizada
- Nivel
- Fundamentos
Next.js
Integra routing, React, servidor, cliente, datos, caché, seguridad, mutaciones, rendimiento y despliegue en un modelo mental completo de Next.js.
Next.js es un sistema que conecta URL, routing, React, servidor, cliente, datos, caché y plataforma. Para comprenderlo no memorices APIs aisladas: sigue cada request desde que entra hasta que la interfaz se actualiza y pregunta en qué fase ocurre cada trabajo, quién puede ver el resultado y qué lo vuelve a calcular.
User intent
→ browser request or client navigation
→ CDN / platform edge
→ config redirects and headers
→ Proxy
→ filesystem routing
→ page, layout or Route Handler
→ cache lookup
→ Server Components and data access
→ Suspense and streaming
→ HTML + RSC payload
→ Client Components hydrate
→ user interaction
→ Server Action or HTTP request
→ validation + authentication + authorization
→ transaction / side effect
→ cache invalidation
→ refreshed RSC tree
→ observability and deployment feedbackCada flecha puede introducir latencia, error, seguridad o caché.
Resuelve DNS, TLS, CDN, WAF, regiones, funciones y límites. Una respuesta puede salir de CDN sin ejecutar tu código.
Relaciona URL y método con segmentos, layouts, pages, slots, Proxy o Route Handlers.
Ejecuta Server Components, lee datos y produce RSC/HTML. No envía su implementación al navegador.
Hidrata Client Components, conserva state durante navegación y maneja eventos.
Autentica, autoriza, consulta, transforma DTOs y define transacciones.
Reutiliza resultados por request, entre requests, en router, CDN o proveedor. Cada capa posee key y lifetime distintos.
Build, deployment, metrics, logs, security patches, backups y rollback mantienen el sistema real.
Determina:
GET /dashboard/orders?status=pending
POST Server Action
POST /api/webhooks/payment
GET /_next/image?... No todas atraviesan React. Un webhook termina en Route Handler; un asset puede terminar en CDN.
app/dashboard/layout.tsx
app/dashboard/orders/page.tsx
app/dashboard/orders/loading.tsx
app/dashboard/orders/error.tsxRoute groups no aparecen en URL. Dynamic segments capturan strings y deben validarse. Parallel routes e intercepting routes dependen de navegación y hard refresh.
Antes de la route pueden actuar redirects de config, Proxy y rewrites.
Clasifica:
build-time
request-time server
client hydration
client interaction
background workerEjemplos:
NEXT_PUBLIC_*: build-time bundle.Un mismo archivo puede participar en varias fases, pero una operación concreta ocurre en una.
Úsalo para:
Necesita "use client" para:
Server page
├─ heading
├─ authorized data
└─ Client filter controlsNo significa “todo server” ni “todo client”. La boundary debe ser mínima y coherente con ownership del state.
Server → client necesita valores serializables:
No pases:
Usa DTOs mínimos por caso de uso.
En Server Components:
component
→ DAL/service
→ DB/APINo necesitas llamar tu propio /api desde servidor.
Para datos independientes:
const aPromise = getA();
const bPromise = getB();
const [a, b] = await Promise.all([aPromise, bPromise]);O separa regiones con Suspense.
Define siempre:
No clasifiques solo la route. Clasifica regiones:
static synchronous UI
cached reusable data
request-time private/fresh dataCon Cache Components:
static → shell
use cache → reusable result
Dynamic API under Suspense → request-time holeLa decisión depende de:
React.cache → dedupe within request
use cache → reuse between requests
prerendered route output → shell/HTML/RSC
client router cache → browser navigation
HTTP/CDN cache → response headers/platform
data source cache → Redis/provider/DBAntes de “limpiar caché” pregunta:
Suspense declara fallback. Streaming envía resultados conforme terminan.
shell
→ metrics boundary
→ orders boundary
→ recommendations boundaryNo reduce la duración de la query. Evita que una dependencia lenta bloquee todo.
Loading, empty, not found y error son estados distintos.
HTML visible no significa handlers listos.
server HTML
→ browser paints
→ JS downloads
→ Client Components hydrate
→ events readyReduce JavaScript, prioriza interacción crítica y prueba CPU/red lenta.
<Link> puede prefetchear segmentos. La navegación cliente solicita RSC payload y preserva layouts/state compatibles.
click
→ RSC request
→ server/cache
→ merge tree
→ update focus and scrollHard navigation crea documento nuevo y reinicia state.
Search params representan estado compartible; local state representa interacción efímera.
Flujo seguro:
intent
→ Action or Handler
→ parse/validate
→ authenticate
→ authorize resource and action
→ enforce business rule
→ transaction/idempotency
→ commit
→ invalidate
→ result/redirect/refreshUna Server Action vive en servidor, pero es invocable. Todo argumento es no confiable.
Después del commit:
updateTag para read-your-own-writes.revalidateTag(..., "max") para stale-while-revalidate.revalidatePath cuando el path es la unidad adecuada.router.refresh para solicitar representación, no para invalidar servidor.Diseña tags por entidad, colección y tenant.
principal
+ action
+ resource
+ tenant
+ state
→ allow/denyUI y Proxy mejoran UX. Protección real vive en DAL/Action/Handler y puede reforzarse en DB.
Authentication identifica. Authorization decide.
La aplicación valida intención; PostgreSQL protege integridad:
No resuelvas concurrencia solo con botones disabled o consultas previas.
Clasifica:
expected business result
unexpected application error
dependency timeout
platform failure
client/hydration errorSuspense maneja espera, no errores.
Correlaciona:
request ID
→ Proxy
→ route
→ DAL
→ DB
→ provider
→ Action resultUsa:
No registres tokens, passwords ni payloads sensibles.
source
→ CI verification
→ production build
→ preview
→ migrations
→ deploy
→ smoke tests
→ rollout
→ monitorLa plataforma debe soportar las features usadas: streaming, Actions, images, cache, revalidation y runtime.
Vercel es una opción integrada; Node server, containers y adapters son alternativas.
GET /products/domisys
→ route match
→ metadata and page share loader
→ cache lookup by slug
→ authorized/public DAL
→ HTML + RSC
→ client gallery hydratesPreguntas de diagnóstico:
submit order
→ Action receives FormData
→ schema
→ session
→ tenant policy
→ transaction order + stock
→ outbox
→ commit
→ updateTag order/list
→ UI receives new treePreguntas:
Link visible
→ possible prefetch
→ click
→ RSC navigation
→ cached layouts preserved
→ loading boundary
→ streamed data
→ focus/scroll updatePrueba también URL directa; puede comportarse diferente con slots/interception.
browser is untrusted
Proxy is early filter
Server route is trust boundary
DAL scopes data
DB enforces integrity
external providers are untrusted dependenciesAmenazas:
network
+ CDN/TTFB
+ server/data
+ streaming
+ RSC payload
+ JS bundle
+ hydration
+ images/fonts/scripts
+ interaction workNo existe una optimización única. Mide el cuello real.
indexable URL
→ status 200
→ canonical metadata
→ useful server-rendered content
→ internal links
→ sitemap
→ crawler accessMetadata no garantiza ranking. Robots no protege. JSON-LD debe reflejar contenido visible.
semantic HTML
+ keyboard
+ focus after navigation
+ announced pending/errors
+ responsive/reduced motion
+ testingNext.js no vuelve accesible una UI automáticamente. Routing cliente requiere preservar contexto y foco.
app route files
→ presentation and coordination
features/domain
→ use cases and rules
DAL/repositories
→ authorized data access
infrastructure
→ DB/providers/cacheNo conviertas app en toda la arquitectura. Routing y dominio son ejes distintos.
concept durable
release-specific behavior
platform-specific capabilityMantén conceptos en notas temáticas y cambios temporales en compatibilidad. Actualiza mediante branch, codemods, tests, preview y observabilidad.
¿se necesita para HTML inicial?
├─ no → client interaction/query may fit
└─ sí → Server Component
↓
¿es compartible y reusable?
├─ sí → cache with key/lifetime/tag
└─ no → request-time under Suspense
↓
¿es externo?
├─ sí → validate + timeout
└─ DB → scope + select + transaction rules¿debe sobrevivir/share URL?
├─ sí → search params/path
└─ no
├─ server authoritative → server data
├─ preference/session → cookie/DB
├─ local interaction → useState/useReducer
└─ cross-tree client coordination → Context/store¿consumidor es UI React propia?
├─ sí → Server Action may fit
└─ no → Route Handler/API
¿webhook/third party/mobile?
→ Route HandlerEl servicio de dominio queda separado de ambos.
¿puede compartirse entre usuarios?
├─ no → request-time/private strategy
└─ sí
↓
¿cuánto stale tolera?
↓
cacheLife
↓
¿qué evento cambia el dato?
↓
cacheTag + invalidation¿requiere runtime server?
├─ no → static export possible
└─ sí
↓
Node server / container / serverless / adapter
↓
verify streaming, cache, images, regions, jobsCuando “Next.js no funciona”, responde en este orden:
Explica render, state, Suspense, hydration y Server Components.
Explica event loop, runtime, streams, módulos, procesos y servidores.
Ayuda a comparar middleware/control HTTP con Route Handlers y Proxy.
Asegura persistencia, transacciones, constraints, índices y concurrencia.
Empaqueta self-hosting y define runtime reproducible.
Define boundaries, casos de uso, trade-offs, observabilidad y evolución.
Ignora servidor, caché, build y plataforma.
Server Components describen dónde se ejecuta el componente; SSR describe generación de HTML. Se relacionan, pero no son sinónimos.
Cache Components permite composición por regiones.
La implementación es servidor; la entrada es invocable.
Solo solicita una representación.
Es una plataforma; el framework puede ejecutarse en otros targets.
Explica qué ocurre cuando un gerente abre /dashboard/orders?status=pending, cambia un pedido a confirmed y otro usuario ve la actualización.
El navegador solicita la URL; plataforma, Proxy y router resuelven layouts/page. El servidor verifica sesión y tenant, valida search params y consulta pedidos mediante DAL. La shell y tabla se envían como HTML/RSC; controles cliente se hidratan. Al confirmar, una Server Action valida input, vuelve a autenticar y autorizar la orden, verifica su estado dentro de una transacción, actualiza DB y registra auditoría/outbox. Después invalida las tags del detalle, listado y métricas. El actor recibe el árbol actualizado. El otro usuario no recibe el cambio solo por invalidación: lo verá al navegar/refrescar/pollear o mediante un evento realtime que provoque una nueva lectura autorizada.
Esta nota no reemplaza las demás. Funciona como mapa: cuando un concepto no esté claro, vuelve a la nota especializada y después regresa a este flujo completo.