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 Integrationssetări-chei APISettings UsageSettings Websites
All Systems Operational
Powered Byprofound-logo
Theme

Build & Ship an Airport Directory

Un ghid practic: construiește un director de aeroporturi internaționalizat în Profound CMS — o singură rută parametrică ce redă o pagină pentru fiecare aeroport, în 35 de limbi.

Construiește un director de aeroporturi real, internaționalizat, în Profound CMS: un singur tipar de URL care redă o pagină pentru fiecare aeroport, în 35 de limbi. Tu scrii codul Next.js și construiești structura CMS manual; Claude Code (prin Profound MCP) se ocupă de trei sarcini — generarea datelor despre aeroporturi, conectarea unui sistem de design și generarea celor patru componente React. Trei părți: Configurare, Construire, Producție.

Urmărește video-ul de prezentare complet.

Ce vei construi

  • ~50 de înregistrări de aeroport, fiecare pe propriul URL.
  • O rută parametrică /{language}/{airport_code}.
  • Patru elemente UI — nav, headline, body, footer — randate de cms-renderer.
  • Date CMS live prin binding-uri CEL.
  • Toate cele 35 de limbi, traduse dintr-un singur clic.
  • Implementare pe Vercel cu previzualizare live și editare in-place.

Prerechizite

  • Bun ≥ 1.3 — curl -fsSL https://bun.sh/install | bash
  • Claude Code cu Profound MCP conectat (Partea 1).
  • Un cont Profound CMS.
  • Pentru Partea 3: GitHub CLI (gh) autentificat și un cont Vercel legat de GitHub.

Cum se leagă toate

  • Componentele definesc structura conținutului. Un câmp Route Slug face o componentă rutabilă; un tag UI Element o face plasabilă pe o pagină; componentele System (precum language) sunt incluse implicit.
  • Variantele sunt conținutul (JFK, SFO, LAX...).
  • Elementele UI sunt secțiuni de pagină, populate cu CEL — motorul de scripting in-template al Profound, evaluat la randare.
  • O rută parametrică map-ează un URL la o variantă plus un set de elemente UI.
  • Aplicația ta Next.js redă totul prin SDK-ul cms-renderer cu o cheie API de tip read.

Partea 1 — Configurare

Rezultat final: ~50 de aeroporturi în CMS, aplicația conectată pentru citire și sistemul de design la locul lui.

1. Creează site-ul

Înscrie-te în Profound (autentificare WorkOS) și creează un site numit airports. Copiază două lucruri: ID-ul site-ului (UUID-ul din URL-ul de admin) și o cheie API de tip read din Deployments → Create API key. Aplicația doar citește, deci o cheie read este suficientă.

2. Generează scheletul și conectează aplicația

bunx create-profound-next airports
cd airports

Adaugă credențialele în .env.local:

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

Rulează bun dev și deschide localhost:3000 pentru a confirma că se conectează.

3. Creează componenta airport

În panoul de administrare, mergi la Components → Create new component și denumește-o airport. Adaugă șase câmpuri: code, name, city, country (Text) și latitude, longitude (Number). Marchează code ca Route Slug și setează statusul la Active. Lasă toate câmpurile opționale; nu adăuga tag de UI Element.

Componenta airport — șase câmpuri, cu code setat drept Route Slug.

4. Importă componenta în tipuri

bun run generate-schemas

Aceasta scrie airportSchema (Zod) și Airport (tip) în generated/cms-schemas.ts și confirmă că credențialele funcționează.

5. Populează datele prin MCP

Conectează MCP-ul și autentifică-te:

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

Serverul se autentifică prin OAuth (WorkOS). În Claude Code, rulează /mcp, alege Profound și finalizează autentificarea în browser — Claude Code te va atenționa automat prima dată când este apelat un instrument Profound. După ce /mcp afișează Profound ca connected, cere-i lui Claude:

