profound-logoProfound CMS
⌘K
Admin
Theme
DocsGuidaBlogPhilosophy
DocsGuidaBlogPhilosophy

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 an Airport Directory

Un tutorial pratico: costruisci una directory di aeroporti internazionalizzata su Profound CMS — un'unica route parametrica che renderizza una pagina per ogni aeroporto, in 35 lingue.

Crea una vera directory di aeroporti internazionalizzata su Profound CMS: un solo pattern di URL che renderizza una pagina per ogni aeroporto, in 35 lingue. Tu scrivi il codice Next.js e costruisci a mano la struttura del CMS; Claude Code (tramite il Profound MCP) si occupa di tre attività — generare i dati degli aeroporti, collegare un design system e generare i quattro componenti React. Tre parti: Setup, Build, Production.

Guarda il video tutorial completo.

Cosa costruirai

  • ~50 record di aeroporti, ciascuno con il proprio URL.
  • Una route parametrica /{language}/{airport_code}.
  • Quattro elementi UI — nav, headline, body, footer — renderizzati da cms-renderer.
  • Dati del CMS in tempo reale tramite binding CEL.
  • Tutte e 35 le lingue, tradotte con un clic.
  • Deployment su Vercel con live preview e modifica in linea.

Prerequisiti

  • Bun ≥ 1.3 — curl -fsSL https://bun.sh/install | bash
  • Claude Code connesso al Profound MCP (Parte 1).
  • Un account Profound CMS.
  • Per la Parte 3: GitHub CLI (gh) con accesso effettuato e un account Vercel collegato a GitHub.

Come si integra il tutto

  • I componenti definiscono la forma del contenuto. Un campo Route Slug rende un componente raggiungibile tramite route; un tag UI Element lo rende posizionabile su una pagina; i componenti System (come language) sono preinstallati.
  • Le varianti sono i contenuti (JFK, SFO, LAX…).
  • Gli elementi UI sono sezioni di pagina, riempite con CEL — lo scripting in-template di Profound, valutato in fase di render.
  • Una route parametrica collega un URL a una variante più un set di elementi UI.
  • La tua app Next.js renderizza tutto tramite l'SDK cms-renderer con una chiave API di livello lettura.

Parte 1 — Setup

Stato finale: ~50 aeroporti nel CMS, l'app collegata per leggerli e il design system configurato.

1. Crea il sito web

Registrati su Profound (autenticazione WorkOS) e crea un sito chiamato airports. Copia due elementi: l'ID del sito web (la UUID nell'URL dell'admin) e una chiave API di livello lettura da Deployments → Create API key. L'app esegue solo lettura, quindi è sufficiente una chiave di read.

2. Genera lo scaffold e collega l'app

bunx create-profound-next airports
cd airports

Aggiungi le tue credenziali a .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

Esegui bun dev e apri localhost:3000 per verificare la connessione.

3. Crea il componente airport

Nell'admin vai su Components → Create new component e chiamalo airport. Aggiungi sei campi: code, name, city, country (Text) e latitude, longitude (Number). Imposta code come campo Route Slug e imposta lo stato su Active. Lascia tutti i campi facoltativi; non aggiungere tag UI Element.

Il componente airport — sei campi, con code impostato come Route Slug.

4. Importa il componente nei tipi

bun run generate-schemas

Questo comando scrive airportSchema (Zod) e Airport (type) in generated/cms-schemas.ts e conferma che le credenziali funzionano.

5. Popola i dati tramite l'MCP

Collega l'MCP e autentica:

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

Il server autentica tramite OAuth (WorkOS). In Claude Code, esegui /mcp, scegli Profound e completa l'accesso nel browser — Claude Code ti chiede automaticamente la prima volta che viene chiamato uno strumento Profound. Quando /mcp mostra Profound come connected, chiedi a Claude:

Genera cinquanta aeroporti reali — codici IATA corretti, nomi, città, paesi e coordinate. Salvali come JSON in una cartella data, validali rispetto al nostro componente airport, quindi crea ciascuno come documento pubblicato tramite il Profound MCP, in parallelo.

Apri airport → Variants per confermare ~50 aeroporti pubblicati. L'app legge con la chiave API; l'MCP scrive con la propria sessione WorkOS.

Circa 50 aeroporti, inseriti come Varianti pubblicate.

6. Aggiungi un design system

Lo scaffold viene fornito senza stile. Inserisci un file DESIGN.md (un blocco @theme di Tailwind v4 più i token) nella root del progetto — puoi crearne uno tuo oppure scaricarne uno da refero.design. Quindi chiedi a Claude:

Leggi DESIGN.md. Configura Tailwind v4 e integra il tema e i font. Usa next/font per i font, non un import runtime da Google. Solo styling — niente pagine o componenti per ora.

Verifica che src/app/globals.css contenga @import "tailwindcss"; più il blocco @theme, e che localhost:3000 mostri i token.

Parte 2 — Build

Costruisci il livello di render: gli elementi UI, i componenti React, la route, i binding CEL e la traduzione.

1. Definisci i quattro componenti UI Element

Nell'admin, fai Create new component quattro volte (senza Route Slug). Per ciascuno, aggiungi i campi come Text salvo indicazione diversa, imposta lo stato su Active e aggiungi il tag UI Element in Settings → Tags:

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

