profound-logoProfound CMS
⌘K
Admin
Theme
DocsTutorialBlogPhilosophy
DocsTutorialBlogPhilosophy

Tutorials

Build & Ship an Airport DirectoryDeploymentsBuild & Ship a Stripe Storefront

Feature

Documentation Site TemplateFeature Template BuilderTranslation ServiceOrganizations & Website HeirarchyConnect Profound CMS to your AI clientSettings IntegrationsSettings API KeysSettings UsageSettings Websites
All Systems Operational
Powered Byprofound-logo
Theme

Build & Ship a Stripe Storefront

En praktisk gjennomgang: bygg en innholdsdrevet Stripe-butikkfront pĂ„ Profound CMS — en katalog en kjĂžpmann redigerer uten kode, to parametriske ruter, en headless-handlekurv og Stripe-hostet utsjekk.

Den ferdige butikken i bevegelse — bla gjennom en kategori, Ă„pne et produkt, legg i handlekurven, gĂ„ til kassen.

En praktisk gjennomgang som bygger en innholdsdrevet butikk pÄ Profound CMS: en produkt- katalog (kategorier + varer) modellert i CMS-et, liste- og detaljsider fra ett sett med ruter, og Stripe-hostet utsjekk levert som en headless-komponent.

Ryggraden er hĂ„ndskrevet Next.js pluss Profound-admin. Claude Code (via Profound MCP) trekker det tyngste lasset pĂ„ tre oppgaver — fyller katalogen, kobler design-systemet, og skriver butikkkomponentene (inkludert den headless-handlekurven). Tre deler: Oppsett, Bygg, Produksjon.

Betalinger pĂ„ Ă©n linje. Vi bruker Stripe-hostet Checkout: kunden betaler pĂ„ Stripes side, ikke din. Appen din gjĂžr bare to ting pĂ„ serversiden — oppretter en Checkout Session og verifiserer Ă©n webhook. Ingen kortfelt, ingen Stripe Elements, ingen PCI-byrde.

Hva du skal bygge

  • En liten publisert katalog i CMS-et — tre kategorier og Ă„tte produkter (demoen «Edison’s Inventions») — hver redigerbar av en kjĂžpmann uten kode.
  • To parametriske ruter (/products/{item_code}, /categories/{category_code}) pluss en statisk /cart, alt fra ett sett med komponenter.
  • En headless-handlekurv (useCart) og Stripe-hostet utsjekk, med prisen alltid avklart pĂ„ serveren fra en Stripe Price ID.
  • Butikken distribuert til Vercel med direkte forhĂ„ndsvisning og redigering pĂ„ stedet for teamet.

Forutsetninger

  • Bun ≄ 1,3 — curl -fsSL https://bun.sh/install | bash
  • Claude Code med Profound MCP (Del 1 installerer den).
  • En Profound CMS-konto.
  • En Stripe-konto. Denne veiledningen kjĂžres i testmodus slik at ingenting belastes med ekte penger mens du bygger — men flyten er identisk med live-nĂžkler, sĂ„ bruk dine ekte kontonĂžkler hvis du foretrekker det. (Testmodus krever ingen bedrifts- eller bankdetaljer.)
  • Stripe CLI (stripe login) for lokale webhooks.
  • For distribusjon: GitHub CLI (gh) og en Vercel-konto koblet til GitHub.

Hvordan bitene passer sammen

Profound skiller innhold fra rendering:

  • Komponenter definerer formen pĂ„ innholdet. En Custom Component med et Route Slug-felt er rutbar (category, item); Ă©n merket UI Element kan plasseres pĂ„ en side (nav, product_grid, 
).
  • Documenter er innholdet (et produkt, en kategori).
  • UI-elementer er seksjoner pĂ„ en side; hvert skalart felt tar en statisk verdi eller et CEL-uttrykk, evaluert ved rendering.
  • Parametriske ruter kartlegger en URL til et dokument + UI-elementer, og sender ruteparametre (meta.params.* i CEL, routeParams i React).
  • Next.js-appen din leser det gjennom cms-renderer; Stripe legges til som ordinĂŠre API-ruter.

