WP WordPress Intermédio

Headless Starter Kit: guia completo

Instalar, configurar e implantar o Headless Starter Kit: plugin WordPress e starter Next.js 15 chave na mão para passar o WooCommerce a headless.

Atualizado Versão do módulo 1.0.0

Este guia cobre a instalação, a configuração e a utilização completa do Headless Starter Kit, o plugin WordPress que transforma a sua loja WooCommerce em comércio headless, acompanhado de um starter Next.js 15 chave na mão.

A quem se destina este guia. Programador, agência ou comerciante técnico que quer passar um WooCommerce existente para headless sem reinventar a autenticação, o carrinho e o checkout. Tem de estar à vontade com a linha de comandos, o Node.js e alguma configuração de servidor se escolher o Hetzner.

Visão de conjunto

O Headless Starter Kit apresenta-se em dois entregáveis distribuídos na mesma compra:

  1. O plugin WordPress (ZIP a carregar em /wp-admin/plugins.php) que expõe do lado do backend: autenticação JWT, API de carrinho, ponte de checkout, endpoint de configuração público, webhooks ISR e CORS estrito.
  2. O starter Next.js 15 (ZIP descarregável a partir da administração do WordPress depois de o plugin estar ativo e configurado) que contém um projeto Next.js completo com páginas inicial, listagem, ficha de produto ISR, carrinho, checkout, início de sessão, registo e área de cliente, com as variáveis de ambiente já preenchidas com os seus URL e segredos.

A arquitetura é propositadamente simples: o seu WooCommerce continua a ser a fonte de verdade (produtos, encomendas, stocks, pagamentos) e o Next.js consome a API REST através de rotas proxy seguras. Sem duplicação de base de dados e sem replicação para gerir.

Requisitos

Do lado do WordPress

  • WordPress 6.4 ou superior
  • WooCommerce 8.0 ou superior (testado até à 9.5)
  • PHP 8.1 ou superior
  • Permalinks configurados em Nome do artigo (e não em Simples)
  • HTTPS ativo (indispensável para os cookies httpOnly e para a autenticação em produção)
  • Um par de chaves REST do WooCommerce em leitura e escrita (geradas em WooCommerce → Definições → Avançado → API REST)

Do lado do frontend Next.js

  • Node.js 20 ou superior (recomendado: gerir as versões com o nvm)
  • Alojamento compatível com Node: Vercel, VPS Hetzner, Netlify, Railway ou qualquer servidor capaz de executar Node 20+

Um alojamento partilhado clássico não serve para alojar o frontend Next.js, que exige um runtime Node persistente. O plugin WordPress, esse, funciona em qualquer alojamento WP.

Instalação do plugin WordPress

  1. No back-office do WordPress, vá a Plugins → Adicionar plugin → Carregar plugin.
  2. Selecione o ficheiro dfheadlessstarterkit.zip e clique em Instalar agora.
  3. Clique em Ativar plugin.
  4. Aparece um novo menu Headless Kit na barra lateral esquerda, com três separadores: Definições, Diagnósticos e Descarregar o starter.

Na ativação, o plugin gera automaticamente um segredo JWT e um token de revalidação aleatórios. Pode regerá-los a qualquer momento a partir das definições.

Configuração

Abra Headless Kit → Definições. Cada secção é independente e pode ser ajustada sem reiniciar seja o que for.

URL do frontend

Indique o URL público completo da sua aplicação Next.js, sem barra final. Exemplo:

https://loja.exemplo.pt

Este URL serve para três coisas: construir os webhooks ISR, alimentar a variável NEXT_PUBLIC_SITE_URL do starter entregue, e validar a origem CORS predefinida.

Segredo JWT e token de revalidação

São usados dois segredos:

  • Segredo JWT: assina os tokens de acesso e de refresh. No mínimo 32 carateres. Nunca o partilhe.
  • Token de revalidação: enviado no cabeçalho Authorization: Bearer … dos webhooks ISR. Tem de ser igual à variável REVALIDATE_TOKEN do lado do Next.js.

Um botão Regerar ao lado de cada campo produz um segredo aleatório criptograficamente sólido através do crypto.getRandomValues.

Depois de regerar o segredo JWT, todos os tokens de acesso e de refresh existentes ficam inválidos. Os utilizadores terão de iniciar sessão de novo. Avise-os ou faça-o fora das horas de maior tráfego.

Modo de carrinho: JWT ou servidor?

A escolha faz-se através de um botão de opção nas definições.

Modo JWT (predefinido, recomendado)

O carrinho completo é serializado num token assinado HS256 e devolvido através do cabeçalho X-DFHSK-Cart. Nenhum dado é guardado do lado do WordPress. Ideal para:

  • Implantações em Vercel edge, Cloudflare ou em várias instâncias
  • Lojas de tráfego elevado onde evitar a base de dados a cada chamada é um ganho claro
  • Configurações em que o WordPress é puramente API e não precisa de sessões

Modo servidor (WC_Session)

