Introduction
Emerald Grit est une plateforme e-commerce headless complète,
spécialement conçue pour la mode écoresponsable. Elle combine
les meilleures technologies modernes avec une approche centrée
sur la durabilité et la transparence.
Pourquoi Emerald Grit ?
- Architecture Headless : Flexibilité totale et performances optimales
- Éco-responsabilité : Transparence sur l'impact environnemental
- Multilingue : Support de 6 langues dès le départ
- Moderne : Stack technologique à jour (Medusa v2, Nuxt.js, Next.js)
- Complet : Frontend, backend et back-office intégrés
Installation
Prérequis
- Node.js v22 ou supérieur
- PostgreSQL 14+ avec SSL support
- npm ou yarn
- Git
- Medusa v2 backend (sur port 9000)
Installation du Frontend Client (Nuxt.js)
# Naviguer vers le dossier frontend-client
cd frontend-client
# Installer les dépendances
npm install
# Démarrer le serveur de développement
npm run dev
# Le serveur démarre sur http://localhost:3001
Installation du Frontend Admin (Next.js 15.3.1)
# Naviguer vers le dossier frontend-admin
cd frontend-admin
# Installer les dépendances
npm install
# Configurer les variables d'environnement
# Créer un fichier .env.local avec :
NEXT_PUBLIC_MEDUSA_URL=http://localhost:9000
DATABASE_URL=postgresql://user:password@localhost:5432/emerald-grit
# Démarrer le serveur de développement
npm run dev
# Le serveur démarre sur http://localhost:3002
Configuration de la Base de Données PostgreSQL
# Se connecter à PostgreSQL
psql -U postgres
# Créer la base de données
CREATE DATABASE emerald-grit;
# Exécuter les scripts de création de tables
# Les tables sont créées automatiquement via les API routes
# ou manuellement via les scripts SQL dans server/db/
Configuration
Variables d'environnement Frontend Client
Configuration complète pour le frontend Nuxt.js :
Fichier .env (Frontend Client)
# URL de l'application
NUXT_PUBLIC_APP_URL=http://localhost:3001
# URL du backend Medusa
http://localhost:9000/app
NUXT_PUBLIC_MEDUSA_BACKEND_URL=http://localhost:9000
MEDUSA_URL=http://localhost:9000
# Base de données PostgreSQL (contenu éditorial, blog, durabilité)
DATABASE_URL=postgresql://user:password@localhost:5432/emerald-grit
# Configuration serveur
NODE_ENV=production
HOST=0.0.0.0
PORT=3001
Variables d'environnement Frontend Admin
Fichier .env.local (Frontend Admin)
# URL du backend Medusa
NEXT_PUBLIC_MEDUSA_URL=http://localhost:9000
# Base de données PostgreSQL
DATABASE_URL=postgresql://user:password@localhost:5432/emerald-grit
# Configuration Next.js
NODE_ENV=production
Configuration i18n (Multilingue)
Le frontend-client supporte 6 langues configurées dans nuxt.config.ts :
- FR (Français) - Langue par défaut
- EN (English)
- ES (Español)
- DE (Deutsch)
- IT (Italiano)
- ZH (中文)
Les fichiers de traduction sont dans i18n/locales/ avec langDir: 'locales'.
Architecture
Emerald Grit suit une architecture headless moderne avec séparation claire
des responsabilités entre les différents composants.
Frontend Client (Nuxt.js)
Port 3001 - Interface utilisateur
SSR, SSG, i18n, Tailwind CSS v4
→
Frontend Admin (Next.js 15.3.1)
Port 3002 - Back-office
App Router, Server Components, @medusajs/js-sdk
→
Medusa v2 Backend
Port 9000 - CMS Transactionnel
Modules Commerce, API REST/GraphQL
→
PostgreSQL
Base de données
Contenu éditorial, blog, durabilité
Architecture des Données Produit
Les données produit sont réparties entre 3 sources :
- Medusa CMS - Données transactionnelles (prix, stock, variants, commandes)
- product_additional_data (PostgreSQL) - Données éco-score globales (non multilingues)
- product_extended_content (PostgreSQL) - Contenu éditorial multilingue
Structure product_additional_data
CREATE TABLE product_additional_data (
id SERIAL PRIMARY KEY,
product_id VARCHAR(255) NOT NULL UNIQUE,
eco_rating NUMERIC, -- Note éco (0-5)
sustainability_score INTEGER, -- Score durabilité (0-100)
materials JSONB, -- [{name, percentage, eco_friendly}]
carbon_footprint NUMERIC, -- Empreinte carbone
sustainability_options JSONB, -- {certifications: [...]}
brand_id VARCHAR(255),
created_at TIMESTAMP,
updated_at TIMESTAMP
);
Structure product_extended_content
CREATE TABLE product_extended_content (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
sustainability_story TEXT,
care_instructions TEXT,
material_details TEXT,
production_process TEXT,
eco_certifications TEXT,
carbon_footprint VARCHAR(100),
origin_country VARCHAR(100),
production_location VARCHAR(100),
editor_id VARCHAR(255),
created_at TIMESTAMP,
updated_at TIMESTAMP
);
CREATE TABLE product_content_link (
id SERIAL PRIMARY KEY,
product_id VARCHAR(255),
extended_content_id INTEGER,
language_code VARCHAR(5), -- fr, en, es, de, it, zh
UNIQUE(product_id, language_code)
);
Gestion des Produits
Les produits sont gérés via Medusa v2 pour les données transactionnelles
et PostgreSQL pour le contenu éditorial enrichi et les données de durabilité.
Flux de Données
- Medusa v2 : Données de base (titre, prix, images, variants, stock, catégories)
- product_additional_data : Éco-scores, matériaux, certifications (globales, non multilingues)
- product_extended_content : Contenu éditorial traduit (une entrée par langue)
API Endpoints Frontend-Client
GET
/api/products/[handle]
Récupérer un produit par son handle avec toutes les données
GET
/api/products/additional-data
Récupérer les données éco-score pour plusieurs produits
GET
/api/products/multilingual-data
Récupérer le contenu éditorial multilingue
GET
/api/products/filter
Filtrer les produits avec critères avancés
GET
/api/products-with-sustainability
Récupérer les produits avec données de durabilité
API Endpoints Frontend-Admin
GET
/api/medusa/products
Liste des produits via @medusajs/js-sdk
GET
/api/medusa/products/[id]
Détails d'un produit
POST
/api/medusa/products
Créer un nouveau produit
PUT
/api/medusa/products/[id]
Mettre à jour un produit
DELETE
/api/medusa/products/[id]
Supprimer un produit
GET
/api/product-additional-data/[productId]
Récupérer les données éco-score
POST
/api/product-additional-data/[productId]
Sauvegarder les données éco-score
GET
/api/editorial-content/product/[productId]/[language]
Récupérer le contenu éditorial pour une langue
POST
/api/editorial-content/product/[productId]/[language]
Sauvegarder le contenu éditorial pour une langue
Fonctionnalités Éco-responsables
Emerald Grit intègre un système complet de durabilité avec des métriques
détaillées stockées dans PostgreSQL.
Éco-Rating (0-5)
Note éco-responsable sur 5 étoiles stockée dans product_additional_data.eco_rating :
- 5 étoiles : Excellent (matériaux 100% recyclés/biologiques, certifications complètes)
- 4 étoiles : Très bon (majoritairement éco-responsable)
- 3 étoiles : Bon (partiellement éco-responsable)
- 2 étoiles : Moyen (quelques aspects éco-responsables)
- 1 étoile : Faible (minimalement éco-responsable)
- 0 étoile : Non évalué
Score de Durabilité (0-100)
Score détaillé stocké dans product_additional_data.sustainability_score :
- 80-100 : Excellent impact environnemental
- 60-79 : Très bon impact
- 40-59 : Impact moyen
- 20-39 : Impact faible
- 0-19 : Impact très faible
Matériaux avec Pourcentages
Structure JSONB dans product_additional_data.materials :
[
{
"name": "Cotton",
"percentage": 57,
"eco_friendly": true
},
{
"name": "Polyester Recycled",
"percentage": 7,
"eco_friendly": true
}
]
Certifications
Certifications stockées dans product_additional_data.sustainability_options :
- GOTS (Global Organic Textile Standard)
- OEKO-TEX (Standard 100)
- Fair Trade (Commerce équitable)
- Certifications personnalisées
API Endpoints Durabilité
GET
/api/sustainability/metrics
Récupérer les métriques de durabilité
GET
/api/sustainability/options
Récupérer les options de durabilité disponibles
GET
/api/sustainability/[productId]
Récupérer les données de durabilité d'un produit (Admin)
API Reference
Emerald Grit expose plusieurs types d'APIs : Medusa v2 (Store API & Admin API),
APIs personnalisées frontend-client et frontend-admin.
Medusa v2 Store API
API publique pour le frontend-client via @nuxtjs/medusa :
GET
/store/products
Liste des produits avec filtres et pagination
GET
/store/products/:id
Détails d'un produit
GET
/store/product-categories
Liste des catégories produits
POST
/store/carts
Créer un panier
POST
/store/carts/:id/line-items
Ajouter un article au panier
POST
/store/carts/:id/payment-sessions
Créer une session de paiement
APIs Frontend-Client (Nuxt Server API)
Endpoints personnalisés dans server/api/ :
Catégories
GET
/api/categories
Toutes les catégories avec cache (2 min)
GET
/api/categories/top-level
Catégories de niveau 1 uniquement
GET
/api/categories/children
Catégories enfants d'une catégorie parent
GET
/api/categories/by-handle/:handle
Catégorie par handle
GET
/api/categories/by-id/:id
Catégorie par ID
POST
/api/categories/clear-cache
Vider le cache des catégories
Blog
GET
/api/blog
Liste des articles (paramètres: language, limit, category, featured)
GET
/api/blog/[slug]
Détails d'un article par slug
GET
/api/blog/featured
Articles mis en avant
GET
/api/blog/search
Recherche d'articles
GET
/api/blog/related
Articles similaires
Checkout & Commandes
POST
/api/checkout/stripe-session
Créer une session Stripe Checkout
POST
/api/checkout/process-payment
Traiter un paiement
POST
/api/checkout/verify
Vérifier un paiement
POST
/api/orders/complete-order
Finaliser une commande
APIs Frontend-Admin (Next.js API Routes)
Endpoints d'administration dans app/api/ :
Produits Medusa
GET
/api/medusa/products
Liste produits (filtres: limit, offset, q, status)
GET
/api/medusa/products/[id]
Détails produit
POST
/api/medusa/products
Créer un produit
PUT
/api/medusa/products/[id]
Mettre à jour un produit
DELETE
/api/medusa/products/[id]
Supprimer un produit
Commandes & Clients
GET
/api/medusa/orders
Liste des commandes
GET
/api/medusa/customers
Liste des clients
Blog Admin
GET
/api/blog
Liste des articles de blog
POST
/api/blog
Créer un article
GET
/api/blog/[slug]/[language]
Récupérer un article par langue
POST
/api/blog/[slug]/[language]
Mettre à jour un article
Bibliothèque Medusa Personnalisée
Le frontend-client utilise une bibliothèque personnalisée dans
lib/personalizedMedusaLibrary.ts pour toutes les requêtes Medusa.
getAllProducts() - Récupérer tous les produits
getProductByHandle() - Produit par handle
getAllCategories() - Toutes les catégories
medusaFetch() - Utilitaire pour requêtes authentifiées
customerAuth - Authentification client (register, login, logout)
Gestion Multilingue
Emerald Grit supporte nativement 6 langues avec gestion complète des traductions.
Configuration i18n
Configuration dans nuxt.config.ts :
i18n: {
locales: [
{ code: 'fr', iso: 'fr-FR', file: 'fr.json', name: 'Français' },
{ code: 'en', iso: 'en-US', file: 'en.json', name: 'English' },
{ code: 'es', iso: 'es-ES', file: 'es.json', name: 'Español' },
{ code: 'de', iso: 'de-DE', file: 'de.json', name: 'Deutsch' },
{ code: 'it', iso: 'it-IT', file: 'it.json', name: 'Italiano' },
{ code: 'zh', iso: 'zh-CN', file: 'zh.json', name: '中文' }
],
defaultLocale: 'fr',
langDir: 'locales', // ⚠️ IMPORTANT : pas 'i18n/locales'
strategy: 'no_prefix',
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'user-locale',
fallbackLocale: 'fr'
}
}
Fichiers de Traduction
Les fichiers sont dans i18n/locales/ :
fr.json - Français (par défaut)
en.json - English
es.json - Español
de.json - Deutsch
it.json - Italiano
zh.json - 中文
Contenu Multilingue
Le contenu éditorial des produits est stocké dans product_extended_content
avec une entrée par langue via product_content_link.
Chaque langue peut avoir :
- Titre traduit
- Histoire de durabilité
- Instructions d'entretien
- Détails matériaux
- Processus de production
- Certifications (texte)
Déploiement en Production
Architecture Serveur VPS Ubuntu
Configuration recommandée pour la production :
# Serveur VPS Ubuntu
# Medusa v2 : http://localhost:9000 (interne)
# Frontend Client : Port 3001
# Frontend Admin : Port 3002
# Frontend Client (.env)
NUXT_PUBLIC_APP_URL=http://votre-domaine.com
NUXT_PUBLIC_MEDUSA_BACKEND_URL=http://localhost:9000
MEDUSA_URL=http://localhost:9000
NODE_ENV=production
HOST=0.0.0.0
PORT=3001
# Frontend Admin (.env.local)
NEXT_PUBLIC_MEDUSA_URL=http://localhost:9000
DATABASE_URL=postgresql://user:password@localhost:5432/emerald-grit
NODE_ENV=production
Déploiement avec PM2
Configuration PM2 pour le frontend-client :
# Installer PM2
npm install -g pm2
# Démarrer l'application
cd frontend-client
pm2 start pm2.config.cjs
# Sauvegarder la configuration
pm2 save
# Voir les logs
pm2 logs emerald-grit
# Redémarrer
pm2 restart emerald-grit
Configuration PM2 (pm2.config.cjs)
module.exports = {
apps: [{
name: 'emerald-grit',
script: '.output/server/index.mjs',
instances: 1,
exec_mode: 'fork',
env_file: '.env',
env: {
NODE_ENV: 'production',
PORT: 3001,
HOST: '0.0.0.0'
}
}]
};
Vérifications Post-Déploiement
- Vérifier que Medusa tourne :
curl http://localhost:9000/health
- Vérifier le frontend :
curl http://localhost:3001
- Vérifier le back-office :
curl http://localhost:3002
- Vérifier la base de données :
psql -U postgres -d emerald-grit -c "SELECT COUNT(*) FROM blog_posts;"
Frontend Client (Nuxt.js)
Technologies
- Nuxt.js 3 avec SSR et SSG
- Vue 3 Composition API
- Tailwind CSS v4 avec configuration CSS-first
- @nuxtjs/i18n pour le multilingue
- @nuxtjs/medusa pour l'intégration Medusa
- Nuxt UI pour les composants
Structure des Pages
pages/index.vue - Landing page
pages/products/[...slug].vue - Pages produits dynamiques
pages/products/index.vue - Liste des produits
pages/blog/ - Blog et articles
pages/account/ - Compte utilisateur
pages/cart.vue - Panier
pages/checkout.vue - Checkout
pages/engagement/ - Pages engagement
pages/research/ - Pages recherche
Composables Principaux
useCategories() - Gestion des catégories
useProductUrl() - Génération d'URLs produits
useMedusa() - Client Medusa
useNotification() - Système de notifications
Backend Medusa v2
Modules de Commerce
Emerald Grit utilise les modules suivants de Medusa v2 :
- Product Module - Produits, variants, catégories
- Cart Module - Panier et checkout
- Payment Module - Traitement des paiements
- Order Module - Gestion des commandes
- Inventory Module - Gestion du stock
- Fulfillment Module - Exécution des commandes
- Customer Module - Gestion des clients
- User Module - Gestion des utilisateurs admin
- Auth Module - Authentification
Intégration avec @medusajs/js-sdk
Le frontend-admin utilise le SDK officiel :
import Medusa from "@medusajs/js-sdk";
const client = new Medusa({
baseUrl: 'http://localhost:9000',
apiKey: 'sk_...' // Admin API key
});
// Utilisation
const products = await client.admin.product.list();
const product = await client.admin.product.retrieve(id);
const order = await client.admin.order.retrieve(id);
Base de Données PostgreSQL
Tables Principales
- blog_posts - Articles de blog multilingues
- product_additional_data - Données éco-score globales
- product_extended_content - Contenu éditorial multilingue
- product_content_link - Lien produit ↔ contenu par langue
- brands - Marques avec éco-scores
Connexion
Configuration via DATABASE_URL avec support SSL :
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
}
});
Environnements de Développement
Variables d'Environnement par Composant
Frontend Client (Développement)
# .env (développement local)
NUXT_PUBLIC_APP_URL=http://localhost:3001
NUXT_PUBLIC_MEDUSA_BACKEND_URL=http://localhost:9000
MEDUSA_URL=http://localhost:9000
DATABASE_URL=postgresql://user:password@localhost:5432/emerald-grit
NODE_ENV=development
PORT=3001
Frontend Client (Production)
# .env (production sur VPS)
NUXT_PUBLIC_APP_URL=http://votre-domaine.com
NUXT_PUBLIC_MEDUSA_BACKEND_URL=http://localhost:9000
MEDUSA_URL=http://localhost:9000
DATABASE_URL=postgresql://user:password@localhost:5432/emerald-grit
NODE_ENV=production
HOST=0.0.0.0
PORT=3001
Frontend Admin (Développement)
# .env.local (développement)
NEXT_PUBLIC_MEDUSA_URL=http://localhost:9000
DATABASE_URL=postgresql://user:password@localhost:5432/emerald-grit
NODE_ENV=development
Frontend Admin (Production)
# .env.local (production)
NEXT_PUBLIC_MEDUSA_URL=http://localhost:9000
DATABASE_URL=postgresql://user:password@localhost:5432/emerald-grit
NODE_ENV=production
Différences Clés Production vs Développement
| Variable |
Développement |
Production |
MEDUSA_URL |
IP externe (localhost:9000) |
localhost:9000 |
DATABASE_URL |
IP externe du serveur |
localhost |
NODE_ENV |
development |
production |
Vérification des Variables
Commandes utiles pour vérifier la configuration :
# Vérifier les variables d'environnement (Frontend Client)
cd frontend-client
cat .env | grep MEDUSA
# Vérifier les variables d'environnement (Frontend Admin)
cd frontend-admin
cat .env.local | grep MEDUSA
# Tester la connexion Medusa
curl http://localhost:9000/health
# ou depuis l'extérieur
curl http://localhost:9000/health
# Tester la connexion PostgreSQL
psql $DATABASE_URL -c "SELECT version();"