Den ene regelen som former byggingen: CEL binder kun string- og number-felt. SĂ„ skalar krom (nav-brand, bunntekst, overskrifter) bindes med CEL, mens alt som er rikt eller samlinger (et produktgalleri, et bildegalleri, rik tekst) hentes inne i React- komponenten via ruteparameter. Og Stripe er kilde til sannhet for prising — CMS- price er kun for visning; belĂžpet avklares alltid pĂ„ serversiden fra en Stripe Price ID.

Del 1 — Oppsett

Sluttresultat: en liten publisert katalog, appen tilkoblet for Ă„ lese den, Stripe installert, design pĂ„ plass — ingenting rendret ennĂ„.

1. Registrer deg og opprett nettsiden

Registrer deg hos Profound (WorkOS-autentisering). Opprett en nettside som heter store, kopier deretter website ID-en (UUID-en i admin-URL-en) og en lese-nivĂ„ API-nĂžkkel (Deployments → Create API key). Appen leser bare; katalogseedingen skjer senere via MCP-en, som autentiserer separat.

2. Skjelett appen, koble den til og legg til Stripe

bunx create-profound-next store
cd store
bun add stripe

Skjelettet er et Next.js App Router-prosjekt forhĂ„ndskablet for Profound (cms-renderer-SDK, en catch-all-rute, et generate-schemas-skript, en <Refresher>). Det leveres uten stiler. bun add stripe henter server-SDK-en — den eneste betalingsavhengigheten en hostet utsjekk trenger.

Legg verdiene dine til .env.local:

# CMS
PROFOUND_API_KEY=<din lesekey>
NEXT_PUBLIC_PROFOUND_WEBSITE_ID=<din website-id>
NEXT_PUBLIC_CMS_API_URL=https://cms.dev.tryprofound.com
NEXT_PUBLIC_BUNNY_CDN_URL=https://cms-profound.b-cdn.net   # leverer CMS-hostede bilder

# Stripe
STRIPE_SECRET_KEY=sk_test_...            # testnÞkkel her; bytt til live-nÞkkelen nÄr du gÄr live
STRIPE_WEBHOOK_SECRET=whsec_...          # fylles inn i Bygg, trinn 4
NEXT_PUBLIC_SITE_URL=http://localhost:3000

Hent STRIPE_SECRET_KEY fra Stripe → Developers → API keys. Vi bruker en testnĂžkkel (sk_test_
) slik at byggingen aldri flytter ekte penger; bytt til live-nĂžkkelen nĂ„r du er klar for ekte betalinger. KjĂžr bun dev og Ă„pne localhost:3000 — startprosjektet rendres.

Hostet checkout videresender nettleseren til en Stripe-URL, sĂ„ serverens hemmelige nĂžkkel er alt Stripe trenger — ingen publiserbar nĂžkkel, ingen Stripe-klient-SDK.

3. Definer komponentene category, product_image og item

Opprett tre Custom Components (Components → Create new component) — datakilden, sĂ„ ingen UI Element-tag. Sett hver som Active.

CMS-et har ikke et felt for «array av bilder», sĂ„ et galleri er en array av referanser til en liten product_image-komponent. Opprett category og product_image (og sett dem Active) fĂžr item — et referansefelt kan bare peke mot aktive komponenter.

  • category — name (Text), code (Text, Route Slug), description (Rich text), heroImage (Image)
  • product_image — image (Image)
  • item — name (Text), code (Text, Route Slug), description (Rich text), images (array av referanser → product_image), price (Number, Ăžre — kun visning), currency (Select, usd), stripePriceId (Text), category (Reference → category), active (Boolean)

