Headless Starter Kit — Guide complet
Installer, configurer et déployer Headless Starter Kit : plugin WordPress + starter Next.js 15 clé en main pour passer WooCommerce en headless.
Ce guide couvre l’installation, la configuration et l’utilisation complète de Headless Starter Kit — plugin WordPress qui transforme votre boutique WooCommerce en commerce headless, accompagné d’un starter Next.js 15 clé en main.
À qui s’adresse ce guide. Développeur, agence ou marchand technique qui veut passer un WooCommerce existant en headless sans réinventer authentification, panier et checkout. Vous devez être à l’aise avec la ligne de commande, Node.js et un peu de configuration serveur si vous choisissez Hetzner.
Vue d’ensemble
Headless Starter Kit se présente en deux livrables distribués dans le même achat :
- Le plugin WordPress (ZIP à uploader dans
/wp-admin/plugins.php) qui expose côté backend : authentification JWT, API panier, pont de checkout, endpoint de configuration public, webhooks ISR et CORS strict. - Le starter Next.js 15 (ZIP téléchargeable depuis l’admin WordPress une fois le plugin activé et configuré) qui contient un projet Next.js complet avec pages home, listing, fiche produit ISR, panier, checkout, login, register et espace client — variables d’environnement déjà pré-remplies avec vos URLs et secrets.
L’architecture est volontairement simple : votre WooCommerce reste la source de vérité (produits, commandes, stocks, paiements), et Next.js consomme l’API REST via des routes proxy sécurisées. Aucune duplication de base de données, aucune réplication à gérer.
Prérequis
Côté WordPress
- WordPress 6.4 ou supérieur
- WooCommerce 8.0 ou supérieur (testé jusqu’à 9.5)
- PHP 8.1 ou supérieur
- Permaliens configurés en Nom de l’article (pas en Simple)
- HTTPS actif (indispensable pour les cookies httpOnly et l’authentification en production)
- Une paire de clés WooCommerce REST en lecture-écriture (générées dans WooCommerce → Réglages → Avancé → API REST)
Côté frontend Next.js
- Node.js 20 ou supérieur (recommandé : gérer les versions avec
nvm) - Hébergement compatible Node : Vercel, Hetzner VPS, Netlify, Railway ou tout serveur pouvant exécuter Node 20+
Hébergement mutualisé classique (o2switch, OVH mutualisé, etc.) n’est pas adapté pour héberger le frontend Next.js, qui requiert un runtime Node persistant. Le plugin WordPress, lui, fonctionne sur tout hébergement WP.
Installation du plugin WordPress
- Depuis le back-office WordPress, allez dans Extensions → Ajouter une extension → Téléverser une extension.
- Sélectionnez le fichier
dfheadlessstarterkit.zip, puis cliquez sur Installer maintenant. - Cliquez sur Activer l’extension.
- Un nouveau menu Headless Kit apparaît dans la barre latérale gauche, avec trois onglets : Réglages, Diagnostics, Télécharger le starter.
À l’activation, le plugin génère automatiquement un secret JWT et un jeton de revalidation aléatoires. Vous pouvez les régénérer à tout moment depuis les réglages.
Configuration
Ouvrez Headless Kit → Réglages. Chaque section est indépendante et peut être ajustée sans redémarrer quoi que ce soit.
URL du frontend
Renseignez l’URL publique complète de votre application Next.js, sans slash final. Exemple :
https://shop.exemple.fr
Cette URL sert à trois choses : construire les webhooks ISR, alimenter la variable NEXT_PUBLIC_SITE_URL du starter livré, et valider l’origine CORS par défaut.
Secret JWT et jeton de revalidation
Deux secrets sont utilisés :
- Secret JWT — signe les tokens d’accès et de refresh. Au moins 32 caractères. Ne le partagez jamais.
- Jeton de revalidation — envoyé dans le header
Authorization: Bearer …des webhooks ISR. Doit être identique à la variableREVALIDATE_TOKENcôté Next.js.
Un bouton Régénérer à côté de chaque champ produit un secret aléatoire cryptographiquement solide via crypto.getRandomValues.
Après régénération du secret JWT, tous les tokens d’accès et de refresh existants deviennent invalides. Les utilisateurs devront se reconnecter. Prévenez-les ou faites-le en dehors des heures de trafic.
Mode panier : JWT ou serveur ?
Le choix se fait via un bouton radio dans les réglages.
Mode JWT (par défaut, recommandé)
Le panier complet est sérialisé dans un token signé HS256 et renvoyé via le header X-DFHSK-Cart. Aucune donnée n’est stockée côté WordPress. Idéal pour :
- Déploiements sur Vercel edge, Cloudflare, ou multi-instances
- Boutiques à fort trafic où éviter la base de données à chaque appel est un gain net
- Setups où le WordPress est purement API et n’a pas besoin de sessions
Mode serveur (WC_Session)
Le panier vit dans la table native WC_Session de WooCommerce. À privilégier si :
- Vous utilisez des extensions WooCommerce qui hookent sur le panier (WooCommerce Subscriptions, Dynamic Pricing, YITH plugins, etc.)
- Vous voulez conserver la logique de session native de WooCommerce (relances de paniers abandonnés natifs, cross-sell côté serveur, etc.)
Origines CORS
Une liste blanche stricte d’origines autorisées à appeler l’API. Une origine par ligne, format complet https://…. Les wildcards de sous-domaines sont supportés :
https://shop.exemple.fr
https://preview.exemple.fr
https://*.previews.exemple.fr
http://localhost:3000
Ajoutez http://localhost:3000 pendant le développement, puis retirez-le en production.
Événements ISR
Cinq cases à cocher indiquent quels événements WordPress déclenchent un webhook ISR vers Next.js :
- Produits —
save_post_product,woocommerce_update_product - Catégories — création, mise à jour, suppression de termes de la taxonomie
product_cat - Commandes — changements de statut (utile pour rafraîchir la page compte client)
- Pages —
save_post_page - Coupons — création et mise à jour de codes promo
Un textarea Chemins à revalider vous permet de définir précisément quels chemins Next.js sont revalidés pour chaque événement (par défaut, le plugin déduit intelligemment les chemins concernés).
Diagnostics
Onglet Headless Kit → Diagnostics. Onze contrôles automatiques sont exécutés à chaque affichage de la page :
- WooCommerce actif — la classe
WooCommerceest disponible - Permaliens propres — la structure n’est pas Simple
- REST API joignable —
/wp-json/répond en 200 - HTTPS actif —
is_ssl()renvoie true - WPGraphQL détecté — information seulement, non bloquant
- Secret JWT défini — au moins 32 caractères
- URL du frontend configurée — non vide et format URL valide
- Origines CORS renseignées — au moins une origine
- Jeton de revalidation défini — au moins 24 caractères
- Clés WooCommerce REST — le plugin détecte une paire consumer_key/consumer_secret active
- Mode panier lisible — le stockage choisi fonctionne
Chaque contrôle affiche vert (OK), orange (avertissement, non bloquant) ou rouge (bloquant). Résolvez tout ce qui est rouge avant de mettre en production.
Télécharger et lancer le starter Next.js
Une fois les réglages remplis et les diagnostics au vert, ouvrez Headless Kit → Télécharger le starter. Cliquez sur le gros bouton Télécharger le starter Next.js.
Le ZIP livré est un projet Next.js 15 complet, généré à la volée avec vos URLs et secrets déjà injectés. Les placeholders remplacés à la génération :
{{SITE_URL}}→ URL de votre WordPress{{FRONTEND_URL}}→ URL du front configurée{{REVALIDATE_TOKEN}}→ votre jeton de revalidation{{CURRENCY}}→ devise WooCommerce{{SITE_NAME}}→ titre du site{{LOCALE}}→ locale WordPress (fr, en, es, etc.)
Le fichier .envtmpl est renommé en .env.example à la génération.
Variables d’environnement à compléter manuellement
Certaines valeurs ne peuvent pas être récupérées automatiquement — vous devez les ajouter au fichier .env (à créer depuis .env.example) :
WOO_REST_CONSUMER_KEY=ck_xxxxxxxxxxxxxx
WOO_REST_CONSUMER_SECRET=cs_xxxxxxxxxxxxxx
SESSION_PASSWORD=votre-mot-de-passe-32-caracteres-minimum
Générez un SESSION_PASSWORD solide :
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Développement local
npm install
cp .env.example .env
# Éditez .env avec vos secrets manquants
npm run dev
Le front est accessible sur http://localhost:3000. Ajoutez cette URL dans les origines CORS côté WordPress pendant le développement.
Déploiement sur Vercel
npx vercel link
npx vercel env pull .env.production
npx vercel deploy --prod
Configurez ensuite toutes les variables d’environnement dans le dashboard Vercel (Project → Settings → Environment Variables). Le fichier vercel.json livré fixe la région sur cdg1 (Paris) et désactive le cache sur les routes /api/*.
Déploiement sur Hetzner (ou tout VPS Ubuntu/Debian)
# Sur le serveur, en tant que root ou avec sudo
git clone votre-repo.git storefront && cd storefront
cp .env.example .env
nano .env # Renseignez toutes les variables
bash deploy/hetzner.sh
Le script installe Docker si nécessaire, construit l’image, lance le conteneur et expose le service sur 127.0.0.1:3000. Ajoutez Caddy ou nginx en reverse-proxy pour le TLS. Exemple de Caddyfile minimal :
shop.exemple.fr {
encode zstd gzip
reverse_proxy 127.0.0.1:3000
}
Endpoints REST exposés
Tous les endpoints du plugin sont sous le namespace dfhsk/v1. URL complète : https://exemple.fr/wp-json/dfhsk/v1/…
Authentification
POST /auth/login— body :{ username, password }→ renvoie{ token, refresh_token, user }POST /auth/refresh— body :{ refresh_token }→ renvoie un nouveautokenGET /auth/me— header :Authorization: Bearer …→ renvoie l’utilisateur courantPOST /auth/register— body :{ email, password, first_name, last_name }POST /auth/logout— invalide le refresh token
Panier
Tous les appels transmettent le token de panier via le header X-DFHSK-Cart. Le serveur renvoie un nouveau token dans le même header à chaque réponse.
GET /cart— snapshot complet (items, totaux, taxes, frais de port)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 }→ renvoie les tarifs applicablesPOST /cart/clear
Checkout
POST /checkout/create-order— body :{ payment_method, billing, shipping? }→ renvoie{ order_id, order_key, redirect }. Leredirectest l’URL vers la passerelle de paiement (Stripe, PayPal, etc.).GET /checkout/order/{id}— headerAuthorization: Bearer …requis
Configuration publique
GET /config— accessible sans authentification. Renvoie{ currency, base_country, countries, payment_methods, tax_settings }. Le starter Next.js utilise cet endpoint pour hydrater les formulaires de checkout.
Webhooks ISR (côté Next.js)
Le plugin envoie des POST vers {FRONTEND_URL}/api/revalidate avec le header Authorization: Bearer {REVALIDATE_TOKEN}. Le corps est un JSON :
{
"paths": ["/products/veste-lin", "/products"],
"tags": ["product:veste-lin"],
"reason": "wc_update_product"
}
La route /api/revalidate livrée dans le starter valide le token puis appelle revalidatePath et revalidateTag pour chaque entrée.
Personnaliser le starter
Le code livré est sous licence GPL v2 — vous pouvez modifier, étendre, redistribuer sans restriction. Les points d’entrée usuels :
- Palette de couleurs :
tailwind.config.ts, palettebrand(orange par défaut) - Composants boutique :
src/components/shop/(Header, Footer, ProductCard, CartProvider) - Pages publiques :
src/app/(shop)/ - Pages compte client :
src/app/(auth)/ - Format prix et dates :
src/lib/format.ts - Types TypeScript :
src/types/woo.ts - Helper d’appel API :
src/lib/woo-rest.ts(fonctionswooRestetdfhskFetch)
Pour ajouter une nouvelle page qui liste par exemple les produits d’une marque, dupliquez src/app/(shop)/products/page.tsx et adaptez la query WooCommerce REST. La fonction wooRest<T>() gère l’authentification Basic automatiquement.
Résolution de problèmes
Erreur CORS dans la console navigateur
L’origine du front n’est pas dans la liste blanche. Ajoutez-la dans Réglages → Origines CORS, une par ligne, sans slash final.
Webhooks ISR qui répondent 401
Le REVALIDATE_TOKEN côté Next.js ne correspond pas au jeton configuré côté WordPress. Copiez-collez la valeur exacte des réglages WP dans le .env Next.js, puis redéployez.
Login retourne 403 malgré des identifiants corrects
Vérifiez que le compte utilisateur a bien un mot de passe défini (pas un login social uniquement), que HTTPS est actif en production, et que le secret JWT fait au moins 32 caractères. Consultez l’onglet Diagnostics.
Le panier se vide entre deux pages
En mode JWT, vérifiez que le starter lit et écrit bien le token dans localStorage (clé dfhsk_cart_token). Ouvrez l’inspecteur navigateur → onglet Application → Local Storage.
Une commande créée dans WooCommerce n’apparaît pas côté Next.js
Vérifiez que l’événement Commandes est bien coché dans les événements ISR et que le webhook part sans erreur (activez WP_DEBUG_LOG).
Aller plus loin
Le starter est un point de départ, pas un produit fini. Selon votre projet, envisagez d’ajouter :
- Un moteur de recherche instantané (Algolia, Meilisearch, Typesense) alimenté par les mêmes webhooks ISR
- Un CMS de contenu éditorial côté WordPress avec le plugin ACF ou similaire, et une page Next.js dédiée
- Une PWA avec service worker pour le mode hors-ligne (voir aussi notre module dfpwa)
- De la personnalisation IA temps-réel (voir dfsmartcontent)
Pour toute question technique, contactez le support DataFirefly avec vos logs et les résultats de l’onglet Diagnostics.