Next.js E-commerce
Come creare un negozio e-commerce Next.js per la produzione: catalogo, checkout, scorte e SEO
Crea un negozio Next.js 16 pronto per la produzione con prodotti, varianti, carrelli, prezzi gestiti dal server, Stripe Checkout, scorte, SEO e distribuzione.
Una vetrina online diventa un sistema commerciale quando dati del catalogo, prezzi, scorte, stato dei pagamenti, ordini ed evasione devono rimanere coerenti anche con richieste simultanee.
Definisci i confini del sistema commerciale
Trail Supply è l'esempio usato nella guida: un negozio di articoli outdoor che vende Alpine Shell in più colori e taglie. La vetrina presenta i dati del catalogo; il livello commerciale gestisce prezzi ufficiali, scorte, carrelli, pagamenti e ordini; i provider esterni gestiscono pagamenti ed email. Definisci questi confini prima di scegliere i componenti.
Definisci la fonte ufficiale di ogni valore. Un sistema di contenuti può gestire le descrizioni editoriali, mentre un database commerciale gestisce SKU, prezzi e scorte. La pagina del prodotto può combinarli, ma il checkout non deve mai affidarsi ai contenuti editoriali o allo stato del browser per i valori transazionali.
- —Catalogo: prodotti, varianti, categorie, contenuti multimediali e stato di pubblicazione.
- —Commercio: prezzo, valuta, dati fiscali, scorte, carrelli, ordini e rimborsi.
- —Identità: token carrello anonimo, account cliente, indirizzi e autorizzazioni.
- —Operazioni: eventi di pagamento, job di evasione degli ordini, email, stato del servizio, log e rilasci.
Modella prodotti e varianti acquistabili
Un prodotto descrive le caratteristiche comuni di Alpine Shell. Una variante rappresenta una combinazione specifica acquistabile, per esempio blu e taglia media, con il proprio SKU, riferimento di prezzo, disponibilità e stato. Associa ID stabili agli slug leggibili, così gli URL possono cambiare senza compromettere gli ordini o la riconciliazione degli eventi.
Distingui ciò che può essere pubblicato da ciò che può essere acquistato. Un prodotto può rimanere visibile anche se una taglia non è disponibile; un articolo fuori catalogo può restare utile per assistenza e ricerca mentre il checkout è disabilitato. Imposta vincoli nel database per l'unicità degli SKU e la validità dell'appartenenza, senza affidarti solo alla validazione dei moduli.
type Product = {
id: string;
slug: string;
name: string;
published: boolean;
};
type Variant = {
id: string;
productId: string;
sku: string;
color: string;
size: string;
priceId: string;
active: boolean;
};Renderizza le route del catalogo sul server
Usa Server Components per i contenuti di categorie e prodotti, così le richieste dirette contengono titoli, descrizioni, prezzi, link ai prodotti e disponibilità. Mantieni galleria, selettore di taglia e controllo di aggiunta al carrello in Client Components mirati. Il client riceve una vista limitata ai dati necessari per l'acquisto, anziché record del database senza restrizioni.
Scegli la strategia di cache in base al ciclo di vita dei contenuti. Descrizioni e immagini dei prodotti possono cambiare di rado; prezzi e scorte richiedono garanzie più rigorose. Memorizza in cache le letture stabili del catalogo con tag di prodotto e categoria e rivalidale dopo un aggiornamento approvato. Il checkout ricarica sempre i valori transazionali.
Tratta il carrello come una proposta
Un cliente anonimo può ricevere un token casuale per il carrello in un cookie HTTP-only; il relativo record nel database conserva ID delle varianti e quantità. Dopo l'accesso, uniscilo al carrello del cliente con regole esplicite per duplicati, varianti non disponibili e limiti di quantità. Non conservare i prezzi ufficiali in un cookie modificabile.
La pagina del carrello può mostrare una stima calcolata, ma ogni modifica e richiesta di checkout deve ricaricare sul server varianti, prezzi, limiti di acquisto e scorte. Se un prodotto è cambiato, restituisci correzioni per le singole righe anziché addebitare un importo diverso senza avvisare.
Completa il pagamento in modo asincrono
Crea la Stripe Checkout Session sul server a partire dal carrello validato e associa nei metadati un ID stabile del carrello o dell'ordine in attesa. L'URL di ritorno può indicare che il pagamento è in fase di conferma, ma non può creare da solo l'ordine definitivo.
Verifica la firma di Stripe sul corpo originale del webhook, registra l'ID dell'evento con un vincolo di unicità e crea o fai avanzare l'ordine una sola volta. Gestisci sessioni completate e scadute, pagamenti non riusciti, rimborsi ed eventi ripetuti. Metti in coda email ed evasione dopo aver salvato lo stato persistente dell'ordine.
const session = await stripe.checkout.sessions.create({
mode: "payment",
line_items: pricedCart.lines.map((line) => ({
price: line.stripePriceId,
quantity: line.quantity,
})),
success_url: SITE_URL + "/orders/confirm?session_id={CHECKOUT_SESSION_ID}",
cancel_url: SITE_URL + "/cart",
metadata: { pendingOrderId: pendingOrder.id },
});Gestisci le scorte con transazioni
Decidi quando riservare le scorte: all'aggiunta al carrello, alla creazione del checkout o alla conferma del pagamento. Riservarle nel carrello riduce la disponibilità apparente e richiede scadenze brevi; riservarle al pagamento rischia di accettare più checkout simultanei delle scorte disponibili. Il modello di evasione del prodotto determina il compromesso.
Qualunque politica tu scelga, aggiorna le scorte in modo atomico e impedisci quantità negative nel database. Registra la scadenza delle prenotazioni e riconcilia esplicitamente gli eventi di pagamento tardivi. Le cache possono pubblicare la disponibilità, ma sono la tabella delle scorte e la transazione a decidere se un ordine può riservarle.
Rendi i prodotti scopribili e cura la SEO
Definisci consapevolmente un modello canonico per ogni prodotto. Genera titoli, descrizioni, immagini Open Graph, JSON-LD Product e Offer, breadcrumb e voci della sitemap a partire dai record pubblicati. Mantieni prezzo e disponibilità coerenti con la pagina visibile e con il percorso di checkout.
Le pagine di categoria devono collegare i prodotti importanti con veri link. Tratta i filtri come stato dell'applicazione, a meno che una combinazione selezionata abbia una domanda di ricerca e contenuti propri. Per i prodotti fuori catalogo, scegli consapevolmente tra 200, reindirizzamento, 404 e 410 in base all'utilità che la pagina conserva per i clienti.
Distribuisci e verifica il percorso della transazione
Adios esegue il server di produzione completo di Next.js come processo persistente: Server Components, endpoint del carrello, webhook firmati e pagine degli ordini condividono lo stesso rilascio. Il manifest dichiara compilazione, avvio, route di verifica dello stato, dipendenza dal database e riferimenti ai segreti accanto al sorgente.
Distribuisci un'anteprima e verifica l'HTML dei prodotti, un carrello manomesso, due acquirenti simultanei, Checkout in modalità test, eventi duplicati, una sessione scaduta, il passaggio all'invio delle email e un prodotto sconosciuto. Esamina i log della compilazione e dell'ambiente di esecuzione, poi promuovi la versione solo quando l'applicazione risulta sana. Il dominio personalizzato e il TLS gestito rimangono associati alla versione verificata.
adios.yaml
name: trail-supply
build_cmd: npm ci && npm run build
start_cmd: npm start
runtime:
name: node@24
port: 3000
health_path: /api/health
requires:
- db
env:
DATABASE_URL: secret://DATABASE_URL
STRIPE_SECRET_KEY: secret://STRIPE_SECRET_KEY
STRIPE_WEBHOOK_SECRET: secret://STRIPE_WEBHOOK_SECRET