← Tillbaka till artiklar

Ingen databas, inga problem: e-handel med Nuxt Content och Stripe

Publicerad 31 mars 2026 · 4 min läsning

nuxttailwindcssstripebunjs

Den här artikeln är automatiskt översatt från engelska. Visa på dev.to

Jag har byggt frontend för ett tag nu, och en sak som fortfarande förvånar mig är hur mycket infrastruktur vi accepterar som en given för små e-handelsprojekt. En databas. En admin panel. En CMS-prenumeration. En backend för att limma allt ihop.

För en kurerad katalog på 10 till 50 produkter är det mycket rörliga delar.

Resultatet är AURORA Commerce – en Nuxt 4-butik där produkter lever i YAML-filer, betalningar går genom Stripe och infrastrukturkostnaden är noll.

Här är hur jag byggde det och varför det kan vara rätt inställning för ditt nästa projekt.


Idén: din repo är din databas

I stället för att fråga en databas eller ringa ett CMS API, lever produktdata direkt i lagret:

content/
  products/
    heavyweight-crewneck-charcoal.yml
    linen-midi-dress-terracotta.yml
    oxford-button-down-shirt-white.yml

Varje fil är en komplett produktrekord:

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. }

Lägg till en produkt genom att duplicera en fil. Uppdatera ett pris genom att ändra ett nummer. Utplacera på tryck. Ingen instrumentpanel, ingen migrering, ingen API-nyckel att rotera.

Det låter nästan för enkelt. Det är som det är - och det är poängen.


Sök efter Nuxt Content v3

[Nuxt Content v3] (https://content.nuxt.com/) hanterar YAML-analys och avslöjar en typad fråga API. Fetching hela katalogen:

// pages/boutique.vue
const { data: products } = await useAsyncData('products', () =>
  queryCollection('products')
    .where('active', '=', true)
    .order('productId', 'ASC')
    .all()
)

En produkt per slug:

// pages/produit/[slug].vue
const { data: product } = await useAsyncData(`product-${slug}`, () =>
  queryCollection('products')
    .where('slug', '=', slug)
    .first()
)

Nuxt Content genererar en typad samling från ditt YAML-schema automatiskt. Du får autocomplete på product.sizeChart, product.titleFr, product.fabricWeightGsm – hela saken. TypeScript är glad. Du är glad.


Stripe integration

Checkoutflödet är enkelt:

  1. Användaren bygger en vagn (Pinia)
  2. Frontend ringer en serverrutt med varukorgen
  3. Server skapar en Stripe Checkout-session och returnerar URL-adressen
  4. Frontend omdirigeringar

Serverrutten är den enda backend-koden i projektet:

// 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 }
})

En detalj värt att notera: Jag använder price_data i stället för en Stripe pris-ID. Detta innebär att produkter inte behöver existera i Stripe-dashboard alls - källan till sanningen stannar i YAML-filerna.


Tvåspråkigt utan översättningsbibliotek

Storefront stöder engelska och franska nativt. Inget i18n-bibliotek, inga översättningsfiler. Strategin är enkel: tvåspråkiga fält direkt i YAML (title / titleFr, description / descriptionFr), kombinerat med Nuxts inbyggda routingstrategi (prefix_except_default):

/boutique     → English
/fr/boutique  → French

Ett litet kompostabelt fält löser rätt fält baserat på den aktiva lokalen:

// 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 }
}

Användning i templen:

<h1>{{ t(product.title, product.titleFr) }}</h1>
<p>{{ t(product.description, product.descriptionFr) }}</p>

Kopian lever med produkten. Inga nycklar att hantera, inga filer att synkronisera.


Design tokens på ett ställe

Hela den visuella identiteten styrs från tailwind.config.ts:

theme: {
  extend: {
    colors: {
      brand: {
        primary: '#0A0A0A',
        accent: '#C9A96E',
        surface: '#F8F6F2',
      },
    },
    fontFamily: {
      display: ['Cormorant Garamond', 'serif'],
      body: ['DM Sans', 'sans-serif'],
    },
  },
}

Ändra brand.accent en gång och varje knapp, badge och markera uppdateringar över hela butiken.


När det är meningsfullt – och när det inte är

Detta tillvägagångssätt fungerar bra när:

  • Din katalog är **liten och kurerad ** (under ~200 produkter)
  • Du vill ha ** noll löpande infrastrukturkostnad**
  • Du är bekväm med ett git-baserat arbetsflöde för innehållsuppdateringar
  • Du vill ha fullt ägande – ingen plattformslås

Det passar inte om du behöver realtidsinventariehantering, en icke-teknisk klient som behöver ett visuellt CMS eller komplexa produktvarianter över flera axlar.

För CMS-fallet specifikt: arkitekturen stöder byte av ‘queryCollection’ för en Sanity eller Contentful-klient bakom ett delat adaptergränssnitt.


Resultatet är

En fullständig butiksfront - hem, butik, produktdetaljer, varukorg, Stripe checkout, framgång och avbokningssidor, tvåspråkigt, mörkt läge, SEO redo - kan distribueras på Vercel på mindre än en timme.

Live demoAURORA Commerce on Gumroad — Från och med €29 / Pro €59

Om du har frågor eller vill diskutera arkitekturen, lämna en kommentar.


  • Byggd med Nuxt 4, Vue 3, Nuxt Content v3, Pinia, Tailwind CSS, Stripe och Bun.*