# Headless Starter Kit — Guía completa

> Guía completa de instalación, configuración y despliegue de Headless Starter Kit: el plugin WordPress que convierte tu tienda WooCommerce en comercio headless, con starter Next.js 15 llave en mano preconfigurado.

- Página: <https://www.datafirefly.com/es/documentation/headless-starter-kit/>
- Idioma: es
- Actualizado el: 2026-07-01
- Otros idiomas: [fr](https://www.datafirefly.com/documentation/headless-starter-kit/index.md), [en](https://www.datafirefly.com/en/documentation/headless-starter-kit/index.md), [de](https://www.datafirefly.com/de/documentation/headless-starter-kit/index.md), [it](https://www.datafirefly.com/it/documentation/headless-starter-kit/index.md), [pl](https://www.datafirefly.com/pl/documentation/headless-starter-kit/index.md), [nl](https://www.datafirefly.com/nl/documentation/headless-starter-kit/index.md), [pt](https://www.datafirefly.com/pt/documentation/headless-starter-kit/index.md)
- Índice: <https://www.datafirefly.com/es/documentation/llms.txt>

Esta guía cubre la instalación, configuración y uso completo de **Headless Starter Kit** — el plugin WordPress que convierte tu tienda WooCommerce en un comercio headless, acompañado de un starter Next.js 15 llave en mano.

**A quién se dirige esta guía.** Desarrolladores, agencias o comerciantes técnicos que quieren pasar un WooCommerce existente a headless sin reinventar autenticación, carrito y checkout. Debes sentirte cómodo con la línea de comandos, Node.js y algo de configuración de servidor si eliges Hetzner.

## Visión general

Headless Starter Kit se presenta como **dos entregables** en una sola compra:

1. **El plugin WordPress** (ZIP subido vía `/wp-admin/plugins.php`) que expone del lado backend: autenticación JWT, API de carrito, puente de checkout, endpoint de configuración público, webhooks ISR y CORS estricto.
2. **El starter Next.js 15** (ZIP descargable desde el admin WordPress una vez el plugin activado y configurado) que contiene un proyecto Next.js completo con páginas home, listado, ficha producto ISR, carrito, checkout, login, registro y área de cliente — variables de entorno ya pre-rellenadas con tus URLs y secretos.

La arquitectura es deliberadamente simple: tu WooCommerce sigue siendo la fuente de verdad (productos, pedidos, stock, pagos), y Next.js consume la API REST mediante rutas proxy seguras. Sin duplicación de base de datos, sin réplica que gestionar.

## Requisitos

### Lado WordPress

- WordPress **6.4 o superior**
- WooCommerce **8.0 o superior** (probado hasta 9.5)
- PHP **8.1 o superior**
- Enlaces permanentes configurados en _Nombre de la entrada_ (no en _Simple_)
- HTTPS activo (imprescindible para cookies httpOnly y autenticación en producción)
- Un par de claves WooCommerce REST con lectura-escritura (generadas en _WooCommerce → Ajustes → Avanzado → REST API_)

### Lado frontend Next.js

- Node.js **20 o superior** (recomendado: gestionar versiones con `nvm`)
- Alojamiento compatible con Node: Vercel, Hetzner VPS, Netlify, Railway o cualquier servidor capaz de ejecutar Node 20+

**El alojamiento compartido clásico (o2switch, OVH compartido, etc.) no es adecuado** para alojar el frontend Next.js, que requiere un runtime Node persistente. El plugin WordPress, en cambio, funciona en cualquier alojamiento compatible con WP.

## Instalación del plugin WordPress

1. Desde el back-office de WordPress, ve a _Plugins → Añadir nuevo → Subir plugin_.
2. Selecciona el archivo `dfheadlessstarterkit.zip`, luego haz clic en _Instalar ahora_.
3. Haz clic en _Activar plugin_.
4. Aparece un nuevo menú **Headless Kit** en la barra lateral izquierda, con tres pestañas: _Ajustes_, _Diagnósticos_, _Descargar starter_.

Al activar, el plugin genera automáticamente un secreto JWT y un token de revalidación aleatorios. Puedes regenerarlos en cualquier momento desde los ajustes.

## Configuración

Abre _Headless Kit → Ajustes_. Cada sección es independiente y puede modificarse sin reiniciar nada.

### URL del frontend

Introduce la URL pública completa de tu aplicación Next.js, sin barra final. Ejemplo:

```
https://shop.ejemplo.com
```

Esta URL sirve para tres cosas: construir los webhooks ISR, alimentar la variable `NEXT_PUBLIC_SITE_URL` del starter entregado, y validar el origen CORS por defecto.

### Secreto JWT y token de revalidación

Se utilizan dos secretos:

- **Secreto JWT** — firma los tokens de acceso y refresh. Al menos 32 caracteres. Nunca lo compartas.
- **Token de revalidación** — enviado en la cabecera `Authorization: Bearer …` de los webhooks ISR. Debe ser idéntico a la variable `REVALIDATE_TOKEN` del lado Next.js.

Un botón _Regenerar_ junto a cada campo produce un secreto aleatorio criptográficamente sólido vía `crypto.getRandomValues`.

**Tras regenerar el secreto JWT, todos los tokens de acceso y refresh existentes quedan inválidos.** Los usuarios tendrán que volver a iniciar sesión. Avísales o hazlo fuera de horas punta.

### Modo carrito: ¿JWT o servidor?

La elección se hace mediante un botón radio en los ajustes.

#### Modo JWT (por defecto, recomendado)

El carrito completo se serializa en un token firmado HS256 y se devuelve mediante la cabecera `X-DFHSK-Cart`. No se almacena ningún dato del lado WordPress. Ideal para:

- Despliegues en Vercel edge, Cloudflare, o multi-instancia
- Tiendas de alto tráfico donde evitar la base de datos en cada llamada es una ganancia neta
- Configuraciones donde WordPress es puramente API y no necesita sesiones

#### Modo servidor (WC_Session)

El carrito vive en la tabla WC_Session nativa de WooCommerce. Preferible si:

- Usas extensiones WooCommerce que se enganchan al carrito (WooCommerce Subscriptions, Dynamic Pricing, plugins YITH, etc.)
- Quieres conservar la lógica de sesión nativa de WooCommerce (recuperación nativa de carritos abandonados, cross-sell del lado servidor, etc.)

### Orígenes CORS

Una lista blanca estricta de orígenes autorizados a llamar la API. Un origen por línea, formato completo `https://…`. Se admiten comodines de subdominios:

```
https://shop.ejemplo.com
https://preview.ejemplo.com
https://*.previews.ejemplo.com
http://localhost:3000
```

Añade `http://localhost:3000` durante el desarrollo, luego quítalo en producción.

### Eventos ISR

Cinco casillas indican qué eventos de WordPress disparan un webhook ISR hacia Next.js:

- **Productos** — `save_post_product`, `woocommerce_update_product`
- **Categorías** — creación, actualización, eliminación de términos de la taxonomía `product_cat`
- **Pedidos** — cambios de estado (útil para refrescar la página de cuenta)
- **Páginas** — `save_post_page`
- **Cupones** — creación y actualización de códigos promocionales

Un textarea _Rutas a revalidar_ te permite definir con precisión qué rutas Next.js se revalidan para cada evento (por defecto, el plugin deduce inteligentemente las rutas afectadas).

## Diagnósticos

_Headless Kit → Diagnósticos_. Once controles automáticos se ejecutan cada vez que se muestra la página:

1. **WooCommerce activo** — la clase `WooCommerce` está disponible
2. **Enlaces permanentes correctos** — la estructura no es _Simple_
3. **REST API accesible** — `/wp-json/` responde 200
4. **HTTPS activo** — `is_ssl()` devuelve true
5. **WPGraphQL detectado** — solo informativo, no bloqueante
6. **Secreto JWT definido** — al menos 32 caracteres
7. **URL del frontend configurada** — no vacía y formato URL válido
8. **Orígenes CORS definidos** — al menos un origen
9. **Token de revalidación definido** — al menos 24 caracteres
10. **Claves WooCommerce REST** — el plugin detecta un par consumer_key/consumer_secret activo
11. **Modo carrito legible** — el almacenamiento elegido funciona

Cada control muestra verde (OK), naranja (advertencia, no bloqueante) o rojo (bloqueante). Resuelve todo lo rojo antes de pasar a producción.

## Descargar y lanzar el starter Next.js

Una vez rellenados los ajustes y los diagnósticos en verde, abre _Headless Kit → Descargar starter_. Haz clic en el botón grande _Descargar starter Next.js_.

El ZIP entregado es un proyecto Next.js 15 completo, generado sobre la marcha con tus URLs y secretos ya inyectados. Placeholders reemplazados en la generación:

- `{{SITE_URL}}` → URL de tu WordPress
- `{{FRONTEND_URL}}` → URL del front configurada
- `{{REVALIDATE_TOKEN}}` → tu token de revalidación
- `{{CURRENCY}}` → moneda WooCommerce
- `{{SITE_NAME}}` → título del sitio
- `{{LOCALE}}` → locale WordPress (es, fr, en, etc.)

El archivo `.envtmpl` se renombra a `.env.example` en la generación.

### Variables de entorno a completar manualmente

Algunos valores no pueden recuperarse automáticamente — debes añadirlos al archivo `.env` (creado desde `.env.example`):

```
WOO_REST_CONSUMER_KEY=ck_xxxxxxxxxxxxxx
WOO_REST_CONSUMER_SECRET=cs_xxxxxxxxxxxxxx
SESSION_PASSWORD=tu-contrasena-de-32-caracteres-minimo
```

Genera un `SESSION_PASSWORD` sólido:

```
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
```

### Desarrollo local

```
npm install
cp .env.example .env
# Edita .env con tus secretos que faltan
npm run dev
```

El front está disponible en `http://localhost:3000`. Añade esta URL a los orígenes CORS del lado WordPress durante el desarrollo.

### Despliegue en Vercel

```
npx vercel link
npx vercel env pull .env.production
npx vercel deploy --prod
```

Después configura todas las variables de entorno en el dashboard de Vercel (_Project → Settings → Environment Variables_). El archivo `vercel.json` entregado fija la región en `cdg1` (París) y desactiva la caché en las rutas `/api/*`.

### Despliegue en Hetzner (o cualquier VPS Ubuntu/Debian)

```
# En el servidor, como root o con sudo
git clone tu-repo.git storefront && cd storefront
cp .env.example .env
nano .env                       # Rellena todas las variables
bash deploy/hetzner.sh
```

El script instala Docker si es necesario, construye la imagen, lanza el contenedor y expone el servicio en `127.0.0.1:3000`. Añade Caddy o nginx como reverse-proxy para el TLS. Ejemplo de Caddyfile mínimo:

```
shop.ejemplo.com {
  encode zstd gzip
  reverse_proxy 127.0.0.1:3000
}
```

## Endpoints REST expuestos

Todos los endpoints del plugin viven bajo el namespace `dfhsk/v1`. URL completa: `https://ejemplo.com/wp-json/dfhsk/v1/…`

### Autenticación

- `POST /auth/login` — body: `{ username, password }` → devuelve `{ token, refresh_token, user }`
- `POST /auth/refresh` — body: `{ refresh_token }` → devuelve un nuevo `token`
- `GET /auth/me` — cabecera: `Authorization: Bearer …` → devuelve el usuario actual
- `POST /auth/register` — body: `{ email, password, first_name, last_name }`
- `POST /auth/logout` — invalida el refresh token

### Carrito

Cada llamada transmite el token de carrito mediante la cabecera `X-DFHSK-Cart`. El servidor devuelve un nuevo token en la misma cabecera en cada respuesta.

- `GET /cart` — snapshot completo (items, totales, impuestos, envío)
- `POST /cart/add` — body: `{ product_id, quantity, variation? }`
- `POST /cart/update` — body: `{ key, quantity }`
- `POST /cart/remove` — body: `{ key }`
- `POST /cart/coupon` — body: `{ code }`
- `DELETE /cart/coupon/{code}`
- `POST /cart/shipping` — body: `{ country, postcode }` → devuelve las tarifas aplicables
- `POST /cart/clear`

### Checkout

- `POST /checkout/create-order` — body: `{ payment_method, billing, shipping? }` → devuelve `{ order_id, order_key, redirect }`. El `redirect` es la URL a la pasarela de pago (Stripe, PayPal, etc.).
- `GET /checkout/order/{id}` — cabecera `Authorization: Bearer …` requerida

### Configuración pública

- `GET /config` — accesible sin autenticación. Devuelve `{ currency, base_country, countries, payment_methods, tax_settings }`. El starter Next.js utiliza este endpoint para hidratar los formularios de checkout.

### Webhooks ISR (lado Next.js)

El plugin envía peticiones `POST` a `{FRONTEND_URL}/api/revalidate` con la cabecera `Authorization: Bearer {REVALIDATE_TOKEN}`. El cuerpo es JSON:

```
{
  "paths": ["/products/chaqueta-lino", "/products"],
  "tags": ["product:chaqueta-lino"],
  "reason": "wc_update_product"
}
```

La ruta `/api/revalidate` entregada en el starter valida el token y luego llama a `revalidatePath` y `revalidateTag` para cada entrada.

## Personalizar el starter

El código entregado está bajo licencia GPL v2 — puedes modificar, extender, redistribuir sin restricciones. Puntos de entrada habituales:

- **Paleta de colores**: `tailwind.config.ts`, paleta `brand` (naranja por defecto)
- **Componentes tienda**: `src/components/shop/` (Header, Footer, ProductCard, CartProvider)
- **Páginas públicas**: `src/app/(shop)/`
- **Páginas de cuenta**: `src/app/(auth)/`
- **Formato de precios y fechas**: `src/lib/format.ts`
- **Tipos TypeScript**: `src/types/woo.ts`
- **Helper de llamadas API**: `src/lib/woo-rest.ts` (funciones `wooRest` y `dfhskFetch`)

Para añadir una nueva página que liste por ejemplo los productos de una marca, duplica `src/app/(shop)/products/page.tsx` y adapta la consulta WooCommerce REST. La función `wooRest()` gestiona la autenticación Basic automáticamente.

## Resolución de problemas

### Error CORS en la consola del navegador

El origen del front no está en la lista blanca. Añádelo en _Ajustes → Orígenes CORS_, uno por línea, sin barra final.

### Los webhooks ISR responden 401

El `REVALIDATE_TOKEN` del lado Next.js no coincide con el token configurado del lado WordPress. Copia el valor exacto de los ajustes WP en el `.env` de Next.js, luego redespliega.

### Login devuelve 403 pese a credenciales correctas

Verifica que la cuenta de usuario tiene una contraseña definida (no solo login social), que HTTPS está activo en producción, y que el secreto JWT tiene al menos 32 caracteres. Consulta la pestaña Diagnósticos.

### El carrito se vacía entre dos páginas

En modo JWT, verifica que el starter lee y escribe correctamente el token en `localStorage` (clave `dfhsk_cart_token`). Abre el inspector del navegador → pestaña _Application → Local Storage_.

### Un pedido creado en WooCommerce no aparece en Next.js

Verifica que el evento _Pedidos_ está marcado en los eventos ISR y que el webhook se envía sin error (activa `WP_DEBUG_LOG`).

## Ir más lejos

El starter es un punto de partida, no un producto terminado. Según tu proyecto, considera añadir:

- Un motor de búsqueda instantáneo (Algolia, Meilisearch, Typesense) alimentado por los mismos webhooks ISR
- Un CMS de contenido editorial del lado WordPress con el plugin ACF o similar, y una página Next.js dedicada
- Una PWA con service worker para el modo sin conexión (ver también nuestro módulo _dfpwa_)
- Personalización IA en tiempo real (ver _dfsmartcontent_)

Para cualquier duda técnica, contacta con el soporte de DataFirefly con tus logs y los resultados de la pestaña Diagnósticos.
