Pas de base de données, pas de problème : e-commerce avec Nuxt Content et Stripe
Publié le 31 mars 2026 · 4 min de lecture
Cet article est traduit automatiquement depuis l'anglais. Voir sur dev.to
Je construis des frontends depuis un certain temps, et une chose qui me surprend encore, c’est combien d’infrastructure nous acceptons comme don pour de petits projets de commerce électronique. Une base de données. Un panneau d’administration. Un abonnement CMS. Un backend pour le coller ensemble.
Pour un catalogue curé de 10 à 50 produits, c’est beaucoup de pièces mobiles.
Le résultat est AURORA Commerce – un magasin Nuxt 4 où les produits vivent dans les fichiers YAML, les paiements passent par Stripe et le coût de l’infrastructure est zéro.
Voici comment je l’ai construit et pourquoi il pourrait être la bonne approche pour votre prochain projet.
L’idée : votre repo est votre base de données
Au lieu de demander une base de données ou d’appeler une API CMS, les données de produits vivent directement dans le dépôt :
content/
products/
heavyweight-crewneck-charcoal.yml
linen-midi-dress-terracotta.yml
oxford-button-down-shirt-white.yml
Chaque fichier est un fichier de produit complet :
productId: 6
title: Heavyweight Crewneck - Charcoal
titleFr: Sweat Crewneck Heavyweight - Charbon
slug: heavyweight-crewneck-charcoal
price: 109
category: sweats
badge: Core line
highlight: Brushed cotton 420 g/m2
description: Oversize sweatshirt in ultra-soft brushed cotton. 420 g/m2 weight,
reinforced collar, and premium finishes. The staple you never take off.
descriptionFr: Sweat oversize en coton brosse ultra-doux 420 g/m2. Col renforce,
finitions soignees. Le basique premium que tu portes tous les jours.
images:
- https://your-cdn.com/product-1.jpg
- https://your-cdn.com/product-2.jpg
- https://your-cdn.com/product-3.jpg
sizes: [S, M, L, XL]
fabricWeightGsm: 420
origin: Knit in France, made in Portugal
sizeChart:
- { size: S, chestCm: 90, waistCm: 74, lengthCm: 67 }
- { size: M, chestCm: 95, waistCm: 79, lengthCm: 68 }
- { size: L, chestCm: 100, waistCm: 84, lengthCm: 69 }
- { size: XL, chestCm: 106, waistCm: 90, lengthCm: 70 }
reviews:
- { author: Theo G., city: Nantes, rating: 5, date: '2026-03-07',
quote: The weight is perfect and the finish feels way above standard sweatshirts. }
Ajouter un produit en dupliquant un fichier. Mettre à jour un prix en changeant un numéro. Déployer sur push. Pas de tableau de bord, pas de migration, pas de clé API à tourner.
C’est trop simple, c’est comme ça, et c’est le point.
Télécharger Nuxt Content v3
[Nuxt Content v3] (https://content.nuxt.com/) gère le partage YAML et expose une API de requête typée.
// pages/boutique.vue
const { data: products } = await useAsyncData('products', () =>
queryCollection('products')
.where('active', '=', true)
.order('productId', 'ASC')
.all()
)
Un seul produit par slug:
// pages/produit/[slug].vue
const { data: product } = await useAsyncData(`product-${slug}`, () =>
queryCollection('products')
.where('slug', '=', slug)
.first()
)
Nuxt Content génère automatiquement une collection typée à partir de votre schéma YAML. Vous obtenez l’autocomplète sur product.sizeChart, product.titleFr, product.fabricWeightGsm — tout cela. TypeScript est heureux. Vous êtes heureux.
L’intégration de Stripe
Le flux de checkout est simple :
- Utilisateur construit un panier (Pinia)
- Frontend appelle une route de serveur avec les éléments du panier
- Le serveur crée une session de check-out et renvoie l’URL
- Les redirections frontales
L’itinéraire du serveur est le seul code backend du projet :
// server/api/checkout-session.post.ts
import Stripe from 'stripe'
export default defineEventHandler(async (event) => {
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!)
const body = await readBody(event)
const session = await stripe.checkout.sessions.create({
mode: 'payment',
line_items: body.items.map((item: CartItem) => ({
quantity: item.quantity,
price_data: {
currency: 'eur',
unit_amount: item.price * 100, // YAML stores euros, Stripe wants cents
product_data: {
name: item.title,
images: [item.thumbnail],
},
},
})),
success_url: `${process.env.NUXT_PUBLIC_APP_URL}/success`,
cancel_url: `${process.env.NUXT_PUBLIC_APP_URL}/panier`,
shipping_address_collection: {
allowed_countries: ['FR', 'BE', 'CH', 'DE', 'GB', 'SE'],
},
})
return { url: session.url }
})
Un détail à noter: j’utilise price_data au lieu d’un identifiant de prix Stripe. Cela signifie que les produits n’ont pas besoin d’exister dans le tableau de bord Stripe du tout - la source de vérité reste dans les fichiers YAML.
Bilingue sans bibliothèque de traduction
La boutique supporte l’anglais et le français nativement. Pas de bibliothèque i18n, pas de fichiers de traduction. La stratégie est simple: champs bilingues directement dans le YAML (title / titleFr, description / descriptionFr), combiné avec la stratégie de routage intégrée de Nuxt (prefix_except_default):
/boutique → English
/fr/boutique → French
Un petit composable résout le bon champ basé sur le local actif :
// composables/useLocaleField.ts
export function useLocaleField() {
const { locale } = useI18n()
function t(en: string, fr?: string): string {
return locale.value === 'fr' && fr ? fr : en
}
return { t }
}
Utilisation dans les temples :
<h1>{{ t(product.title, product.titleFr) }}</h1>
<p>{{ t(product.description, product.descriptionFr) }}</p>
La copie vit avec le produit. Pas de clés à gérer, pas de fichiers à synchroniser.
Des jetons de design en un seul endroit
L’ensemble de l’identité visuelle est contrôlée à partir de «tailwind.config.ts » :
theme: {
extend: {
colors: {
brand: {
primary: '#0A0A0A',
accent: '#C9A96E',
surface: '#F8F6F2',
},
},
fontFamily: {
display: ['Cormorant Garamond', 'serif'],
body: ['DM Sans', 'sans-serif'],
},
},
}
Changer « brand.accent » une fois et chaque bouton, badge, et mettre en évidence les mises à jour à travers le magasin.
Quand cela a du sens - et quand ce n’est pas
Cette approche fonctionne bien lorsque :
- Votre catalogue est petit et curé (moins de 200 produits)
- Vous voulez ** zéro coût d’infrastructure en cours**
- Vous êtes à l’aise avec un flux de travail ** basé surgit** pour les mises à jour de contenu
- Vous voulez ** propriété complète ** – pas de verrouillage de plateforme
Il ne convient pas si vous avez besoin de gestion en temps réel des stocks, d’un client non technique qui a besoin d’un CMS visuel ou de variantes de produits complexes sur plusieurs axes.
Pour le cas CMS spécifiquement: l’architecture prend en charge l’échange de ‘queryCollection’ pour un client Sanity ou Contentful derrière une interface d’adaptateur partagé.
Le résultat
Une boutique complète - maison, magasin, détail du produit, panier, paiement de la bande, pages de réussite et d’annulation, bilingue, mode sombre, SEO prêt - déployable sur Vercel en moins d’une heure.
→ démonstration en direct → AURORA Commerce sur Gumroad — À partir de €29 / Pro €59
Si vous avez des questions ou souhaitez discuter de l’architecture, laissez un commentaire.
Construit avec Nuxt 4, Vue 3, Nuxt Content v3, Pinia, Tailwind CSS, Stripe et Bun.