Editorial e-commerce front end for limited-edition works: Next.js 16 (App Router), Tailwind CSS 4, shadcn/ui, Storybook, Supabase (client helpers), and Stripe (hosted Checkout session + webhook scaffold). UI routes mirror the linked Figma frames (home, portfolio / “Residue”, curate grid & detail, cart, checkout summary, about).
npm run dev # Next.js dev server
npm run build # Production build
npm run start # Serve production build
npm run lint # ESLint
npm run storybook # Component workshopCopy .env.example to .env.local and fill values from the Supabase and Stripe dashboards. getSupabaseBrowser() returns null until NEXT_PUBLIC_SUPABASE_* are set, so the storefront still runs for local UI work.
-
Dashboard → API keys (Test mode): set
STRIPE_SECRET_KEY(sk_test_…). OptionalNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYfor future client-side Stripe (hosted Checkout works without it). -
Set
NEXT_PUBLIC_SITE_URLto the exact URL you open in the browser (e.g.http://localhost:3000locally, productionhttps://…). Success/cancel URLs for Checkout are derived from this. -
Webhooks (recommended for real orders): Webhooks → add endpoint
https://your-domain.com/api/webhooks/stripeand subscribe tocheckout.session.completed. Copy the signing secret intoSTRIPE_WEBHOOK_SECRET.
Local CLI:stripe login, then:stripe listen --forward-to localhost:3000/api/webhooks/stripe
Use the CLI’s
whsec_…secret asSTRIPE_WEBHOOK_SECRETwhile testing. -
Flow:
/cart→/checkout→ Continue to payment → Stripe-hosted Checkout →/checkout/success. Inspect events in Stripe Dashboard → Developers → Events.
Enable wallets/Link/regional methods under Payment methods.
Checkout: POST https://r.stripe.com/b → net::ERR_BLOCKED_BY_CLIENT? That’s almost always an ad blocker or privacy extension (uBlock, Brave Shields, etc.) blocking Stripe—not a bad API key. Chrome’s “blocked by client” means the browser extension stopped the request. Allow Stripe domains (stripe.com, checkout.stripe.com, r.stripe.com) for your site, or use incognito without extensions while testing. Payments may still work; blocking can break Link, Radar, or some wallets.
| Path | Figma reference |
|---|---|
/ |
Home hero + caption |
/portfolio |
Long-form “Residue” / series |
/curate |
Grid |
/curate/[slug] |
Edition detail + “Inquire / add to cart” |
/cart |
Cart |
/checkout |
Order summary + Stripe Checkout redirect |
/about |
Myth / about |
Demo imagery uses Unsplash via next/image remote patterns. Replace URLs in src/lib/demo-content.ts with exports from your Figma asset pipeline or Supabase Storage.
- Push this repo to GitHub/GitLab/Bitbucket.
- In Vercel, import the repo, set Root Directory if needed, and add environment variables from
.env.example. - Deploy; note the production URL
*.vercel.app. - Hostinger domain → Vercel
- In Vercel: Project → Settings → Domains → add
yourdomain.comandwww.yourdomain.com. - Vercel shows required DNS records (usually A
76.76.21.21for apex and CNAMEcname.vercel-dns.comforwww, or ALIAS/ANAME depending on DNS host). - In Hostinger hPanel → Domains → DNS / Nameservers: either point nameservers to Vercel or keep Hostinger DNS and add the A/CNAME records Vercel lists.
- In Vercel: Project → Settings → Domains → add
- Wait for DNS propagation; Vercel will issue TLS automatically.
- Set
NEXT_PUBLIC_SITE_URL=https://yourdomain.comin Vercel env for Stripe return URLs.
The app is built for Vercel (serverless + edge-friendly). Hostinger is used as the registrar/DNS home for your custom domain; you typically do not need Hostinger shared hosting for the Next.js app itself.
Add auxiliary tooling (image processing, automation) under e.g. tools/ with its own requirements.txt when needed — not required for the web app.
Design file: Raivis_WebDev. Re-export assets if Figma Dev Mode localhost image URLs are unavailable outside the desktop plugin.