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.
/{language}/{airport_code}.cms-renderer.curl -fsSL https://bun.sh/install | bashgh) autentificat și un cont Vercel legat de GitHub.language) sunt incluse implicit.cms-renderer cu o cheie API de tip read.Rezultat final: ~50 de aeroporturi în CMS, aplicația conectată pentru citire și sistemul de design la locul lui.
Î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ă.
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ă.
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.
bun run generate-schemas
Aceasta scrie airportSchema (Zod) și Airport (tip) în generated/cms-schemas.ts și confirmă că credențialele funcționează.
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.
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/fontpentru 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.
Construiește stratul de randare: elementele UI, componentele React, ruta, binding-urile CEL și traducerea.
Î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 → brandheadline → title, subtitlebody → code, city, country, latitude (Number), longitude (Number)footer → textbody.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.
bun run generate-schemas
Cere-i lui Claude:
Construiește patru componente React — nav, headline, body, footer — în
components/. Fiecare primește o singură propcontenttipată caBlockComponentProps<T>dincms-renderer/lib/types, undeTeste tipul generat al elementului, și își citește câmpurile dincontent. Î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 subtitlucode · 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.
Î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ă.
Adăugarea unui element UI în pagină din fila Custom.
Cele patru elemente UI adăugate în binding-ul JFK din Page Builder.
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.
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âmp | Valoare CEL |
|---|---|
headline.title | documents.get("airport", meta.params.airport_code).name |
headline.subtitle | documents.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.country | documents.get("airport", meta.params.airport_code).<field> |
body.latitude / body.longitude | documents.get("airport", meta.params.airport_code).latitude (și .longitude) |
nav.brand, footer.text | șiruri statice |
Publish pagina (dreapta sus).
Deschide localhost:3000/JFK, apoi /SFO, /LAX — același șablon, aeroporturi diferite.
Pagina finalizată randând datele lui JFK, în engleză.
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.
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ă.
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âmp | CEL tradus |
|---|---|
headline.title | documents.translated("airport", meta.params.airport_code, meta.params.language).name |
headline.subtitle | documents.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.country | documents.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.
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ă.
Ambele vin cu scheletul.
<Refresher> din layout.tsx actualizează pagina pe care o previzualizezi atunci când editezi și salvezi în admin — fără redeploy.?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.
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ă.