body.latitude e body.longitude devono essere Number per corrispondere al componente airport.

Ogni elemento UI è un componente a sé — qui body, attivo con il tag UI Element.

Tutti e quattro gli elementi UI accanto al componente airport personalizzato.

2. Rigenera i tipi

bun run generate-schemas

3. Genera i componenti React e registrali

Chiedi a Claude:

Crea quattro componenti React — nav, headline, body, footer — in components/. Ognuno accetta una singola prop content tipizzata come BlockComponentProps<T> da cms-renderer/lib/types, dove T è il tipo generato dell'elemento, e legge i campi da content. Registra tutti e quattro nel registro della route catch-all con il nome del componente. Stile secondo il nostro design system, ma come componenti originali — niente copia del layout del sito sorgente. Nav: brand a sinistra. Headline: nome dell'aeroporto con un sottotitolo code · city, country. Body: pannello dettagli con codice, città, paese e coordinate. Footer: una riga statica. Solo layout e stile.

Claude crea i quattro componenti e popola il registro in src/app/[...slug]/page.tsx:

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

Due regole: ogni componente legge i campi da content (non come prop separate) e le chiavi del registro devono corrispondere esattamente ai nomi dei componenti nel CMS — un disallineamento produce un render vuoto.

4. Crea la route parametrica

Nell'admin vai su Pages → Create page e imposta il pattern /{airport_code}. In Dynamic Segment Mappings, collega airport_code → componente airport, campo slug code. Salva — arriverai al Page Builder. Verifica che /JFK si risolva.

5. Aggiungi gli UI Element, collega il CEL e pubblica

Aggiunta di un elemento UI alla pagina dalla scheda Custom.

I quattro UI Element aggiunti al binding di JFK nel Page Builder.

  1. Seleziona il binding JFK → Add UI Element → scheda Custom → aggiungi nav, headline, body, footer in quest'ordine. Profound propaga il set a ogni binding aeroportuale.

  2. Compila ciascun campo. Valori statici (nav brand, testo del footer): inseriscili direttamente. Valori dinamici: passa alla modalità dinamica e scrivi CEL. La funzione di lookup condivisa è documents.get("airport", meta.params.airport_code).

    CampoValore 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 (e .longitude)
    nav.brand, footer.textstringhe statiche
  3. Pubblica la pagina (in alto a destra).

6. Verifica in inglese

Apri localhost:3000/JFK, poi /SFO, /LAX — stesso template, aeroporto diverso.

La pagina finale che mostra i dati di JFK, in inglese.

7. Internazionalizza

  1. Traduci prima i componenti. Nell'admin, apri ciascun componente (qualsiasi componente — non dev'essere un elemento UI) e fai clic su Translate → Submit. Profound traduce il contenuto in tutte e 35 le lingue in un colpo solo, inclusi i valori statici dei campi. Fallo prima di modificare la route o toccare il CEL.

    Translate → Submit invia un componente a tutte e 35 le lingue contemporaneamente.

  2. Aggiungi la dimensione lingua. In Pages, modifica il pattern in /{language}/{airport_code}. Aggiungi un Dynamic Segment Mapping per language → componente di sistema language, campo slug code. Salva e verifica che /en/JFK si risolva.

    Aggiunta del segmento {language} alla route.

  3. Collega ogni campo traducibile al fetch tradotto. Internazionalizzare la pagina significa sostituire ogni campo dipendente dalla lingua — non solo l'headline — da documents.get(...) a documents.translated("airport", meta.params.airport_code, meta.params.language):

    CampoCEL tradotto
    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 (e .country)

    Lascia il codice IATA code e le coordinate su documents.get — sono identici in ogni lingua. nav.brand e footer.text sono già coperti dalla traduzione del componente al punto 1.

Quando tutte e tre le operazioni sono completate, /fr/SFO, /de/SFO, ecc. si risolvono interamente tradotte.

Parte 3 — Production

1. Deploy: GitHub, poi Vercel

Esegui il push su GitHub:

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

Importa su Vercel: Add New → Project → importa il repository airports. Aggiungi le variabili d'ambiente — PROFOUND_API_KEY, NEXT_PUBLIC_PROFOUND_WEBSITE_ID, NEXT_PUBLIC_CMS_API_URL e facoltativamente NEXT_PUBLIC_BUNNY_CDN_URL — quindi fai Deploy. Visita /en/JFK e /fr/SFO. Ogni futuro git push genera un nuovo deploy.

2. Live preview e modifica in linea

Entrambi inclusi nello scaffold.

  • Live preview: il <Refresher> in layout.tsx aggiorna la pagina che stai visualizzando quando modifichi e salvi nell'admin — senza redeploy.
  • Modifica in linea: aggiungi ?edit_mode=true a qualsiasi URL (es. …/en/JFK?edit_mode=true) per le sovrapposizioni di editing. I visitatori pubblici vedono comunque la pagina pulita.

?edit_mode=true mostra l'editor sulla pagina live.

E questo è il progetto

Cinquanta aeroporti, 35 lingue, live — descritti una sola volta e alimentati dai dati: una route, quattro componenti React e una manciata di binding CEL. Il CMS conserva il contenuto, il tuo codice lo renderizza e il CEL li collega.

Continue Reading
NextDeployments›