Como montar un front headless con la REST API de WordPress en WordPress

Contents

Introducción

Este tutorial detalla, paso a paso y con ejemplos prácticos, cómo montar un front headless consumiendo la REST API de WordPress. Se cubren desde la preparación del backend (WordPress), la configuración de endpoints, autenticación, hasta ejemplos de consumo desde el front (fetch, Next.js/React) y consideraciones de rendimiento, seguridad y SEO. Los ejemplos de código están incluidos y formateados para su copia directa.

Por qué usar WordPress headless

  • Flexibilidad del front: puedes usar React, Vue, Svelte, o cualquier framework moderno.
  • Separación de responsabilidades: WordPress actúa sólo como CMS y API.
  • Mejor experiencia de desarrollo front: herramientas modernas, SSR/SSG y despliegues en plataformas JAMstack.
  • Escalabilidad: CDN y arquitectura desacoplada para mejorar rendimiento.

Requisitos previos

  • Instalación de WordPress (mínimo PHP 7.4 , MySQL/MariaDB). La REST API está integrada desde WP 4.7.
  • Acceso FTP/SSH o panel para instalar plugins y editar el tema o un plugin personalizado.
  • Conocimientos básicos de JavaScript (fetch/axios) y opcionalmente React/Next.js o Vue/Nuxt.
  • HTTPS en producción (autenticación segura, cookies y tokens).

Configurar WordPress para headless

Permalinks y REST

En Ajustes → Enlaces permanentes, usar una estructura distinta a “Simple” (p. ej. “Nombre de entrada”). Eso asegura que los endpoints REST y rutas funcionen correctamente.

Exponer Custom Post Types y campos personalizados

Al registrar un custom post type, asegúrate de activar show_in_rest y, si usas campos personalizados (ACF), exponerlos o usar plugins que los publiquen en la REST API.

register_post_type(book, array(
  label => Books,
  public => true,
  show_in_rest => true,
  rest_base => books,
  supports => array(title,editor,thumbnail)
))

Endpoints básicos de la REST API

  • /wp-json/wp/v2/posts — lista de posts.
  • /wp-json/wp/v2/pages — páginas.
  • /wp-json/wp/v2/media — medios.
  • /wp-json/wp/v2/categories, /tags — taxonomías.
  • /wp-json/wp/v2/types — tipos de contenido registrados.

La respuesta incluye campos HTML renderizados (title.rendered, content.rendered) y metadatos.

Uso de parámetros para optimizar respuestas

  • per_page, page — paginación.
  • _fields — devolver sólo los campos necesarios.
  • _embed — incluir relaciones (por ejemplo, featured media) para evitar llamadas adicionales.
fetch(https://example.com/wp-json/wp/v2/posts?per_page=5_fields=id,title,slug,excerpt,date_embed)
  .then(r => r.json())
  .then(posts => console.log(posts))

Autenticación

Para acciones que requieren autenticación (crear, editar, obtener context=edit), existen varias opciones:

  • Application Passwords (WP 5.6 ): muy prácticas para integraciones servidor-servidor o herramientas CLI.
  • JWT Authentication: buena para SPA, devuelve token y se usa en el header Authorization: Bearer TOKEN.
  • Cookies y nonces: cuando front y WP comparten dominio, usar la autenticación por cookies del propio WordPress.

Ejemplo: Application Password (Basic Auth)

curl --user usuario:app-password -X POST https://example.com/wp-json/wp/v2/posts 
 -H Content-Type: application/json 
 -d {title:Mi post desde API,status:publish}

Ejemplo: JWT (obtener token y usarlo)

curl -X POST https://example.com/wp-json/jwt-auth/v1/token 
 -d username=adminpassword=miContrasena
fetch(https://example.com/wp-json/wp/v2/posts, {
  headers: { Authorization: Bearer TU_TOKEN }
})

Crear endpoints personalizados

Si necesitas lógica específica o endpoints agregados, usa register_rest_route en un plugin o en functions.php (mejor en plugin propio para mantener la lógica fuera del tema).

add_action(rest_api_init, function(){
  register_rest_route(miapi/v1, /stats, array(
    methods => GET,
    callback => function(request){
      count = wp_count_posts()->publish
      return rest_ensure_response(array(posts_count => count))
    },
    permission_callback => __return_true
  ))
})

Incluye siempre permission_callback robustos cuando el endpoint manipule datos sensibles o requiera permisos.

Ejemplos prácticos de consumo desde el front

Fetch simple (cliente)