O carrinho vive na tabela nativa WC_Session do WooCommerce. A privilegiar se:

  • Usa extensões WooCommerce que fazem hook no carrinho (WooCommerce Subscriptions, Dynamic Pricing, plugins YITH, etc.)
  • Quer conservar a lógica de sessão nativa do WooCommerce (recuperação nativa de carrinhos abandonados, cross-sell no servidor, etc.)

Origens CORS

Uma lista de permissões estrita das origens autorizadas a chamar a API. Uma origem por linha, no formato completo https://…. Os wildcards de subdomínio são suportados:

https://loja.exemplo.pt
https://preview.exemplo.pt
https://*.previews.exemplo.pt
http://localhost:3000

Acrescente http://localhost:3000 durante o desenvolvimento e retire-o em produção.

Eventos ISR

Cinco caixas de seleção indicam que eventos do WordPress desencadeiam um webhook ISR para o Next.js:

  • Produtos: save_post_product, woocommerce_update_product
  • Categorias: criação, atualização e eliminação de termos da taxonomia product_cat
  • Encomendas: mudanças de estado (útil para atualizar a página da conta do cliente)
  • Páginas: save_post_page
  • Cupões: criação e atualização de códigos promocionais

Uma caixa de texto Caminhos a revalidar permite definir com precisão que caminhos do Next.js são revalidados em cada evento (por predefinição, o plugin deduz de forma inteligente os caminhos em causa).

Diagnósticos

Separador Headless Kit → Diagnósticos. São executadas onze verificações automáticas a cada apresentação da página:

  1. WooCommerce ativo: a classe WooCommerce está disponível
  2. Permalinks limpos: a estrutura não é Simples
  3. API REST acessível: o /wp-json/ responde com 200
  4. HTTPS ativo: o is_ssl() devolve true
  5. WPGraphQL detetado: apenas informativo, não bloqueante
  6. Segredo JWT definido: no mínimo 32 carateres
  7. URL do frontend configurado: não vazio e com formato de URL válido
  8. Origens CORS preenchidas: pelo menos uma origem
  9. Token de revalidação definido: no mínimo 24 carateres
  10. Chaves REST do WooCommerce: o plugin deteta um par consumer_key/consumer_secret ativo
  11. Modo de carrinho legível: o armazenamento escolhido funciona

Cada verificação aparece a verde (OK), laranja (aviso, não bloqueante) ou vermelho (bloqueante). Resolva tudo o que estiver a vermelho antes de passar a produção.

Descarregar e lançar o starter Next.js

Depois de preencher as definições e com os diagnósticos a verde, abra Headless Kit → Descarregar o starter. Clique no botão grande Descarregar o starter Next.js.

O ZIP entregue é um projeto Next.js 15 completo, gerado na hora com os seus URL e segredos já injetados. Os marcadores substituídos na geração:

  • {{SITE_URL}} → URL do seu WordPress
  • {{FRONTEND_URL}} → URL do front configurado
  • {{REVALIDATE_TOKEN}} → o seu token de revalidação
  • {{CURRENCY}} → moeda do WooCommerce
  • {{SITE_NAME}} → título do site
  • {{LOCALE}} → locale do WordPress (pt, fr, en, es, etc.)

O ficheiro .envtmpl passa a chamar-se .env.example na geração.

Variáveis de ambiente a completar manualmente

Alguns valores não podem ser obtidos automaticamente e têm de ser acrescentados ao ficheiro .env (a criar a partir do .env.example):

WOO_REST_CONSUMER_KEY=ck_xxxxxxxxxxxxxx
WOO_REST_CONSUMER_SECRET=cs_xxxxxxxxxxxxxx
SESSION_PASSWORD=a-sua-palavra-passe-de-32-carateres-no-minimo

Gere uma SESSION_PASSWORD sólida:

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

Desenvolvimento local

npm install
cp .env.example .env
# Edite o .env com os segredos em falta
npm run dev

O front fica acessível em http://localhost:3000. Acrescente este URL às origens CORS do lado do WordPress durante o desenvolvimento.

Implantação em Vercel

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

