profound-logoProfound CMS
⌘K
Admin
Theme
DocsTutorialBlogPhilosophy
DocsTutorialBlogPhilosophy

Tutorials

Build & Ship an Airport DirectoryDeploymentsBuild & Ship a Stripe Storefront

Satura pārvaldības sistēmas funkcijas

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

Praktiska pamācība: izveidojiet uz saturu balstītu Stripe veikalu Profound CMS — katalogu, ko tirgotājs var rediģēt bez koda, divus parametriskus maršrutus, bezgalvas grozu un Stripe mitinātu Checkout.

Pabeigtais veikals darbībā — pārlūkojiet kategoriju, atveriet produktu, pievienojiet grozam un noformējiet pirkumu.

Praktiska pamācība, kurā Profound CMS tiek izveidots uz saturu balstīts veikals: CMS modelēts produktu katalogs (kategorijas un preces), saraksta un detalizētās lapas no viena maršrutu kopuma, kā arī Stripe mitināta apmaksa, kas ieviesta kā bezgalvas komponents.

Pamatā ir ar roku veidots Next.js un Profound administrēšanas panelis. Claude Code (izmantojot Profound MCP) veic galveno darbu trīs jomās — kataloga sākotnējā aizpildīšanā, dizaina sistēmas pieslēgšanā un veikala komponentu (tostarp bezgalvas groza) izveidē. Trīs daļas: Iestatīšana, Izveide, Produkcija.

Maksājumi vienā teikumā. Izmantojam Stripe mitināto Checkout: pircējs maksā Stripe lapā, nevis jūsu lapā. Jūsu lietotne servera pusē veic tikai divas darbības — izveido Checkout sesiju un pārbauda vienu tīmekļa āķi. Nav kartes lauku, Stripe Elements vai PCI atbilstības sloga.

Ko jūs izveidosiet

  • Nelielu CMS publicētu katalogu — trīs kategorijas un astoņus produktus (demonstrācijas katalogs “Edisona izgudrojumi”) — katru no tiem tirgotājs varēs rediģēt bez koda.
  • Divus parametriskus maršrutus (/products/{item_code}, /categories/{category_code}) un statisku /cart, izmantojot vienu komponentu kopumu.
  • Bezgalvas grozu (useCart) un Stripe mitināto Checkout, kur cena vienmēr tiek atrisināta servera pusē, izmantojot Stripe Price ID.
  • Veikalu, kas izvietots Vercel ar tiešo priekšskatījumu un komandas rediģēšanu lapā.

Priekšnoteikumi

  • Bun ≥ 1.3 — curl -fsSL https://bun.sh/install | bash
  • Claude Code ar Profound MCP (1. daļā tas tiek instalēts).
  • Profound CMS konts.
  • Stripe konts. Šī pamācība darbojas testēšanas režīmā, tāpēc izveides laikā netiks iekasēta īsta nauda — taču plūsma ar tiešajām atslēgām ir identiska, tādēļ, ja vēlaties, izmantojiet sava īstā konta atslēgas. (Testēšanas režīmam nav nepieciešama uzņēmuma vai bankas informācija.)
  • Stripe CLI (stripe login) lokālajiem tīmekļa āķiem.
  • Izvietošanai: GitHub CLI (gh) un Vercel konts, kas savienots ar GitHub.

Kā daļas darbojas kopā

Profound atdala saturu no attēlošanas:

  • Komponenti nosaka satura struktūru. Pielāgots komponents ar Route Slug lauku ir maršrutējams (category, item); komponentu, kas atzīmēts kā UI Element, var ievietot lapā (nav, product_grid u. c.).
  • Dokumenti ir saturs (produkts, kategorija).
  • UI elementi ir lapu sadaļas; katrs skalārais lauks pieņem statisku vērtību vai CEL izteiksmi, kas tiek novērtēta renderēšanas laikā.
  • Parametriskie maršruti sasaista URL ar dokumentu un UI elementiem, nododot maršruta parametrus (meta.params.* CEL izteiksmēs, routeParams React komponentēs).
  • Jūsu Next.js lietotne to nolasa, izmantojot cms-renderer; Stripe tiek pievienots kā parasti API maršruti.