fetch(https://example.com/wp-json/wp/v2/posts?per_page=5_fields=id,title,slug,excerpt,date_embed)
  .then(res => {
    // cabeceras con paginado: X-WP-Total, X-WP-TotalPages
    console.log(res.headers.get(X-WP-Total), res.headers.get(X-WP-TotalPages))
    return res.json()
  })
  .then(data => {
    data.forEach(post => {
      console.log(post.title.rendered, post._embedded?.[wp:featuredmedia]?.[0]?.source_url)
    })
  })

Next.js — getStaticProps (SSG con revalidación)

export async function getStaticProps(){
  const res = await fetch(https://example.com/wp-json/wp/v2/posts?per_page=10_embed)
  const posts = await res.json()
  return { props: { posts }, revalidate: 60 } // revalida cada 60s
}

Componente React que renderiza posts

function PostsList({ posts }){
  return (
    React.createElement(ul, null,
      posts.map(p =>
        React.createElement(li, {key: p.id},
          React.createElement(h3, null, p.title.rendered),
          React.createElement(div, {dangerouslySetInnerHTML:{__html: p.excerpt.rendered}})
        )
      )
    )
  )
}

Manejo de medios y URLs

  • Las URLs de medios vienen completas en source_url. Si migras dominios, ten cuidado con enlaces absolutos.
  • Usa el parámetro _embed para traer featured media junto al post y evitar llamadas extra.
fetch(https://example.com/wp-json/wp/v2/posts?_embed)
  .then(r => r.json())
  .then(posts => {
    posts.forEach(p => {
      const img = p._embedded?.[wp:featuredmedia]?.[0]?.source_url  null
      console.log(p.title.rendered, img)
    })
  })

Rendimiento y caching

  • Usa _fields para limitar la respuesta y reducir tamaño.
  • Implementa cache en el servidor (plugins como WP REST Cache) o en proxy (Varnish, CDN).
  • Utiliza cabeceras ETag / If-Modified-Since para evitar transferencias innecesarias.
  • Regenera sólo lo estrictamente necesario cuando usas SSG usa webhooks para desencadenar builds en Netlify/Vercel.

SEO y previews

Para SEO con headless hay varias opciones:

  • SSR (Next.js) o SSG para que los buscadores indexen contenido estático/servidor renderizado.
  • Mantener metadatos (title, meta description) en el front provenientes de campos de WordPress o plugins SEO (exponer los campos necesarios mediante ACF o plugin).
  • Previews: habilitar endpoints que devuelvan contenido en estado preview o usar autenticación para vistas preliminares. En Next.js puedes usar rutas de preview que llamen a WP con credenciales y muestren el contenido sin publicarlo.

Seguridad

  • Limita permisos en endpoints personalizados con permission_callback. No uses __return_true en endpoints que modifiquen datos.
  • Valida y sanitiza datos de entrada en los callbacks.
  • No expongas credenciales en el cliente. Para operaciones seguras, actúa desde un backend intermedio o usa Application Passwords en servidor.
  • Usa HTTPS siempre en producción.

Configuración CORS y servidor

Si el front se sirve desde otro dominio, configurar CORS para permitir peticiones a la API. Para Apache/Nginx, permitir orígenes específicos y métodos necesarios. Evitar en producción especificar dominios concretos.

Plugins recomendados

  • WP REST Cache / WP Super Cache / FastCGI cache: para mejorar rendimiento de endpoints.
  • JWT Authentication for WP REST API: si necesitas tokens JWT.
  • ACF to REST API: para exponer campos de ACF en la API.
  • WPGraphQL: alternativa si prefieres GraphQL en lugar de REST.

Buenas prácticas y checklist

  1. Activar permalinks amigables.
  2. Registrar CPTs con show_in_rest => true.
  3. Usar _fields y _embed para optimizar payloads.
  4. Configurar cache en servidor y usar CDNs para assets.
  5. Implementar autenticación segura (app passwords o JWT) y no exponer secrets en el cliente.
  6. Manejar previews y permisos para evitar exposición de contenido no publicado.
  7. Probar respuestas y paginación (X-WP-Total, X-WP-TotalPages).

Ejemplos de errores comunes y soluciones

  • 404 en endpoints REST: revisar permalinks y .htaccess/rewrites en Nginx.
  • Campos personalizados no aparecen: asegurarse de que show_in_rest esté activo o usar plugin para exponer ACF.
  • CORS bloqueado: configurar cabeceras Access-Control-Allow-Origin en el servidor.
  • Autenticación falla: comprobar que el plugin (JWT) esté configurado y que la hora del servidor esté correcta (tokens temporales).

Flujo típico de desarrollo y despliegue

  1. Desarrollar API en entorno staging de WP (plugins, CPTs, campos).
  2. Crear front local (React/Next/Nuxt) consumiendo endpoints.
  3. Configurar previews y credenciales para previsualización en staging.
  4. Configurar webhooks que disparen builds en Netlify/Vercel al publicar contenido en WordPress.
  5. Poner en producción: HTTPS, CDN, reglas de cache y monitoreo de rendimiento.

Notas finales

Un enfoque headless con la REST API de WordPress ofrece gran flexibilidad: puedes aprovechar WordPress como CMS robusto mientras construyes experiencias frontend modernas y optimizadas. Planifica la autenticación, la exposición de campos personalizados y el flujo de previews antes de pasar a producción. Usa herramientas de caching y revalidación para escalar y mantener tiempos de respuesta bajos.



Acepto donaciones de BAT's mediante el navegador Brave 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *