Apoya mi contenido: 

Tabla de contenido

Headless WordPress + Next.js: cómo migrar y por qué hacerlo

Headless WordPress separa el CMS (panel de administración y contenido) del frontend. En este enfoque, WordPress actúa como fuente de datos y Next.js renderiza el sitio usando SSR/SSG/ISR. El resultado: más rendimiento, mejor DX (Developer Experience) y una arquitectura preparada para escalar.

¿Por qué migrar a Headless con Next.js?

  • Rendimiento superior: páginas estáticas (SSG) e Incremental Static Regeneration (ISR) para latencias muy bajas.
  • SEO sólido: HTML prerenderizado, control total de metadatos y rutas limpias.
  • Experiencias ricas: React + ecosistema moderno (TypeScript, SWR/React Query, Tailwind, etc.).
  • Escalabilidad y seguridad: el panel WP queda aislado; el público consume solo el frontend desplegado en CDN.
  • Multicanal: sirve el mismo contenido a web, apps móviles o dispositivos IoT desde WordPress.

Antes de empezar

  • Actualiza WordPress, PHP (8.1+), base de datos y revisa compatibilidad de plugins.
  • Define modelo de contenido (Entradas, Páginas, CPT, taxonomías, campos ACF, etc.).
  • Elige API: WPGraphQL (recomendado) o REST API nativa.

Stack recomendado

  • WordPress (Headless) con plugins: WPGraphQL, WPGraphQL for ACF (si usas ACF), JWT o OAuth (si requieres auth).
  • Next.js 14/15 con App Router, TypeScript, next/image, next-seo o metadatos del App Router.
  • Vercel (o similar) para despliegue con ISR y CDN global.

Pasos para la migración

1) Preparar WordPress como API

  1. Instala y configura WPGraphQL (o expón rutas de REST API).
  2. Modela el contenido: CPT, taxonomías y campos (ACF). Verifica que el esquema GraphQL exponga todo lo necesario.
  3. Crea webhooks (por ejemplo con WP Webhooks) que notifiquen a Next.js para revalidar páginas al publicar/actualizar.
  4. Activa CORS para permitir peticiones desde tu dominio del frontend.

2) Crear el proyecto Next.js

npx create-next-app@latest headless-wp --ts
cd headless-wp
npm i @apollo/client graphql    # (si usas GraphQL)
# o bien npm i swr axios        # (si prefieres REST + SWR)

Ejemplo con GraphQL (App Router)

lib/apollo-client.ts

import { ApolloClient, InMemoryCache } from "@apollo/client";

export const client = new ApolloClient({
  uri: process.env.NEXT_PUBLIC_WP_GRAPHQL_ENDPOINT,
  cache: new InMemoryCache(),
});

app/page.tsx (home estática con revalidación)

import { gql } from "@apollo/client";
import { client } from "@/lib/apollo-client";

export const revalidate = 60; // ISR: revalida cada 60s

export default async function Home() {
  const { data } = await client.query({
    query: gql`{
      posts(first: 6) { nodes { id title uri excerpt } }
    }`,
    fetchPolicy: "no-cache"
  });

  return (
    <main>
      <h1>Blog</h1>
      <ul>
        {data.posts.nodes.map((p: any) => (
          <li key={p.id}><a href={p.uri}>{p.title}</a></li>
        ))}
      </ul>
    </main>
  );
}

Rutas dinámicas de posts

app/[…slug]/page.tsx

import { gql } from "@apollo/client";
import { client } from "@/lib/apollo-client";

export const revalidate = 300;

export async function generateStaticParams() {
  const { data } = await client.query({
    query: gql`{ posts(first: 100) { nodes { slug } } }`,
    fetchPolicy: "no-cache"
  });
  return data.posts.nodes.map((n: any) => ({ slug: [n.slug] }));
}

export default async function Post({ params }: { params: { slug: string[] } }) {
  const slug = params.slug.at(-1);
  const { data } = await client.query({
    query: gql`query ($slug: ID!) {
      post(id: $slug, idType: SLUG) { title content date featuredImage { node { sourceUrl width height } } }
    }`,
    variables: { slug },
    fetchPolicy: "no-cache"
  });

  const post = data.post;
  return (
    <article>
      <h1>{post.title}</h1>
      {post.featuredImage?.node && (
        <img src={post.featuredImage.node.sourceUrl} width={post.featuredImage.node.width} height={post.featuredImage.node.height} alt={post.title} />
      )}
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
    </article>
  );
}

3) Imágenes y CDN

  • Usa next/image con el dominio del WP configurado en next.config.js para optimización automática.
  • Considera mover la librería multimedia a un bucket S3/Cloud Storage con plugin (Offload Media) para menos carga al WP.

4) SEO, metadatos y sitemap

  • En App Router, define generateMetadata o instala next-seo.
  • Genera /sitemap.xml y /robots.txt con next-sitemap.

5) Vista previa de borradores (Preview Mode)

  1. Crea una ruta API en Next.js (/api/preview) que valide un token y habilite el modo preview.
  2. En WordPress, configura la URL de vista previa para apuntar a esa ruta con el postId.

6) Revalidación por webhook

En /app/api/revalidate/route.ts:

import { NextRequest, NextResponse } from "next/server";

export async function POST(req: NextRequest) {
  const secret = req.nextUrl.searchParams.get("secret");
  if (secret !== process.env.REVALIDATE_SECRET) return NextResponse.json({ ok: false }, { status: 401 });

  const path = (await req.json()).path || "/";
  try {
    // @ts-ignore: disponible en runtime de Vercel
    await res.revalidate(path);
    return NextResponse.json({ revalidated: true, path });
  } catch (e) {
    return NextResponse.json({ revalidated: false, message: String(e) }, { status: 500 });
  }
}

Desde WordPress, envía el webhook al publicar y pasa la ruta afectada.

Consideraciones y buenas prácticas

  • Autenticación: para áreas privadas, usa JWT/OAuth y middleware de Next.
  • Cache: SWR/React Query en cliente y caché de fetch en servidor; evita sobrecargar al WP.
  • Accesibilidad y i18n con next-intl o next-i18next.
  • Monitorización: registra métricas Web Vitals y errores (Sentry/LogRocket).

Desventajas (lo que debes saber)

  • Mayor complejidad inicial que un tema clásico de WordPress.
  • Algunas funciones de plugins visuales no aplican directamente al frontend (requieren integración vía API).
  • Coste operativo: CMS + hosting del frontend + posibles servicios de medios/edge.

Checklist de migración

  • ✓ Inventario de contenido y URL actuales (para redirecciones 301).
  • ✓ API lista (WPGraphQL/REST) y esquema validado.
  • ✓ Next.js con SSG/ISR y rutas equivalentes.
  • ✓ SEO: metadatos, sitemap, robots.txt, canonicals y redirects.
  • ✓ Webhooks de revalidación y vista previa de borradores.
  • ✓ Pruebas de rendimiento, accesibilidad y core web vitals.

Conclusión

Migrar a Headless WordPress + Next.js ofrece un salto notable en rendimiento, seguridad y flexibilidad. Si tu proyecto necesita velocidad, SEO robusto y una UX moderna, el enfoque headless es una apuesta ganadora.

👉 ¿Quieres que planifiquemos y ejecutemos tu migración headless de principio a fin?
Contáctanos aquí.

¡Comunícate con nosotros!

Ads Blocker Image Powered by Code Help Pro

Bloqueador de anuncios detectado!!!

 Por favor, apóyanos desactivando este bloqueador de anuncios para seguir creando contenido que te gusta 🙏🏼

Powered By
100% Free SEO Tools - Tool Kits PRO