La alle felt vĂŠre valgfrie. Adminen bruker lavere snake_case pĂ„ feltnavn («Stripe Price Id» → stripe_price_id) — det er det koden din benytter, sĂ„ les de faktiske navnene tilbake fra generate-schemas senere. Vi kaller det rutbare hĂ„ndtaket code (ikke slug): det er Route Slug og nĂžkkelen for et ryddig documents.getByCode-oppslag senere.

item-komponenten — code som Route Slug, images som referanser til product_image, pluss stripePriceId og en category-referanse.

4. Hent komponentene ned til lokale typer

bun run generate-schemas

Skriver Zod-skjemaer + typer til generated/cms-schemas.ts (categorySchema/Category, itemSchema/Item). Dobbeltkontroll som tilkobling — feil legitimasjon feiler her.

5. Seed katalogen via Profound MCP

Installer og autentiser MCP-en én gang:

claude mcp add --transport http Profound http://107.21.107.99:8081/mcp

KjĂžr mcp__Profound__authenticate, fullfĂžr WorkOS-flyten, og be deretter Claude:

Generer en liten e-handelskatalog for en butikk kalt Edison’s Inventions — tre kategorier og disse produktene, med en kort tidsriktig description for hver, en price i þre, currency: "usd", og active: true:

  • Lighting & Power (code: lighting): Incandescent Lightbulb (incandescent-lightbulb, $24), Electric Dynamo (electric-dynamo, $890), Electric Pen (electric-pen, $49)
  • Sound Recording (code: sound): Tinfoil Phonograph (tinfoil-phonograph, $249), Carbon Microphone (carbon-microphone, $59), Dictaphone (dictaphone, $179)
  • Motion Pictures (code: motion): Kinetoscope (kinetoscope, $399), Kinetograph Camera (kinetograph, $549)

Hver kategori trenger et name og den smĂ„ bokstaver code; hvert item trenger et name, den smĂ„ bokstaver code, description, price (i Ăžre), currency og active. Lagre det i data/catalog.json og valider det mot komponentene vĂ„re category og item. Opprett deretter hver som et publisert dokument via Profound MCP: opprett kategoriene fĂžrst, fang ID-ene deres, opprett deretter varene med category satt til en referanse — { "_type": "reference", "_ref": "<category-id>", "_schema": "category" }. La stripePriceId stĂ„ tom for nĂ„. GjĂžr varene parallelt.

Claude skriver data/catalog.json, validerer det, og sender parallelle create_document-

kall (status: "published"). Seed kategorier fÞr varer slik at referansene peker pÄ ID-er som allerede finnes.

De tre seeded-kategoriene, publisert og Live.

De Ätte seeded-produktene, hver knyttet til en kategori.

6. Opprett Stripe-priser og koble noen produkter

Katalogen ligger i CMS-et; gi nĂ„ noen produkter en ekte Stripe-pris — kjĂžpmannens jobb, utfĂžrt i to admin-paneler, uten kode:

  1. Stripe Dashboard → Products → + Add product, sett en engangspris, kopier Price ID (price_
).
  2. GjĂžr dette for cirka tre hovedprodukter (f.eks. Lightbulb, Phonograph, Kinetoscope).
  3. Profound-admin → item → Documents → lim hver Price ID inn i stripePriceId, lagre.

CMS-et holder katalogen; Stripe holder den autoritative prisen; forbindelsen er Ă©n streng som kjĂžpmannen limer inn. (Vil du automatisere det? Den offisielle Stripe MCP kan opprette Products/Prices for deg — lim inn ID-ene pĂ„ samme mĂ„te.)

7. Legg inn design-systemet og kable det med KI

Skjelettet leveres uten stil. Legg en DESIGN.md (en Tailwind v4 @theme-blokk + tokens) i prosjektroten — din egen, eller last ned en fra refero.design. Be deretter Claude, begrenset til styling:

Les designfilen jeg nettopp la til. Sett opp Tailwind hvis det trengs, og kople inn temaet og fontene slik at stylingen fungerer. Bruk next/font for fonter — ikke last dem fra Google ved kjĂžretid. Bare styling — ikke bygg sider eller komponenter ennĂ„.

