Sylius Shop API : integrer un frontend headless avec React ou Next.js
Le headless commerce separe le frontend du backend. Sylius devient un moteur API pur, et vous construisez l'interface avec la technologie de votre choix : React, Next.js, Vue, Nuxt, ou meme une app mobile. Voici comment structurer cette architecture.
Architecture cible
CDN (Vercel / Cloudflare)
|
Next.js Frontend
(SSR / ISR / CSR)
|
HTTPS + JWT
|
Sylius Backend
(API Platform)
|
PostgreSQL + Redis
Configuration CORS sur Sylius
Installez et configurez NelmioCorsBundle :
composer require nelmio/cors-bundle
# config/packages/nelmio_cors.yaml
nelmio_cors:
defaults:
origin_regex: true
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
allow_methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']
allow_headers: ['Content-Type', 'Authorization']
max_age: 3600
paths:
'^/api/':
allow_origin: ['https://www.votre-front.com']
Client API cote React
Creez un client API type :
// lib/sylius-client.ts
const API_URL = process.env.NEXT_PUBLIC_SYLIUS_API_URL;
class SyliusClient {
private token: string | null = null;
async authenticate(email: string, password: string) {
const res = await fetch(`${API_URL}/shop/authentication-token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
const data = await res.json();
this.token = data.token;
return data;
}
async get(endpoint: string) {
const headers: Record<string, string> = {
'Accept': 'application/ld+json',
};
if (this.token) headers['Authorization'] = `Bearer ${this.token}`;
const res = await fetch(`${API_URL}${endpoint}`, { headers });
if (!res.ok) throw new Error(`API error: ${res.status}`);
return res.json();
}
async getProducts(page = 1, perPage = 12) {
return this.get(`/shop/products?page=${page}&itemsPerPage=${perPage}`);
}
async getProduct(code: string) {
return this.get(`/shop/products/${code}`);
}
async getCart(token: string) {
return this.get(`/shop/orders/${token}`);
}
}
export const sylius = new SyliusClient();
Pages produits avec Next.js ISR
// app/products/[code]/page.tsx
import { sylius } from '@/lib/sylius-client';
export async function generateStaticParams() {
const products = await sylius.getProducts(1, 100);
return products['hydra:member'].map((p: any) => ({
code: p.code,
}));
}
export const revalidate = 3600; // Regenerer toutes les heures
export default async function ProductPage({
params
}: {
params: { code: string }
}) {
const product = await sylius.getProduct(params.code);
return (
<main className="max-w-6xl mx-auto px-4 py-8">
<h1 className="text-3xl font-bold">{product.name}</h1>
<p>{product.shortDescription}</p>
{/* Galerie, variantes, ajout panier... */}
</main>
);
}
Gestion du panier
Le panier Sylius est identifie par un token unique. Stockez-le dans un cookie ou localStorage :
// hooks/useCart.ts
import { useState, useEffect } from 'react';
import { sylius } from '@/lib/sylius-client';
export function useCart() {
const [cartToken, setCartToken] = useState<string | null>(null);
const [cart, setCart] = useState(null);
async function createCart() {
const res = await fetch(`${API_URL}/shop/orders`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ localeCode: 'fr_FR' }),
});
const data = await res.json();
setCartToken(data.tokenValue);
localStorage.setItem('cart_token', data.tokenValue);
return data;
}
async function addItem(variantCode: string, quantity: number) {
let token = cartToken;
if (!token) {
const newCart = await createCart();
token = newCart.tokenValue;
}
// POST item to cart...
}
return { cart, addItem, cartToken };
}
Quand choisir le headless
- Oui : trafic eleve (100K+ visites/mois), equipe front JS confirmee, multi-canal (web + app mobile), besoin de performances extremes
- Non : budget limite, equipe back-end uniquement, projet simple, time-to-market court
Le headless n'est pas une fin en soi. C'est un choix d'architecture qui se justifie par des besoins concrets. Pour la majorite des projets Sylius, le theming classique suffit.
Besoin d'accompagnement pour votre projet headless ? Parlons-en. Voir aussi notre article sur l'API Platform de Sylius.
