WordPress Headless con Next.js y GraphQL
Introducción: El nuevo paradigma del CMS desacoplado
La arquitectura de sitios web ha evolucionado drásticamente. Durante años, WordPress fue sinónimo de un monolito: backend y frontend unidos, con temas PHP y una base de datos MySQL. Sin embargo, la necesidad de mayor velocidad, seguridad y flexibilidad ha impulsado el modelo WordPress headless. En este enfoque, WordPress actúa únicamente como backend o headless CMS, mientras que el frontend se construye con tecnologías modernas como Next.js y la capa de datos se sirve mediante GraphQL.
Este artículo es una guía técnica profunda para implementar un stack JAMstack WordPress en 2025, combinando la potencia del editor de bloques (Gutenberg) con la velocidad de una aplicación React renderizada en el servidor. Exploraremos desde la configuración inicial hasta la optimización para producción, incluyendo estrategias de caché y despliegue.
¿Por qué elegir WordPress Headless en 2025?
Ventajas frente al WordPress tradicional
El modelo headless no es una moda pasajera. Para 2025, se consolida como la opción preferida para proyectos que requieren:
- Rendimiento extremo: Next.js genera páginas estáticas (SSG) o renderiza en el servidor (SSR), eliminando la sobrecarga de temas PHP y plugins pesados.
- Seguridad mejorada: Al separar el frontend, se reduce la superficie de ataque. No hay archivos PHP ejecutables en el servidor web público.
- Experiencia de desarrollo moderna: Usamos React, TypeScript, Tailwind CSS y herramientas de build avanzadas (Webpack, Turbopack).
- Flexibilidad multicanal: El mismo backend WordPress puede servir datos a una web, una app móvil (React Native) y un kiosco interactivo.
[INFO] No confundas headless con sin cabeza. WordPress sigue siendo el cerebro; solo separamos la capa de presentación.
¿Cuándo NO usar headless?
A pesar de sus ventajas, este stack no es ideal para:
- Sitios simples con pocos contenidos (un blog personal con 5 visitas/día).
- Clientes que necesitan editar el frontend visualmente (sin un page builder como Elementor o WPBakery).
- Presupuestos muy ajustados (el coste de hosting y desarrollo inicial es mayor).
Stack técnico: Las piezas del rompecabezas
Next.js como frontend
Next.js es el framework React más popular para aplicaciones híbridas. Ofrece:
- Static Site Generation (SSG): Ideal para páginas que no cambian frecuentemente (home, about, blog posts).
- Incremental Static Regeneration (ISR): Permite actualizar contenido estático sin reconstruir todo el sitio.
- Server-Side Rendering (SSR): Para contenido dinámico o personalizado.
- API Routes: Podemos crear endpoints serverless que actúen como proxy entre el frontend y WordPress.
GraphQL como capa de datos
GraphQL revoluciona la forma de consultar datos. A diferencia de REST, donde cada endpoint devuelve una estructura fija, GraphQL permite:
- Consultas exactas: Pedimos solo los campos que necesitamos. Ejemplo:
title,date,featuredImagey nada más. - Múltiples recursos en una sola petición: Obtenemos posts, categorías y metadatos en un único
query. - Documentación viva: GraphiQL IDE nos permite explorar el esquema completo.
Para WordPress, el plugin WPGraphQL (gratuito y de código abierto) expone todo el contenido (posts, páginas, usuarios, comentarios, campos personalizados) como un endpoint GraphQL.
WordPress como Headless CMS
WordPress sigue siendo el administrador de contenido. Necesitamos:
- Una instalación limpia de WordPress (preferiblemente en un subdominio o ruta separada).
- Plugins esenciales:
- WPGraphQL: Expone los datos.
- WPGraphQL for ACF (si usas Advanced Custom Fields).
- WPGraphQL CORS (para permitir peticiones desde el frontend).
- Yoast SEO o Rank Math (con soporte GraphQL para metadatos).
Configuración paso a paso
1. Preparar el backend WordPress
- Instala WordPress en tu servidor (puede ser local con LocalWP o en un VPS).
- Activa un tema mínimo como Twenty Twenty-Four (o un tema vacío como _s).
- Instala y activa los plugins:
wp plugin install wp-graphql --activate wp plugin install wp-graphql-cors --activate - Configura WPGraphQL CORS en Ajustes > GraphQL CORS. Añade el dominio de tu frontend (ej:
http://localhost:3000). - Crea algunos posts con categorías y una imagen destacada para tener datos de prueba.
[WARNING] Nunca expongas el endpoint GraphQL (
/graphql) sin protección en producción si tu frontend es público. Usa API keys o tokens JWT para mutaciones.
2. Crear el proyecto Next.js
npx create-next-app@latest nextjs-headless-wp --typescript --tailwind --eslint
cd nextjs-headless-wp
npm install graphql @apollo/client
Crea un archivo lib/apollo-client.ts para configurar Apollo Client:
import { ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
uri: process.env.WP_GRAPHQL_URL, // Ej: 'https://tudominio.com/graphql'
cache: new InMemoryCache(),
});
export default client;
3. Primera consulta GraphQL
Creamos un componente PostList que obtiene los últimos posts. En app/page.tsx (App Router de Next.js 13+):
import { client } from '@/lib/apollo-client';
import { gql } from '@apollo/client';
const GET_POSTS = gql`
query GetPosts {
posts(first: 10) {
nodes {
id
title
slug
date
featuredImage {
node {
sourceUrl
altText
}
}
}
}
}
`;
export default async function Home() {
const { data } = await client.query({ query: GET_POSTS });
const posts = data.posts.nodes;
return (
<main>
<h1>Últimos artículos</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
<a href={`/posts/${post.slug}`}>
<h2>{post.title}</h2>
<p>{new Date(post.date).toLocaleDateString()}</p>
</a>
</li>
))}
</ul>
</main>
);
}
4. Páginas dinámicas con SSG
Para generar páginas individuales de posts, usamos generateStaticParams y getStaticProps (o funciones equivalentes en App Router):
// app/posts/[slug]/page.tsx
export async function generateStaticParams() {
const { data } = await client.query({
query: gql`query { posts { nodes { slug } } }`,
});
return data.posts.nodes.map((post: any) => ({ slug: post.slug }));
}
export default async function PostPage({ params }: { params: { slug: string } }) {
const { data } = await client.query({
query: gql`
query PostBySlug($slug: String!) {
postBy(slug: $slug) {
title
content
date
author { node { name } }
}
}
`,
variables: { slug: params.slug },
});
const post = data.postBy;
return (
<article>
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content }} />
</article>
);
}
[TIP] Para manejar contenido enriquecido de Gutenberg, considera usar
@wordpress/block-libraryo librerías comoreact-html-parsercon estilos personalizados.
Optimización para producción y SEO
Estrategias de caché
- ISR: Configura
revalidateen segundos para actualizar páginas sin rebuild completo. - CDN: Usa Vercel, Netlify o Cloudflare Pages para servir estáticos desde el edge.
- Caché de GraphQL: Implementa persisted queries con Apollo o utiliza
@apollo/clientconInMemoryCache.
SEO en un entorno headless
- Metadatos dinámicos: Next.js tiene
generateMetadatapara establecer title, description y Open Graph tags. - Sitemap: Genera un
sitemap.xmldinámico consultando todos los slugs de WordPress. - RSS Feed: Crea un endpoint API Route que devuelva un feed RSS consumible por lectores.
Ejemplo de metadatos en App Router:
export async function generateMetadata({ params }: { params: { slug: string } }): Promise<Metadata> {
const { data } = await client.query({
query: gql`
query SeoData($slug: String!) {
postBy(slug: $slug) {
seo { title metaDesc }
featuredImage { node { sourceUrl } }
}
}
`,
variables: { slug: params.slug },
});
return {
title: data.postBy.seo.title,
description: data.postBy.seo.metaDesc,
openGraph: { images: [{ url: data.postBy.featuredImage?.node.sourceUrl }] },
};
}
Despliegue continuo
- Conecta tu repositorio de GitHub con Vercel.
- Configura las variables de entorno (
WP_GRAPHQL_URL,NEXT_PUBLIC_WP_URL). - Cada push a
maingenera un nuevo build con ISR automático.
Casos de uso reales y ejemplos
Sitios corporativos multilingüe
WordPress con Polylang o WPML expone traducciones via GraphQL. Next.js puede generar rutas /es/, /en/ con SSG.
Portafolios con CMS visual
El cliente edita sus proyectos en WordPress (con ACF para campos personalizados) y el frontend muestra un grid interactivo con filtros.
E-commerce headless
WooCommerce + WPGraphQL + Next.js. Los carritos se manejan en el frontend (usando React Context) y los pedidos se envían a WordPress mediante mutaciones GraphQL.
[INFO] Para e-commerce, considera la latencia adicional. Usa SSR solo para páginas de producto críticas y SSG para catálogos.
Desafíos comunes y cómo resolverlos
Autenticación
Para contenido privado (miembros, cursos), necesitas JWT Authentication en WordPress y manejar tokens en el frontend con cookies HTTP-only.
Preview de contenido
WordPress tiene un sistema de preview que requiere sesiones. Solución: usa WPGraphQL Preview y un endpoint especial en Next.js que renderice el borrador.
Campos personalizados (ACF)
Instala wp-graphql-acf y configura los grupos de campos para que sean accesibles en GraphQL. Luego consulta post.acfFields { miCampo }.
Conclusión: El futuro del JAMstack WordPress
La combinación de WordPress headless, Next.js y GraphQL no es solo una tendencia; es una arquitectura probada que ofrece lo mejor de ambos mundos: la facilidad de gestión de contenido de WordPress y la potencia de un frontend moderno y rápido. En 2025, veremos más empresas adoptando este stack para proyectos que requieren escalabilidad, rendimiento y una experiencia de desarrollo superior.
Si estás comenzando, te recomiendo:
- Probar con un proyecto pequeño (blog personal) para familiarizarte con WPGraphQL.
- Migrar gradualmente: primero el blog, luego páginas estáticas, finalmente secciones dinámicas.
- Invertir en un buen hosting para WordPress (Kinsta, WP Engine con soporte headless) y un frontend en Vercel.
El ecosistema headless está maduro. Ahora es el momento de dar el salto.
¿Ya has implementado un proyecto headless? Cuéntame tu experiencia en los comentarios.