Kontroller at src/app/globals.css har @import "tailwindcss"; + @theme-blokken og at localhost:3000 viser tokenene. Hold prompten stram (Äpen, sÄ skjeletter agenten hele forsiden), og last fonter via next/font, aldri en Google-import ved kjÞretid.

8. Legg til produktbilder (valgfritt)

Valgfritt — du kan nĂ„ en fungerende utsjekk uten bilder. For Ă„ legge dem til: opprett et product_image-dokument per bilde (last opp i image-feltet), og referer dem fra produktets images-array. Bruk egne produktbilder, eller generer et helhetlig sett med en bilde-modell (la Claude utlede merkevare-vennlige prompt fra DESIGN.md og lĂ„s Ă©n Midjourney---sref slik at hvert bilde matcher).

Den frittstĂ„ende cms-renderer har ingen helper for bilde-URL, sĂ„ legg inn buildAssetUrl i src/lib/image.ts (~40 linjer) — den prefikser NEXT_PUBLIC_BUNNY_CDN_URL og legger til filendelsen. Komponentene i Bygg, trinn 3 bruker den.

Del 2 — Bygg

Bygg rendereringslaget og utsjekken, og avslutt i et ekte kjĂžp i testmodus.

1. Definer de fem UI-element-komponentene

Fem komponenter, hver Active og merket UI Element (Settings → Tags), ingen Route Slug:

  • nav → brand · product_grid → heading · product_detail → heading · cart_summary → heading · footer → text (alle Text)

UI Element-taggen er det som gjþr at en komponent vises i Page Builder-listen Add UI Element — Active alene er ikke nok. Hvert felt er et skalarfelt (typen CEL binder); selve katalogdataene er ikke et felt her — ProductGrid/ProductDetail henter dem via ruteparameter (trinn 3).

2. Generer typene pÄ nytt

bun run generate-schemas

3. Generer katalogleseren, komponentene og headless-handlekurven

Én prompt bygger lesehelperen, de fem komponentene, handlekurven og registeret:

Bygg butikken vÄr i src/, ved Ä bruke Profound-cms-renderer-SDK-en.

src/lib/catalog.ts — en server-side CMS-leser. Opprett en klient med getCmsClient({ cmsUrl: process.env.NEXT_PUBLIC_CMS_API_URL!, apiKey: process.env.PROFOUND_API_KEY, websiteId: process.env.NEXT_PUBLIC_PROFOUND_WEBSITE_ID! }) fra cms-renderer/lib/cms-api. Eksporter getItemByCode(code) → cms.documents.getByCode.query({ websiteId, schemaName: "item", code }) som returnerer res.document.published_content. Eksporter listItems(categoryCode?) → cms.documents.list.query({ websiteId, schemaName: "item", status: "published", limit: 100 }), map res.documents til .published_content, filtrer active !== false, og hvis categoryCode er gitt, behold items der category._ref er lik kategoriens document.id. Eksporter resolveImages(refs) som lþser hver item.images-referanse via cms.documents.get.query({ websiteId, id: ref._ref }) og gjþr bilde- feltet om til en URL med den vendede buildAssetUrl (Del 1 trinn 8).

src/components/ — fem UI-element-komponenter registrert i catch-all-rutens register etter komponentnavn, snake_case for Ă„ matche admin: { nav, product_grid, product_detail, cart_summary, footer }. Nav og Footer leser skalarfeltet sitt fra content-propen (typet BlockComponentProps<T> fra cms-renderer/lib/types). ProductGrid og ProductDetail er asynkrone serverkomponenter som leser routeParams og henter fra catalog.ts: routeParams.<param> er { value, 
 } — les .value, sĂ„ ProductGrid kaller listItems(routeParams.category_code?.value) (kortene lenker til /products/{code}) og ProductDetail kaller getItemByCode(routeParams.item_code?.value) (galleri via resolveImages, rik-tekst-beskrivelse, pris, Legg i handlekurv). CartSummary rendrer handlekurven fra useCart med en Betal-knapp. Hold formatPrice i en ren src/lib/format.ts slik at klientkomponenter ikke importerer server-only catalog.ts.