Generează cincizeci de aeroporturi reale — coduri IATA corecte, nume, orașe, țări și coordonate. Salvează-le ca JSON într-un folder data, validează-le cu componenta noastră airport, apoi creează fiecare document publicat prin Profound MCP, în paralel.

Deschide airport → Variants pentru a confirma că există ~50 de aeroporturi publicate. Aplicația citește cu cheia API; MCP-ul scrie cu propria sesiune WorkOS.

Aproximativ 50 de aeroporturi, încărcate ca variante publicate.

6. Adaugă un sistem de design

Scheletul vine fără stilizare. Pune un DESIGN.md (un bloc @theme Tailwind v4 plus token-uri) la rădăcina proiectului — fie al tău, fie descarcă unul de la refero.design. Apoi cere-i lui Claude:

Citește DESIGN.md. Configurează Tailwind v4 și integrează tema și fonturile. Folosește next/font pentru fonturi, nu un import Google la runtime. Doar stilizare — fără pagini sau componente deocamdată.

Confirmă că src/app/globals.css conține @import "tailwindcss"; plus blocul @theme, și că localhost:3000 afișează token-urile.

Partea 2 — Construire

Construiește stratul de randare: elementele UI, componentele React, ruta, binding-urile CEL și traducerea.

1. Definește cele patru componente UI element

În admin, Create new component de patru ori (fără Route Slug). Pentru fiecare, adaugă câmpurile ca Text dacă nu se specifică altfel, setează statusul la Active și adaugă tag-ul UI Element în Settings → Tags:

  • nav → brand
  • headline → title, subtitle
  • body → code, city, country, latitude (Number), longitude (Number)
  • footer → text

body.latitude și body.longitude trebuie să fie Number pentru a se potrivi cu componenta airport.

Fiecare element UI este propria componentă — aici body, setată Active cu tag-ul UI Element.

Toate cele patru elemente UI alături de componenta airport.

2. Regenerează tipurile

bun run generate-schemas

3. Generează componentele React și înregistrează-le

Cere-i lui Claude:

Construiește patru componente React — nav, headline, body, footer — în components/. Fiecare primește o singură prop content tipată ca BlockComponentProps<T> din cms-renderer/lib/types, unde T este tipul generat al elementului, și își citește câmpurile din content. Înregistrează toate cele patru în registrul din ruta catch-all după numele componentei. Stilizează-le cu sistemul nostru de design, dar ca și cum ar fi propriile noastre componente — nu copia layout-ul site-ului sursă. Nav: brand în stânga. Headline: numele aeroportului cu un subtitlu code · city, country. Body: panou de detalii cu cod, oraș, țară și coordonate. Footer: o singură linie statică. Doar layout și stilizare.

Claude creează cele patru componente și completează registrul în src/app/[...slug]/page.tsx:

const registry = { nav: Nav, headline: Headline, body: Body, footer: Footer };

Două reguli: fiecare componentă își citește câmpurile din content (nu ca props separate), iar cheile din registru trebuie să corespundă exact cu numele componentelor din CMS — o nepotrivire va reda un gol.

4. Creează ruta parametrică

În admin, mergi la Pages → Create page și setează tiparul /{airport_code}. În Dynamic Segment Mappings, map-ează airport_code → componenta airport, câmpul slug code. Salvează — ajungi în Page Builder. Verifică faptul că /JFK se rezolvă.

5. Adaugă elementele UI, leagă CEL și publică

Adăugarea unui element UI în pagină din fila Custom.

Cele patru elemente UI adăugate în binding-ul JFK din Page Builder.

  1. Alege binding-ul JFK → Add UI Element → fila Custom → adaugă nav, headline, body, footer în ordine. Profound propagă setul către fiecare binding de aeroport.

  2. Completează fiecare câmp. Valorile statice (nav brand, footer text): tastează-le direct. Valorile dinamice: comută pe dynamic și scrie CEL. Referința partajată este documents.get("airport", meta.params.airport_code).

    CâmpValoare CEL
    headline.titledocuments.get("airport", meta.params.airport_code).name
    headline.subtitledocuments.get("airport", meta.params.airport_code).code + " · " + documents.get("airport", meta.params.airport_code).city + ", " + documents.get("airport", meta.params.airport_code).country
    body.code / body.city / body.countrydocuments.get("airport", meta.params.airport_code).<field>
    body.latitude / body.longitudedocuments.get("airport", meta.params.airport_code).latitude (și .longitude)
    nav.brand, footer.textșiruri statice
  3. Publish pagina (dreapta sus).

