explica cómo el sitio de documentación logra cargas de páginas estáticas rápidas mientras mantiene la funcionalidad del modo de edición del CMS
Esta guía explica cómo el sitio de documentación logra cargas rápidas de páginas estáticas mientras mantiene la funcionalidad del modo de edición del CMS.
Usamos dos rutas para el mismo contenido:
app/
├── [...slug]/page.tsx # Producción: force-static (rápido)
└── preview/[...slug]/page.tsx # Modo de edición: force-dynamic (lee searchParams)
Un middleware proxy reescribe de forma transparente las solicitudes de modo de edición:
Solicitud del usuario: /en/headless/quickstart?edit_mode=true
↓
El proxy detecta ?edit_mode=true
↓
Reescritura interna a: /preview/en/headless/quickstart?edit_mode=true
↓
La ruta dinámica se renderiza con envoltorios de edición
El usuario nunca ve /preview en su URL: es una reescritura interna.
// app/[...slug]/page.tsx
export const dynamic = 'force-static';
export const revalidate = 60;
export default async function Page({ params }) {
// Sin searchParams: la página es completamente estática
// app/preview/[...slug]/page.tsx
export const dynamic = 'force-dynamic';
export default async function PreviewPage({ params, searchParams }) {
// searchParams disponibles: puede detectar edit_mode
return <ParametricRoutePage params={params
?edit_mode=true de la URL// src/proxy.ts
export const proxy = async (request: NextRequest) => {
const { pathname, searchParams } = request.nextUrl;
const editMode = searchParams.get('edit_mode');
| Escenario | Tiempo de respuesta | Renderizado |
|---|---|---|
| Página de producción (en caché) | ~50-100 ms | Estática desde el CDN |
| Página de producción (obsoleta) | ~50-100 ms + actualización en segundo plano | Estática, luego ISR |
| Modo de edición | ~500-1500 ms | SSR dinámico |
La configuración revalidate = 60 habilita ISR. Esto NO significa que las páginas se vuelvan a calcular cada 60 segundos.
ISR utiliza un patrón de stale-while-revalidate:
Llega una solicitud:
→ ¿La página en caché tiene menos de 60 s? → Servir desde la caché (instantáneo)
→ ¿La página en caché tiene más de 60 s? → Servir la caché obsoleta (instantáneo)
+ revalidar en segundo plano para la siguiente solicitud
No hay solicitudes = No hay recálculo. Nunca.
Ejemplo:
La ventana de 60 segundos es una red de seguridad. Idealmente, usaríamos revalidación bajo demanda mediante webhooks cuando cambia el contenido del CMS.
| Caso de uso | URL | Ruta utilizada |
|---|---|---|
| Navegación normal | /en/headless/quickstart | Estática |
| Constructor de plantillas del CMS | /en/headless/quickstart?edit_mode=true | Vista previa (mediante reescritura) |
| Vista previa de bloque de IA | /en/headless/quickstart?ai_preview=1 | Vista previa (mediante reescritura) |
El enfoque simple (sin force-static, sin ruta de vista previa) funciona, pero es lento:
// Enfoque simple: funciona pero tarda ~1-2 s por solicitud
export default async function Page({ params, searchParams }) {
return <ParametricRoutePage params={params} searchParams={searchParams} />;
}
Esto se renderiza dinámicamente en cada solicitud. Para un sitio de documentación con muchas páginas, esto significa:
La arquitectura de doble ruta nos da lo mejor de ambos mundos: velocidad estática para los lectores y funcionalidad dinámica para los editores.