Introducción/Guías/Modo Borrador

Cómo previsualizar contenido con el Modo Borrador en Next.js

En la documentación de Páginas y la documentación de Obtención de Datos, hablamos sobre cómo prerrenderizar una página en tiempo de compilación (Generación Estática) usando getStaticProps y getStaticPaths.

La Generación Estática es útil cuando tus páginas obtienen datos de un CMS headless. Sin embargo, no es ideal cuando estás escribiendo un borrador en tu CMS headless y quieres verlo inmediatamente en tu página. Querrías que Next.js renderice estas páginas en tiempo de solicitud en lugar de tiempo de compilación, y que obtenga el contenido del borrador en vez del contenido publicado. Querrías que Next.js evite la Generación Estática solo para este caso específico.

Next.js tiene una función llamada Modo Borrador que resuelve este problema. Aquí hay instrucciones sobre cómo usarlo.

Paso 1: Crear y acceder a la ruta API

Revisa primero la documentación de Rutas API si no estás familiarizado con las Rutas API de Next.js.

Primero, crea la ruta API. Puede tener cualquier nombre, por ejemplo pages/api/draft.ts.

En esta ruta API, necesitas llamar a setDraftMode en el objeto de respuesta.

export default function handler(req, res) {
  // ...
  res.setDraftMode({ enable: true })
  // ...
}

Esto establecerá una cookie para activar el modo borrador. Las solicitudes posteriores que incluyan esta cookie activarán el Modo Borrador, cambiando el comportamiento para páginas generadas estáticamente (más sobre esto después).

Puedes probar esto manualmente creando una ruta API como la siguiente y accediendo a ella manualmente desde tu navegador:

pages/api/draft.ts
// ejemplo simple para probarlo manualmente desde tu navegador.
export default function handler(req, res) {
  res.setDraftMode({ enable: true })
  res.end('El modo borrador está activado')
}

Si abres las herramientas de desarrollo de tu navegador y visitas /api/draft, notarás un encabezado de respuesta Set-Cookie con una cookie llamada __prerender_bypass.

Acceso seguro desde tu CMS Headless

En la práctica, querrás llamar a esta ruta API de forma segura desde tu CMS headless. Los pasos específicos variarán según el CMS headless que uses, pero aquí hay algunos pasos comunes que podrías seguir.

Estos pasos asumen que tu CMS headless soporta establecer URLs de borrador personalizadas. Si no es así, aún puedes usar este método para proteger tus URLs de borrador, pero necesitarás construir y acceder a la URL de borrador manualmente.

Primero, debes crear un token secreto usando un generador de tokens de tu preferencia. Este secreto solo lo conocerán tu aplicación Next.js y tu CMS headless. Este secreto evita que personas sin acceso a tu CMS accedan a las URLs de borrador.

Segundo, si tu CMS headless soporta establecer URLs de borrador personalizadas, especifica lo siguiente como la URL de borrador. Esto asume que tu ruta API de borrador está ubicada en pages/api/draft.ts.

Terminal
https://<tu-sitio>/api/draft?secret=<token>&slug=<ruta>
  • <tu-sitio> debe ser tu dominio de despliegue.
  • <token> debe ser reemplazado con el token secreto que generaste.
  • <ruta> debe ser la ruta de la página que quieres ver. Si quieres ver /posts/foo, entonces debes usar &slug=/posts/foo.

Tu CMS headless podría permitirte incluir una variable en la URL de borrador para que <ruta> pueda establecerse dinámicamente basado en los datos del CMS, así: &slug=/posts/{entry.fields.slug}

Finalmente, en la ruta API de borrador:

  • Verifica que el secreto coincida y que el parámetro slug exista (si no, la solicitud debe fallar).
  • Llama a res.setDraftMode.
  • Luego redirige el navegador a la ruta especificada por slug. (El siguiente ejemplo usa una redirección 307).