6. Verifică în engleză

Deschide localhost:3000/JFK, apoi /SFO, /LAX — același șablon, aeroporturi diferite.

Pagina finalizată randând datele lui JFK, în engleză.

7. Internaționalizează

  1. Tradu componentele mai întâi. În admin, deschide fiecare componentă (orice componentă — nu trebuie să fie un element UI) și apasă Translate → Submit. Profound îi traduce conținutul în toate cele 35 de limbi deodată, inclusiv valorile statice. Fă asta înainte să editezi ruta sau să atingi orice CEL.

    Translate → Submit trimite o componentă în toate cele 35 de limbi simultan.

  2. Adaugă dimensiunea limbii. În Pages, schimbă tiparul în /{language}/{airport_code}. Adaugă un Dynamic Segment Mapping pentru language → componenta language din System, câmpul slug code. Salvează și verifică faptul că /en/JFK se rezolvă.

    Adăugarea segmentului {language} la rută.

  3. Direcționează fiecare câmp traducibil către fetch-ul tradus. Internaționalizarea paginii înseamnă să comuți fiecare câmp dependent de limbă — nu doar headline-ul — de la documents.get(...) la documents.translated("airport", meta.params.airport_code, meta.params.language):

    CâmpCEL tradus
    headline.titledocuments.translated("airport", meta.params.airport_code, meta.params.language).name
    headline.subtitledocuments.get("airport", meta.params.airport_code).code + " · " + documents.translated("airport", meta.params.airport_code, meta.params.language).city + ", " + documents.translated("airport", meta.params.airport_code, meta.params.language).country
    body.city / body.countrydocuments.translated("airport", meta.params.airport_code, meta.params.language).city (și .country)

    Lasă codul IATA code și coordonatele pe documents.get — sunt identice în fiecare limbă. nav.brand și footer.text sunt deja acoperite de traducerea componentei din pasul 1.

După ce finalizezi toate cele trei etape, /fr/SFO, /de/SFO etc. se încarcă complet traduse.

Partea 3 — Producție

1. Deploy: GitHub, apoi Vercel

Fă push pe GitHub:

git init
git add -A
git commit -m "Airport directory"
gh repo create airports --public --source=. --push

Importă în Vercel: Add New → Project → importă repo-ul airports. Adaugă variabilele de mediu — PROFOUND_API_KEY, NEXT_PUBLIC_PROFOUND_WEBSITE_ID, NEXT_PUBLIC_CMS_API_URL și opțional NEXT_PUBLIC_BUNNY_CDN_URL — apoi Deploy. Vizitează /en/JFK și /fr/SFO. Fiecare viitor git push redeploiază.

2. Previzualizare live și editare in-place

Ambele vin cu scheletul.

  • Previzualizare live: <Refresher> din layout.tsx actualizează pagina pe care o previzualizezi atunci când editezi și salvezi în admin — fără redeploy.
  • Editare in-place: adaugă ?edit_mode=true la orice URL (de ex. …/en/JFK?edit_mode=true) pentru overlay-uri de editare. Vizitatorii publici văd în continuare pagina curată.

?edit_mode=true adaugă overlay-ul editorului pe pagina live.

Asta este construcția

Cincizeci de aeroporturi, 35 de limbi, live — descrise o singură dată și alimentate de date: o singură rută, patru componente React și câteva binding-uri CEL. CMS-ul găzduiește conținutul, codul tău îl randează, iar CEL le conectează.

Continue Reading
NextDeployments›