Configure depois todas as variáveis de ambiente no dashboard da Vercel (Project → Settings → Environment Variables). O ficheiro vercel.json entregue fixa a região em cdg1 (Paris) e desativa a cache nas rotas /api/*.

Implantação em Hetzner (ou em qualquer VPS Ubuntu/Debian)

# No servidor, como root ou com sudo
git clone o-seu-repo.git storefront && cd storefront
cp .env.example .env
nano .env                       # Preencha todas as variáveis
bash deploy/hetzner.sh

O script instala o Docker se for necessário, constrói a imagem, lança o contentor e expõe o serviço em 127.0.0.1:3000. Acrescente o Caddy ou o nginx como reverse-proxy para o TLS. Exemplo de Caddyfile mínimo:

loja.exemplo.pt {
  encode zstd gzip
  reverse_proxy 127.0.0.1:3000
}

Endpoints REST expostos

Todos os endpoints do plugin estão no namespace dfhsk/v1. URL completo: https://exemplo.pt/wp-json/dfhsk/v1/…

Autenticação

  • POST /auth/login: corpo { username, password } → devolve { token, refresh_token, user }
  • POST /auth/refresh: corpo { refresh_token } → devolve um novo token
  • GET /auth/me: cabeçalho Authorization: Bearer … → devolve o utilizador atual
  • POST /auth/register: corpo { email, password, first_name, last_name }
  • POST /auth/logout: invalida o refresh token

Carrinho

Todas as chamadas transmitem o token de carrinho através do cabeçalho X-DFHSK-Cart. O servidor devolve um novo token no mesmo cabeçalho em cada resposta.

  • GET /cart: snapshot completo (itens, totais, impostos, portes)
  • POST /cart/add: corpo { product_id, quantity, variation? }
  • POST /cart/update: corpo { key, quantity }
  • POST /cart/remove: corpo { key }
  • POST /cart/coupon: corpo { code }
  • DELETE /cart/coupon/{code}
  • POST /cart/shipping: corpo { country, postcode } → devolve as tarifas aplicáveis
  • POST /cart/clear

Checkout

  • POST /checkout/create-order: corpo { payment_method, billing, shipping? } → devolve { order_id, order_key, redirect }. O redirect é o URL para o gateway de pagamento (Stripe, PayPal, etc.).
  • GET /checkout/order/{id}: exige o cabeçalho Authorization: Bearer …

Configuração pública

  • GET /config: acessível sem autenticação. Devolve { currency, base_country, countries, payment_methods, tax_settings }. O starter Next.js usa este endpoint para preencher os formulários de checkout.

Webhooks ISR (do lado do Next.js)

O plugin envia pedidos POST para {FRONTEND_URL}/api/revalidate com o cabeçalho Authorization: Bearer {REVALIDATE_TOKEN}. O corpo é um JSON:

{
  "paths": ["/products/casaco-linho", "/products"],
  "tags": ["product:casaco-linho"],
  "reason": "wc_update_product"
}

A rota /api/revalidate entregue no starter valida o token e depois chama revalidatePath e revalidateTag para cada entrada.

Personalizar o starter

O código entregue está sob licença GPL v2: pode alterar, estender e redistribuir sem restrições. Os pontos de entrada habituais:

  • Paleta de cores: tailwind.config.ts, paleta brand (laranja por predefinição)
  • Componentes da loja: src/components/shop/ (Header, Footer, ProductCard, CartProvider)
  • Páginas públicas: src/app/(shop)/
  • Páginas da conta do cliente: src/app/(auth)/
  • Formato de preços e datas: src/lib/format.ts
  • Tipos TypeScript: src/types/woo.ts
  • Helper de chamada à API: src/lib/woo-rest.ts (funções wooRest e dfhskFetch)

Para acrescentar uma nova página que liste, por exemplo, os produtos de uma marca, duplique src/app/(shop)/products/page.tsx e adapte a query da REST do WooCommerce. A função wooRest<T>() trata automaticamente da autenticação Basic.

Resolução de problemas

Erro de CORS na consola do navegador

A origem do front não consta da lista de permissões. Acrescente-a em Definições → Origens CORS, uma por linha, sem barra final.

Webhooks ISR que respondem 401

O REVALIDATE_TOKEN do lado do Next.js não corresponde ao token configurado do lado do WordPress. Copie o valor exato das definições do WP para o .env do Next.js e volte a implantar.

O login devolve 403 apesar de as credenciais estarem corretas

Verifique que a conta de utilizador tem mesmo uma palavra-passe definida (e não apenas um início de sessão social), que o HTTPS está ativo em produção, e que o segredo JWT tem pelo menos 32 carateres. Consulte o separador Diagnósticos.

O carrinho esvazia-se entre duas páginas

No modo JWT, verifique que o starter lê e escreve mesmo o token no localStorage (chave dfhsk_cart_token). Abra o inspetor do navegador → separador Application → Local Storage.

Uma encomenda criada no WooCommerce não aparece do lado do Next.js

Verifique que o evento Encomendas está assinalado nos eventos ISR e que o webhook parte sem erro (ative o WP_DEBUG_LOG).

Ir mais longe

O starter é um ponto de partida, não um produto acabado. Consoante o seu projeto, considere acrescentar:

  • Um motor de pesquisa instantânea (Algolia, Meilisearch, Typesense) alimentado pelos mesmos webhooks ISR
  • Um CMS de conteúdo editorial do lado do WordPress com o plugin ACF ou equivalente, e uma página Next.js dedicada
  • Uma PWA com service worker para o modo offline (ver também o nosso módulo dfpwa)
  • Personalização por IA em tempo real (ver dfsmartcontent)

Para qualquer questão técnica, contacte o suporte DataFirefly com os seus registos e os resultados do separador Diagnósticos.

Esta página foi útil?

Ainda com dúvidas? Contacte o suporte