src/components/AddToCartButton.tsx — en "use client"-knapp som tar { code, name, priceLabel } og kaller useCart().addItem({ code, name, priceLabel, quantity: 1 }). Bruk den inne i ProductDetail.

src/lib/useCart.ts — en headless-handlekurv: linjeelementer { code, name, priceLabel, quantity } i state, persistert til localStorage, som eksponerer addItem/removeItem/updateQty/subtotal og en checkout() som POST-er { lines: [{ code, quantity }] } (kun koder og antall — aldri priser) til /api/stripe/checkout, og omdirigerer til url-en som returneres.

Style alt med design-systemet vĂ„rt, som vĂ„re egne komponenter — ikke kopier kilde-nettstedets layout.

Tre ting du mÄ vite etter at det kjÞrer:

  • Skalarkrom kommer inn via content ({ content }: BlockComponentProps<T>) — destrukturer feltene som top-level-proper og blokken rendrer tom. Katalogdata kommer fra routeParams + et catalog.ts-oppslag, fordi CEL ikke kan binde lister eller galleri. Handlekurven bĂŠrer vare-koder, aldri priser.
  • routeParams.<param> er { value, schemaName, document } — les .value. Les returnerer published_content, ikke .content. RegisternĂžkler er snake_case for Ă„ matche admin.
  • Oppgrader @types/react/@types/react-dom til v19 — skjelettet leveres med v18, som Ăždelegger async serverkomponentblokker mot React 19.

4. Skriv Stripe-serverkoden (ryggraden)

Tre korte serverfiler — den eneste betalingskoden i appen. De gjenbruker getItemByCode, sĂ„ belĂžpet avklares pĂ„ serveren.

src/lib/stripe.ts:

import Stripe from "stripe";
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);

src/app/api/stripe/checkout/route.ts — lþser hver vare fra CMS-et, avklarer Stripe-prisen:

import { NextResponse } from "next/server";
import { stripe } from "@/lib/stripe";
import { getItemByCode } from "@/lib/catalog"; // serverside, lesetiernĂžkkel

export async function POST(req: Request) {
  const { lines } = await req.json();                // [{ code, quantity }] — ingen priser fra klienten
  const line_items = await Promise.all(
    lines.map(async ({ code, quantity }: { code: string; quantity: number }) => {
      const item = await getItemByCode(code);          // serveren lĂžser fra CMS-et
      return { price: item!.stripe_price_id, quantity }; // pris fra CMS, aldri klient
    })
  );
  const session = await stripe.checkout.sessions.create({
    mode: "payment",
    line_items,
    success_url: `${process.env.NEXT_PUBLIC_SITE_URL}/cart?status=success`,
    cancel_url: `${process.env.NEXT_PUBLIC_SITE_URL}/cart?status=cancelled`,
  });
  return NextResponse.json({ url: session.url });     // klienten omdirigerer hit
}

src/app/api/stripe/webhook/route.ts — det betrodde fullfþringssignalet:

import { stripe } from "@/lib/stripe";

export async function POST(req: Request) {
  const body = await req.text();                      // RÅ kropp — nþdvendig for signaturverifisering
  const sig = req.headers.get("stripe-signature")!;
  let event;
  try {
    event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!);
  } catch {
    return new Response("Ugyldig signatur", { status: 400 });
  }
  if (event.type === "checkout.session.completed") {
    // fullfĂžr: registrer bestillingen / send kvittering.
  }
  return new Response(null, { status: 200 });
}