export default async (req, res) => {
  // Verifica el secreto y los parámetros siguientes
  // Este secreto solo debe ser conocido por esta ruta API y el CMS
  if (req.query.secret !== 'MI_TOKEN_SECRETO' || !req.query.slug) {
    return res.status(401).json({ message: 'Token inválido' })
  }

  // Consulta el CMS headless para verificar si el `slug` proporcionado existe
  // getPostBySlug implementaría la lógica necesaria para consultar el CMS headless
  const post = await getPostBySlug(req.query.slug)

  // Si el slug no existe, evita que se active el modo borrador
  if (!post) {
    return res.status(401).json({ message: 'Slug inválido' })
  }

  // Activa el Modo Borrador estableciendo la cookie
  res.setDraftMode({ enable: true })

  // Redirige a la ruta del post obtenido
  // No redirigimos a req.query.slug para evitar vulnerabilidades de redirección abierta
  res.redirect(post.slug)
}

Si tiene éxito, el navegador será redirigido a la ruta que deseas ver con la cookie de modo borrador.

Paso 2: Actualizar getStaticProps

El siguiente paso es actualizar getStaticProps para soportar el modo borrador.

Si solicitas una página que tiene getStaticProps con la cookie establecida (vía res.setDraftMode), entonces getStaticProps será llamado en tiempo de solicitud (en lugar de tiempo de compilación).

Además, será llamado con un objeto context donde context.draftMode será true.

export async function getStaticProps(context) {
  if (context.draftMode) {
    // datos dinámicos
  }
}

Usamos res.setDraftMode en la ruta API de borrador, por lo que context.draftMode será true.

Si también estás usando getStaticPaths, entonces context.params también estará disponible.

Obtener datos de borrador

Puedes actualizar getStaticProps para obtener datos diferentes basados en context.draftMode.

Por ejemplo, tu CMS headless podría tener un endpoint API diferente para posts en borrador. Si es así, puedes modificar la URL del endpoint API como se muestra a continuación:

export async function getStaticProps(context) {
  const url = context.draftMode
    ? 'https://borrador.ejemplo.com'
    : 'https://produccion.ejemplo.com'
  const res = await fetch(url)
  // ...
}

¡Eso es todo! Si accedes a la ruta API de borrador (con secret y slug) desde tu CMS headless o manualmente, ahora deberías poder ver el contenido en borrador. Y si actualizas tu borrador sin publicarlo, deberías poder ver los cambios.

Establece esto como la URL de borrador en tu CMS headless o accede manualmente, y deberías poder ver el borrador.

Terminal
https://<tu-sitio>/api/draft?secret=<token>&slug=<ruta>

Más detalles

Por defecto, la sesión del Modo Borrador termina cuando se cierra el navegador.

Para limpiar la cookie del Modo Borrador manualmente, crea una ruta API que llame a setDraftMode({ enable: false }):

pages/api/disable-draft.ts
export default function handler(req, res) {
  res.setDraftMode({ enable: false })
}

Luego, envía una solicitud a /api/disable-draft para invocar la Ruta API. Si llamas a esta ruta usando next/link, debes pasar prefetch={false} para evitar eliminar accidentalmente la cookie durante el prefetch.

Funciona con getServerSideProps

El Modo Borrador funciona con getServerSideProps, y está disponible como una clave draftMode en el objeto context.

Nota importante: No debes establecer el encabezado Cache-Control cuando uses el Modo Borrador porque no puede ser omitido. En su lugar, recomendamos usar ISR.

Funciona con Rutas API

Las Rutas API tendrán acceso a draftMode en el objeto de solicitud. Por ejemplo:

export default function myApiRoute(req, res) {
  if (req.draftMode) {
    // obtener datos de borrador
  }
}

Único por cada next build

Se generará un nuevo valor de cookie de bypass cada vez que ejecutes next build.

Esto asegura que la cookie de bypass no pueda ser adivinada.

Nota importante: Para probar el Modo Borrador localmente sobre HTTP, tu navegador necesitará permitir cookies de terceros y acceso al almacenamiento local.

On this page