Viens noteikums, kas nosaka izveidi: CEL sasaista tikai string/number laukus. Tādēļ skalārais interfeisa saturs (navigācijas zīmols, kājene, virsraksti) tiek sasaistīts ar CEL, savukārt viss bagātīgais saturs vai kolekcijas (produktu režģis, attēlu galerija, bagātināts teksts) tiek iegūts React komponentē, izmantojot maršruta parametru. Un Stripe ir patiesais cenu avots — CMS price ir paredzēts tikai attēlošanai; maksa servera pusē vienmēr tiek atrisināta, izmantojot Stripe Price ID.

1. daļa — Iestatīšana

Beigu stāvoklis: neliels publicēts katalogs, lietotne, kas pieslēgta tā lasīšanai, instalēts Stripe un ieviests dizains — vēl nekas netiek attēlots.

1. Reģistrējieties un izveidojiet vietni

Reģistrējieties Profound (WorkOS autentifikācija). Izveidojiet vietni ar nosaukumu store, pēc tam nokopējiet tās vietnes ID (UUID administrēšanas URL) un read-tier API atslēgu (Deployments → Create API key). Lietotne tikai lasa datus; kataloga aizpildīšana vēlāk notiks ar MCP, kas autentificējas atsevišķi.

2. Izveidojiet lietotnes skeletu, savienojiet to un pievienojiet Stripe

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

Skelets ir Next.js App Router projekts, kas jau sagatavots darbam ar Profound (cms-renderer SDK, universāls maršruts, generate-schemas skripts, <Refresher>). Tam nav stila. bun add stripe pievieno servera SDK — vienīgo maksājumu atkarību, kas nepieciešama mitinātajai Checkout.

Pievienojiet savas vērtības failam .env.local:

# CMS
PROFOUND_API_KEY=<your read key>
NEXT_PUBLIC_PROFOUND_WEBSITE_ID=<your website id>
NEXT_PUBLIC_CMS_API_URL=https://cms.dev.tryprofound.com
NEXT_PUBLIC_BUNNY_CDN_URL=https://cms-profound.b-cdn.net   # nodrošina CMS mitinātos attēlus

# Stripe
STRIPE_SECRET_KEY=sk_test_...            # šeit testa atslēga; tiešajā režīmā nomainiet pret tiešo atslēgu
STRIPE_WEBHOOK_SECRET=whsec_...          # tiks aizpildīts 2. daļas 4. darbībā
NEXT_PUBLIC_SITE_URL=http://localhost:3000

Iegūstiet STRIPE_SECRET_KEY Stripe → Developers → API keys. Izmantojam testa atslēgu (sk_test_…), lai izveides laikā nekad netiktu pārvietota īsta nauda; kad būsiet gatavi pieņemt īstus maksājumus, nomainiet to pret tiešo atslēgu. Palaidiet bun dev un atveriet localhost:3000 — tiks attēlots sākuma projekts.

Mitinātā Checkout novirza pārlūkprogrammu uz Stripe URL, tāpēc Stripe nepieciešama tikai servera slepenā atslēga — nav vajadzīga publiskojamā atslēga vai klienta Stripe SDK.

3. Definējiet komponentus category, product_image un item

Izveidojiet trīs pielāgotus komponentus (Components → Create new component) — tie ir datu avots, tāpēc tiem nav UI Element taga. Iestatiet katru kā Active.

CMS nav “attēlu masīva” lauka, tādēļ galerija ir atsauču masīvs uz nelielu product_image komponentu. Izveidojiet category un product_image (un iestatiet tos kā Active) pirms item — atsauces lauks var mērķēt tikai uz aktīviem komponentiem.

  • 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 (atsauču masīvs → product_image), price (Number, centos — tikai attēlošanai), currency (Select, usd), stripePriceId (Text), category (Reference → category), active (Boolean)

Atstājiet visus laukus neobligātus. Administrēšanas panelis lauku nosaukumus pārveido uz mazajiem burtiem ar pasvītrojumiem (“Stripe Price Id” → stripe_price_id) — uz to balstās jūsu kods, tāpēc nākamajā darbībā pārbaudiet faktiskos nosaukumus, izmantojot generate-schemas. Maršrutējamo identifikatoru saucam code (nevis slug): tas ir Route Slug un arī atslēga ērtai documents.getByCode meklēšanai vēlāk.

Komponents item — code kā Route Slug, images kā atsauces uz product_image, kā arī stripePriceId un atsauce uz category.

4. Ielādējiet komponentus lokālajos tipos

bun run generate-schemas

Tiek ierakstītas Zod shēmas un tipi failā generated/cms-schemas.ts (categorySchema/Category, itemSchema/Item). Tas vienlaikus pārbauda savienojumu — nepareizi akreditācijas dati šeit radīs kļūdu.

5. Aizpildiet katalogu, izmantojot Profound MCP

Vienreiz instalējiet un autentificējiet MCP:

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

Palaidiet mcp__Profound__authenticate, pabeidziet WorkOS plūsmu un pēc tam dodiet Claude šādu uzdevumu:

Izveido nelielu e-komercijas katalogu veikalam ar nosaukumu Edisona izgudrojumi — trīs kategorijas un šos produktus, katram pievienojot īsu laikmetam atbilstošu description, price centos, currency: "usd" un active: true:

  • Apgaismojums un enerģija (code: lighting): kvēlspuldze (incandescent-lightbulb, $24), elektriskais dinamo (electric-dynamo, $890), elektriskā pildspalva (electric-pen, $49)
  • Skaņas ierakstīšana (code: sound): folijas fonogrāfs (tinfoil-phonograph, $249), oglekļa mikrofons (carbon-microphone, $59), diktofons (dictaphone, $179)
  • Kustīgie attēli (code: motion): kinetoskops (kinetoscope, $399), kinetogrāfa kamera (kinetograph, $549)

Katrai kategorijai nepieciešams name un šis kods ar mazajiem burtiem; katram vienumam nepieciešams name, šis kods ar mazajiem burtiem, description, price centos, currency un active. Saglabā to failā data/catalog.json un validē pret mūsu category un item komponentiem. Pēc tam izmanto Profound MCP, lai katru izveidotu kā publicētu dokumentu: vispirms izveido kategorijas, saglabā to ID, pēc tam izveido vienumus ar category kā atsauci — { "_type": "reference", "_ref": "<category-id>", "_schema": "category" }. Pagaidām atstāj stripePriceId tukšu. Izveido vienumus paralēli.

Claude izveido data/catalog.json, validē to un paralēli izsauc create_document (status: "published"). Vispirms izveidojiet kategorijas, lai atsauces norādītu uz jau esošiem ID.

Trīs aizpildītās kategorijas — publicētas un tiešsaistē pieejamas.

Visi astoņi aizpildītie produkti, katrs saistīts ar kategoriju.

6. Izveidojiet Stripe cenas un savienojiet dažus produktus

Katalogs ir CMS; tagad piešķiriet dažiem produktiem īstu Stripe cenu — tirgotāja darbs, kas paveicams divos administrēšanas paneļos, bez koda:

  1. Stripe Dashboard → Products → + Add product, iestatiet vienreizēju cenu un nokopējiet Price ID (price_…).
  2. Dariet to aptuveni 3 galvenajiem produktiem (piemēram, spuldzei, fonogrāfam un kinetoskopam).
  3. Profound administrēšanas panelis → item → Documents → ielīmējiet katru Price ID laukā stripePriceId un saglabājiet.

CMS glabā katalogu; Stripe glabā oficiālo cenu; saite ir viena virkne, ko tirgotājs ielīmē. (Vēlaties automatizēt? Oficiālais Stripe MCP var izveidot Products/Prices jūsu vietā — ielīmējiet atgrieztos ID tādā pašā veidā.)

7. Pievienojiet dizaina sistēmu un savienojiet to ar MI

Skeletam nav stila. Projekta saknē ievietojiet DESIGN.md (Tailwind v4 @theme bloku un tokenus) — savu failu vai lejupielādējiet to no refero.design. Pēc tam dodiet Claude uzdevumu, kas attiecas tikai uz stilu:

Izlasi tikko pievienoto dizaina failu. Ja nepieciešams, iestati Tailwind, pēc tam pieslēdz tēmu un fontus, lai stils darbotos. Fontiem izmanto next/font — neielādē tos no Google izpildes laikā. Tikai stils — pagaidām neveido lapas vai komponentus.

Pārbaudiet, vai src/app/globals.css satur @import "tailwindcss"; un @theme bloku, kā arī vai localhost:3000 parāda tokenus. Saglabājiet uzdevumu konkrētu (atvērts uzdevums var likt aģentam izveidot visu sākumlapu) un ielādējiet fontus ar next/font, nekad neizmantojot Google importu izpildes laikā.

8. Pievienojiet produktu attēlus (neobligāti)

Neobligāti — funkcionējošu Checkout var izveidot arī bez attēliem. Lai tos pievienotu, izveidojiet vienu product_image dokumentu katram attēlam (augšupielādējiet to laukā image), pēc tam pievienojiet atsauces uz tiem produkta images masīvā. Izmantojiet savas produktu fotogrāfijas vai izveidojiet vienotu kopumu ar attēlu modeli (lieciet Claude iegūt zīmolam atbilstošus uzvedņu tekstus no DESIGN.md un izmantot vienu Midjourney --sref, lai visi attēli būtu saskaņoti).

Atsevišķajam cms-renderer nav attēlu URL palīgfunkcijas, tādēļ ievietojiet buildAssetUrl kodu failā src/lib/image.ts (aptuveni 40 rindiņas) — tas pievieno NEXT_PUBLIC_BUNNY_CDN_URL prefiksu un paplašinājumu. Komponenti 3. darbībā to izmantos.

2. daļa — Izveide

Izveidojiet renderēšanas slāni un Checkout, noslēdzot ar īstu pirkumu testa režīmā.

1. Definējiet piecus UI elementu komponentus

Pieci komponenti, katrs Active un atzīmēts ar UI Element (Settings → Tags), bez Route Slug:

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

Tags UI Element nodrošina, ka komponents parādās Page Builder sarakstā Add UI Element — ar Active vien nepietiek. Katrs lauks ir skalārs (tāds, ko var sasaistīt ar CEL); faktiskais kataloga saturs šeit nav lauks — ProductGrid/ProductDetail to iegūst pēc maršruta parametra (3. darbība).

2. Atjaunojiet tipus

bun run generate-schemas

3. Ģenerējiet kataloga lasītāju, komponentus un bezgalvas grozu

Viens uzdevums izveido lasīšanas palīgu, piecus komponentus, grozu un reģistru:

Izveido mūsu veikalu mapē src/, izmantojot Profound cms-renderer SDK.

src/lib/catalog.ts — servera puses CMS lasītājs. Izveido klientu ar getCmsClient({ cmsUrl: process.env.NEXT_PUBLIC_CMS_API_URL!, apiKey: process.env.PROFOUND_API_KEY, websiteId: process.env.NEXT_PUBLIC_PROFOUND_WEBSITE_ID! }) no cms-renderer/lib/cms-api. Eksportē getItemByCode(code) → cms.documents.getByCode.query({ websiteId, schemaName: "item", code }), atgriežot res.document.published_content. Eksportē listItems(categoryCode?) → cms.documents.list.query({ websiteId, schemaName: "item", status: "published", limit: 100 }), pārveido res.documents par .published_content, filtrē active !== false un, ja norādīts categoryCode, patur vienumus, kuru category._ref ir vienāds ar kategorijas document.id. Eksportē resolveImages(refs), kas atrisina katru item.images atsauci, izmantojot cms.documents.get.query({ websiteId, id: ref._ref }), un pārvērš tās attēla lauku URL, izmantojot ievietoto buildAssetUrl (1. daļas 8. darbība).

src/components/ — pieci UI elementu komponenti, kas reģistrēti universālā maršruta reģistrā pēc komponenta nosaukuma, snake_case formā, lai atbilstu administrēšanas panelim: { nav, product_grid, product_detail, cart_summary, footer }. Nav un Footer nolasa savu skalāro lauku no content rekvizīta (tipizēts ar BlockComponentProps<T> no cms-renderer/lib/types). ProductGrid un ProductDetail ir asinhroni servera komponenti, kas nolasa routeParams un iegūst datus no catalog.ts: routeParams.<param> ir { value, … } — nolasiet .value, tāpēc ProductGrid izsauc listItems(routeParams.category_code?.value) (kartītes ved uz /products/{code}), bet ProductDetail izsauc getItemByCode(routeParams.item_code?.value) (galerija ar resolveImages, bagātināta apraksta teksta attēlošana, cena, pievienošana grozam). CartSummary attēlo grozu no useCart ar pogu Pay. Glabājiet formatPrice tīrā src/lib/format.ts, lai klienta komponentiem nebūtu jāimportē tikai serverim paredzētais catalog.ts.

src/components/AddToCartButton.tsx — "use client" poga, kas pieņem { code, name, priceLabel } un izsauc useCart().addItem({ code, name, priceLabel, quantity: 1 }). Izmantojiet to ProductDetail komponentē.

src/lib/useCart.ts — bezgalvas grozs: rindu vienumi { code, name, priceLabel, quantity } stāvoklī, kas saglabāts localStorage, ar addItem/removeItem/updateQty/subtotal un checkout(), kas nosūta POST pieprasījumu { lines: [{ code, quantity }] } (tikai kodi un daudzumi — nekad cenas) uz /api/stripe/checkout, pēc tam novirza uz atgriezto url.

Veidojiet visu, izmantojot mūsu dizaina sistēmu un mūsu pašu komponentus — nekopējiet avota vietnes izkārtojumu.

Pēc izpildes jāzina trīs lietas:

  • Skalārais interfeisa saturs tiek nodots content ({ content }: BlockComponentProps<T>) — izvelciet laukus kā augstākā līmeņa rekvizītus, pretējā gadījumā bloks būs tukšs. Kataloga dati nāk no routeParams un catalog.ts vaicājuma, jo CEL nevar sasaistīt sarakstus vai galerijas. Grozs glabā produktu kodus, nekad cenas.
  • routeParams.<param> ir { value, schemaName, document } — nolasiet .value. Vaicājumu rezultāts ir published_content, nevis .content. Reģistra atslēgas ir snake_case, lai atbilstu administrēšanas panelim.
  • Atjauniniet @types/react/@types/react-dom uz v19 — skeletā tiek izmantota v18, kas rada problēmas asinhroniem servera komponentu blokiem ar React 19.

4. Uzrakstiet Stripe servera kodu (pamatu)

Trīs īsi servera faili — vienīgais maksājumu kods lietotnē. Tie atkārtoti izmanto getItemByCode, tāpēc maksa tiek atrisināta servera pusē.

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 — iegūstiet katru vienumu no CMS un iekasējiet Stripe cenu:

import { NextResponse } from "next/server";
import { stripe } from "@/lib/stripe";
import { getItemByCode } from "@/lib/catalog"; // servera pusē, read-tier atslēga

export async function POST(req: Request) {
  const { lines } = await req.json();                // [{ code, quantity }] — no klienta cenas netiek pieņemtas
  const line_items = await Promise.all(
    lines.map(async ({ code, quantity }: { code: string; quantity: number }) => {
      const item = await getItemByCode(code);          // serveris iegūst datus no CMS
      return { price: item!.stripe_price_id, quantity }; // cena no CMS, nekad no klienta
    })
  );
  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 });     // klients tiek novirzīts šeit
}

src/app/api/stripe/webhook/route.ts — uzticams pasūtījuma izpildes signāls:

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

export async function POST(req: Request) {
  const body = await req.text();                      // NEAPSTRĀDĀTS ķermenis — nepieciešams paraksta pārbaudei
  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("Bad signature", { status: 400 });
  }
  if (event.type === "checkout.session.completed") {
    // izpilde: reģistrēt pasūtījumu / nosūtīt kvīti.
  }
  return new Response(null, { status: 200 });
}

Nepieciešams skeleta labojums: skeleta src/proxy.ts pārsūta katru /api/* pieprasījumu uz CMS, tāpēc Stripe maršruti nekad netiek izpildīti. Vispirms ļaujiet tiem iziet cauri:

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();                       // apstrādāt lokāli
  }
  return cmsProxy(request as unknown as Parameters<typeof cmsProxy>[0]);
};
// atstājiet skeleta `export const config = { matcher: [...] }` nemainītu

Pārbaude: curl -X POST localhost:3000/api/stripe/webhook -d x atgriež Bad signature.

Palaidiet Stripe CLI lokālajiem tīmekļa āķiem:

stripe login
stripe listen --forward-to localhost:3000/api/stripe/webhook
# nokopējiet whsec_... uz STRIPE_WEBHOOK_SECRET un restartējiet bun dev

whsec_… tiek ģenerēts katrai sesijai. Drošību nodrošina divi noteikumi: Checkout atkārtoti iegūst cenu no CMS pēc code (izmainīts grozs cenu nevar mainīt), bet tīmekļa āķis pārbauda parakstu pret neapstrādāto ķermeni.

5. Izveidojiet maršrutus

Admin → Pages → Create page — trīs reizes. Katru parametru sasaistiet ar tā komponentu (slug lauks code):

  1. /products/{item_code} → item
  2. /categories/{category_code} → category
  3. /cart — statiska lapa (ievadiet burtisku /cart, nevis /{cart})

6. Pievienojiet UI elementus, sasaistiet CEL un publicējiet

Katram maršrutam: Page Builder → Add UI Element → Custom → pievienojiet komponentus secībā, aizpildiet skalāros laukus (statiska vērtība vai CEL) un Publicējiet.

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

Iestatiet nav.brand un footer.text kā statiskas virknes; virsrakstiem izmantojiet statiskas etiķetes.

Page Builder kategorijas maršrutā — atlasīts product_grid elements, tā virsraksts sasaistīts ar CEL.

Page Builder produkta maršrutā — product_detail elements sasaistīts ar produktu.

Parametriskā Page Builder problēma: abos parametriskajos maršrutos UI elementu pievienošana netiek saglabāta (bloki kļūst par bāreņiem un lapa tiek attēlota tukša). Kamēr tas nav novērsts, sasaistiet šo lapu block_ids tieši, izmantojot Profound MCP update_page, pēc tam publicējiet. (Statiskā /cart lapa tiek piesaistīta normāli.) Tā paša iemesla dēļ ProductGrid virsrakstu iegūst no kategorijas, ko tas ielādē, nevis izmantojot CEL.

7. Attēlojiet un veiciet pirkumu

  • /categories/lighting → režģis. Noklikšķiniet uz produkta → detalizēta informācija un pievienošana grozam. /cart → Pay.
  • Poga Pay novirza uz Stripe mitināto Checkout. Izmantojiet testa karti 4242 4242 4242 4242, jebkuru nākotnes derīguma termiņu un CVC. Jūs atgriezīsieties uz /cart?status=success, bet stripe listen parādīs checkout.session.completed.

Attēlota produkta lapa — galerija, cena un poga Pievienot grozam.

Groza lapa — rindu vienumi un viena poga Maksāt ar Stripe.

Iegādāties var tikai produktus, kuriem piešķirta cena — iegādājieties kādu no aptuveni 3 produktiem, kuriem 6. darbībā piešķīrāt cenu.

Neobligāti — internacionalizācija. Tulkot katru komponentu (visas 35 valodas vienlaikus), pievienot segmentu /{language}/…, kas sasaistīts ar iebūvēto language sistēmas komponentu, un CEL sasaistītos laukus pārslēgt uz documents.translated. Skatiet lidostas direktorija pamācības 2. daļas 7. darbību.

3. daļa — Produkcija

1. Publicējiet: vispirms GitHub, pēc tam Vercel

git init && git add -A && git commit -m "Stripe storefront"
gh repo create store --private --source=. --push   # --public arī ir pieļaujams

Izveides komanda: generated/cms-schemas.ts ir iekļauts gitignore, tāpēc piespiediet tā ģenerēšanu izveides laikā — pievienojiet vercel.json:

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

Vercel: Add New → Project, importējiet store un pievienojiet vides mainīgos — PROFOUND_API_KEY, NEXT_PUBLIC_PROFOUND_WEBSITE_ID, NEXT_PUBLIC_CMS_API_URL, NEXT_PUBLIC_BUNNY_CDN_URL, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET (izvietotā galapunkta vērtība, skatiet tālāk) un NEXT_PUBLIC_SITE_URL (jūsu produkcijas URL). Izvietojiet projektu.

Pēc tam pieslēdziet izvietoto tīmekļa āķi (lokālā stripe listen slepenā vērtība darbojās tikai lokāli): Stripe → Developers → Webhooks → + Add endpoint → https://<prod>/api/stripe/webhook, notikums checkout.session.completed. Nokopējiet tā whsec_… uz Vercel un izvietojiet vēlreiz.

Trūkstoši vides mainīgie nozīmē “lokāli darbojas, produkcijā tukšs” — tā ir visbiežākā izvietošanas kļūda. Šeit izvietojam ar testa atslēgām; kad būsiet gatavi pieņemt īstus maksājumus, nomainiet STRIPE_SECRET_KEY un tīmekļa āķa slepeno vērtību pret savām tiešā režīma vērtībām.

2. Tiešais priekšskatījums un rediģēšana lapā

Abi līdzekļi tiek piegādāti kopā ar skeletu.

  • Tiešais priekšskatījums: <Refresher> atjaunina priekšskatāmo lapu, kad redaktors saglabā izmaiņas administrēšanas panelī — nav nepieciešams atkārtots izvietojums. (Tas ir redaktora priekšskatījums; apmeklētāji parastās atkārtotas validācijas laikā redz publicēto saturu.)
  • Rediģēšana lapā: jebkuram URL pievienojiet ?edit_mode=true, lai redzētu rediģēšanas pārklājumus. Publiskie apmeklētāji redz tīru lapu.

Pievienojiet skeletā izlaisto priekšskatījuma maršrutu. Administrēšanas panelis ielādē priekšskatījuma iframe adresē /cms-preview_<path>; bez šī maršruta katrs priekšskatījums atgriezīs 404. Pievienojiet:

// src/app/cms-preview_/[...slug]/page.tsx
import { ParametricRoutePreviewPage } from "cms-renderer/lib/renderer";
import { registry } from "../../registry";   // izdaliet reģistru kopīgā modulī
export default async function Page({ params, searchParams }) {
  const { slug } = await params;
  const PreviewPage = ParametricRoutePreviewPage as any; // asinhrons RSC; React 19 tipi
  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} />;
}

Pievienojiet arī src/app/cms-preview_/page.tsx (tas pats, slug: []) segmenta saknei.

Izveide pabeigta

Uz saturu balstīts Stripe veikals: CMS katalogs, saraksta un detalizētās lapas no viena maršrutu kopuma un funkcionējoša mitinātā Checkout. MI aizpildīja katalogu, savienoja dizainu un uzrakstīja kataloga lasītāju, komponentus un bezgalvas grozu; jūs izveidojāt komponentus, Stripe cenu saites, trīs maršrutus, CEL interfeisa saturu un trīs īsos Stripe failus. CEL sasaista interfeisa saturu; komponenti iegūst katalogu. Stripe palika kompakts — viens sessions.create izsaukums un viens parakstīts tīmekļa āķis, pircējam maksājot paša Stripe lapā.

Continue Reading
Previous‹Deployments