PÄkrevd skjelettfiks: skjelettets src/proxy.ts videresender alle /api/* til CMS-et, sÄ Stripe-rutene dine kjÞrer aldri. La dem passere fÞrst:

import { createCmsProxy } from "cms-renderer/lib/proxy";
import { NextResponse, type NextRequest } from "next/server";
import { cmsConfig } from "@/lib/cms-config";

const cmsProxy = createCmsProxy({ upstream: cmsConfig.cmsUrl });
const LOCAL_API_PREFIXES = ["/api/stripe"];

export const proxy = async (request: NextRequest) => {
  if (LOCAL_API_PREFIXES.some((p) => request.nextUrl.pathname.startsWith(p))) {
    return NextResponse.next();                       // hÄndter lokalt
  }
  return cmsProxy(request as unknown as Parameters<typeof cmsProxy>[0]);
};
// behold skjelettets `export const config = { matcher: [...] }` uendret

Bekreft: curl -X POST localhost:3000/api/stripe/webhook -d x returnerer Ugyldig signatur.

KjĂžr Stripe CLI for lokale webhooks:

stripe login
stripe listen --forward-to localhost:3000/api/stripe/webhook
# kopier whsec_... inn i STRIPE_WEBHOOK_SECRET, start bun dev pÄ nytt

whsec_
 er per Þkt. To regler bÊrer sikkerheten: Checkout gjenutleder prisen fra CMS-et via code (en manipulert handlekurv kan ikke endre den), og webhooken verifiserer signaturen mot den rÄ kroppen.

5. Opprett rutene

Admin → Pages → Create page, tre ganger. Koble hver parameter til komponenten sin (slug-felt code):

  1. /products/{item_code} → item
  2. /categories/{category_code} → category
  3. /cart — en statisk side (skriv inn bokstavelig /cart, ikke /{cart})

6. Legg til UI-elementer, kable CEL, publiser

For hver rute: Page Builder → Add UI Element → Custom → legg til komponenter i rekkefþlge, fyll skalarfeltene (statisk verdi eller CEL), Publish.

  • /products/{item_code}: nav, product_detail, footer
  • /categories/{category_code}: nav, product_grid, footer
  • /cart: nav, cart_summary, footer

Sett nav.brand og footer.text til statiske strenger; overskrifter til statiske etiketter.

Page Builder pĂ„ kategori-ruten — product_grid-elementet er valgt, heading bundet via CEL.

Page Builder pĂ„ produkt-ruten — product_detail-elementet pĂ„ en produktbinding.

Parametrisk Page Builder-fallgruve: pÄ de to parametriske rutene persisterer ikke UI-elementer nÄr du legger dem til (blokker blir foreldrelÞse og siden rendrer tom). Inntil det er fikset, kabler du disse sidenes block_ids direkte via Profound MCP update_page, og publiser. (Statisk /cart kobles normalt.) Av samme grunn henter ProductGrid headingen sin fra kategorien den henter i stedet for via CEL.

7. Render og kjĂžp

  • /categories/lighting → galleriet. Klikk et produkt → detalj + Legg i handlekurv. /cart → Betal.
  • Betaling omdirigerer til Stripe-hostet checkout. Bruk testkortet 4242 4242 4242 4242, en valgfri fremtidig utlĂžpsdato/CVC. Du returnerer til /cart?status=success, og stripe listen viser checkout.session.completed.

En rendret produktside — galleri, pris og Legg i handlekurv.

Handlekurven — linjeelementer og Ă©n Betal med Stripe-knapp.

Bare prisede varer kan kjĂžpes — kjĂžp en av de ~3 du satte pris pĂ„ i trinn 6.

Valgfritt — internasjonaliser. Oversett hver komponent (alle 35 sprĂ„k pĂ„ Ă©n gang), legg til et /{language}/
-segment kartlagt til den innebygde language-System-komponenten, og bytt CEL-bundne felt til documents.translated. Se flyplasstutorialen, Del 2 trinn 7.

Del 3 — Produksjon

1. Send den: GitHub, deretter Vercel

git init && git add -A && git commit -m "Stripe-butikkfront"
gh repo create store --private --source=. --push   # --public er ogsÄ greit

Byggekommando: generated/cms-schemas.ts er ignorert av git, sĂ„ lĂ„s byggingen til Ă„ regenerere den — legg til vercel.json:

{ "$schema": "https://openapi.vercel.sh/vercel.json", "buildCommand": "bun run generate-schemas && next build" }

I Vercel: Add New → Project, importer store, og legg til miljþvariablene — PROFOUND_API_KEY, NEXT_PUBLIC_PROFOUND_WEBSITE_ID, NEXT_PUBLIC_CMS_API_URL, NEXT_PUBLIC_BUNNY_CDN_URL, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET (verdien for distribusjon, under), og NEXT_PUBLIC_SITE_URL (prod-URL-en din). Distribuer.

Koble deretter den distribuerte webhooken (den lokale stripe listen-hemmeligheten var kun lokal): Stripe → Developers → Webhooks → + Add endpoint → https://<prod>/api/stripe/webhook, event checkout.session.completed. Kopier whsec_
 til Vercel og distribuer pĂ„ nytt.

Manglende miljĂžvariabler = «fungerer lokalt, tomt i prod» — den vanligste distribusjonsfellen. Vi publiserer med testnĂžkler her; bytt STRIPE_SECRET_KEY og webhook-hemmeligheten til dine live-verdier nĂ„r du er klar for ekte betalinger.

2. Direkte forhÄndsvisning og redigering pÄ stedet

Begge leveres med skjelettet.

  • Direkte forhĂ„ndsvisning: <Refresher> oppdaterer siden du forhĂ„ndsviser nĂ„r en redaktĂžr lagrer i admin — ingen redistribusjon. (Det er en forhĂ„ndsvisning for redaktĂžren; besĂžkende ser publisert innhold ved normal revalidasjon.)
  • Redigering pĂ„ stedet: legg til ?edit_mode=true pĂ„ en URL for redigeringsoverlegg. Vanlige besĂžkende fĂ„r den rene siden.

Legg til forhÄndsvisningsruten som skjelettet utelater. Admin laster forhÄndsvisnings-iframe-en sin pÄ /cms-preview_<path>; uten denne ruten fÄr hver forhÄndsvisning 404. Legg den til:

// src/app/cms-preview_/[...slug]/page.tsx
import { ParametricRoutePreviewPage } from "cms-renderer/lib/renderer";
import { registry } from "../../registry";   // ekstraher registeret til en delt modul
export default async function Page({ params, searchParams }) {
  const { slug } = await params;
  const PreviewPage = ParametricRoutePreviewPage as any; // async RSC; React 19-typer
  return <PreviewPage registry={registry} apiKey={process.env.PROFOUND_API_KEY ?? ""}
    websiteId={process.env.NEXT_PUBLIC_PROFOUND_WEBSITE_ID ?? ""}
    cmsUrl={process.env.NEXT_PUBLIC_CMS_API_URL ?? "https://cms.dev.tryprofound.com"}
    params={Promise.resolve({ slug })} searchParams={searchParams} />;
}

Legg ogsÄ til src/app/cms-preview_/page.tsx (samme, slug: []) for segmentroten.

Det var byggingen

En innholdsdrevet Stripe-butikkfront: en CMS-katalog, liste- + detaljsider fra ett sett med ruter, og en fungerende hostet utsjekk. KI seedet katalogen, koblet designet og skrev katalogleser + komponenter + headless-handlekurv; du gjorde komponentene, Stripe-pris-koblingene, de tre rutene, CEL-kromet og tre korte Stripe-filer. CEL binder kromet; komponenter henter katalogen. Og Stripe forble liten — ett sessions.create-kall og Ă©n signert webhook, med kunden som betaler pĂ„ Stripes egen side.

Continue Reading
Previousâ€čDeployments