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

Un guide pratique : créez un annuaire d’aéroports internationalisé sur Profound CMS — une route paramétrique qui génère une page pour chaque aéroport, en 35 langues.

Créez un véritable annuaire d’aéroports internationalisé sur Profound CMS : un motif d’URL qui génère une page pour chaque aéroport, en 35 langues. Vous écrivez le code Next.js et construisez la structure du CMS à la main ; Claude Code (via le Profound MCP) s’occupe de trois tâches — générer les données des aéroports, connecter un système de design et générer les quatre composants React. Trois parties : Configuration, Construction, Production.

Regardez la vidéo de présentation complète.

Ce que vous allez construire

  • ~50 fiches d’aéroports, chacune à sa propre URL.
  • Une route paramétrique /{language}/{airport_code}.
  • Quatre éléments d’interface — navigation, titre, corps, pied de page — rendus par cms-renderer.
  • Des données CMS en direct via des liaisons CEL.
  • Les 35 langues, traduites en un clic.
  • Déploiement sur Vercel avec prévisualisation en direct et édition in situ.

Prérequis

  • Bun ≥ 1.3 — curl -fsSL https://bun.sh/install | bash
  • Claude Code avec le Profound MCP connecté (Partie 1).
  • Un compte Profound CMS.
  • Pour la partie 3 : GitHub CLI (gh) connecté et un compte Vercel relié à GitHub.

Comment l’ensemble s’articule

  • Les composants définissent la forme du contenu. Un champ Route Slug rend un composant routable ; une étiquette UI Element le rend positionnable sur une page ; les composants System (comme language) sont fournis par défaut.
  • Les variantes constituent le contenu (JFK, SFO, LAX…).
  • Les éléments d’interface sont des sections de page, remplies avec CEL — le script in-template de Profound, évalué au rendu.
  • Une route paramétrique associe une URL à une variante accompagnée d’un ensemble d’éléments d’interface.
  • Votre application Next.js rend le tout via le SDK cms-renderer avec une clé API de niveau lecture.

Partie 1 — Configuration

État final : ~50 aéroports dans le CMS, l’application connectée pour les lire, et le système de design en place.

1. Créer le site web

Inscrivez-vous sur Profound (authentification WorkOS) et créez un site nommé airports. Copiez deux éléments : l’ID du site (le UUID dans l’URL d’administration) et une clé API de niveau lecture depuis Deployments → Create API key. L’application ne fait que lire, une clé de lecture suffit donc.

2. Mettre l’application en place et la connecter

bunx create-profound-next airports
cd airports

Ajoutez vos identifiants à .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

Exécutez bun dev et ouvrez localhost:3000 pour confirmer la connexion.

3. Créer le composant airport

Dans l’admin, allez à Components → Create new component et nommez-le airport. Ajoutez six champs : code, name, city, country (Text) et latitude, longitude (Number). Marquez code comme champ Route Slug et définissez le statut sur Active. Laissez tous les champs facultatifs ; n’ajoutez aucune étiquette UI Element.

Le composant airport — six champs, avec code défini comme Route Slug.

4. Importer le composant dans les types

bun run generate-schemas

Cela écrit airportSchema (Zod) et Airport (type) dans generated/cms-schemas.ts, et confirme que vos identifiants fonctionnent.

5. Initialiser les données via le MCP

Connectez le MCP et authentifiez-vous :

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

Le serveur s’authentifie via OAuth (WorkOS). Dans Claude Code, exécutez /mcp, choisissez Profound et terminez la connexion dans votre navigateur — Claude Code vous y invite également automatiquement lors du premier appel à un outil Profound. Une fois que /mcp affiche Profound comme connected, demandez à Claude :

Génère cinquante aéroports réels — codes IATA valides, noms, villes, pays et coordonnées. Enregistre-les en JSON dans un dossier data, valide-les par rapport à notre composant airport, puis crée chacun comme document publié via le Profound MCP, en parallèle.

Ouvrez airport → Variants pour confirmer ~50 aéroports publiés. L’application lit avec la clé API ; le MCP écrit avec sa propre session WorkOS.

Environ 50 aéroports, initialisés comme variantes publiées.

6. Ajouter un système de design

Le squelette est livré sans style. Placez un fichier DESIGN.md (un bloc @theme Tailwind v4 plus des tokens) à la racine du projet — le vôtre, ou téléchargez-en un sur refero.design. Ensuite, demandez à Claude :

Lis DESIGN.md. Configure Tailwind v4 et connecte le thème et les polices. Utilise next/font pour les polices, pas d’import Google au runtime. Style uniquement — pas de pages ni de composants pour l’instant.

Vérifiez que src/app/globals.css contient @import "tailwindcss"; ainsi que le bloc @theme, et que localhost:3000 affiche les tokens.

Partie 2 — Construction

Construisez la couche de rendu : les éléments d’interface, les composants React, la route, les liaisons CEL et la traduction.

1. Définir les quatre composants d’éléments d’interface

Dans l’admin, Create new component quatre fois (sans Route Slug). Pour chacun, ajoutez les champs en Text sauf mention contraire, définissez le statut sur Active et ajoutez l’étiquette UI Element dans Settings → Tags :

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

body.latitude et body.longitude doivent être en Number pour correspondre au composant airport.

Chaque élément d’interface est son propre composant — ici body, défini sur Active avec l’étiquette UI Element.

Les quatre éléments d’interface aux côtés du composant airport.

2. Régénérer les types

bun run generate-schemas

3. Générer les composants React et les enregistrer

Demandez à Claude :

Crée quatre composants React — nav, headline, body, footer — dans components/. Chacun doit accepter une prop unique content typée comme BlockComponentProps<T> depuis cms-renderer/lib/types, où T est le type généré de l’élément, et lire ses champs sur content. Enregistre les quatre dans le registre de la route catch-all par leur nom de composant. Stylise-les avec notre système de design, mais comme nos propres composants — ne copie pas la mise en page du site source. Nav : marque à gauche. Headline : nom de l’aéroport avec un sous-titre code · ville, pays. Body : panneau de détails avec code, ville, pays et coordonnées. Footer : une ligne statique. Mise en page et style uniquement.

Claude crée les quatre composants et complète le registre dans src/app/[...slug]/page.tsx :

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

Deux règles : chaque composant lit ses champs sur content (pas comme props séparées), et les clés du registre doivent correspondre exactement aux noms des composants dans le CMS — sinon le rendu reste vide.

4. Créer la route paramétrique

Dans l’admin, allez à Pages → Create page et définissez le motif /{airport_code}. Sous Dynamic Segment Mappings, mappez airport_code → le composant airport, champ slug code. Enregistrez — vous arrivez dans le Page Builder. Vérifiez que /JFK fonctionne.

5. Ajouter les éléments d’interface, connecter CEL et publier

Ajout d’un élément d’interface à la page depuis l’onglet Custom.

Les quatre éléments d’interface ajoutés à la liaison JFK dans le Page Builder.

  1. Choisissez la liaison JFK → Add UI Element → onglet Custom → ajoutez nav, headline, body, footer dans cet ordre. Profound réplique cet ensemble sur chaque liaison d’aéroport.

  2. Remplissez chaque champ. Valeurs statiques (marque de la nav, texte du pied de page) : saisissez-les directement. Valeurs dynamiques : passez en mode dynamique et écrivez du CEL. La recherche partagée est documents.get("airport", meta.params.airport_code).

    ChampValeur 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 (et .longitude)
    nav.brand, footer.textchaînes statiques
  3. Publiez la page (en haut à droite).

6. Vérifier en anglais

Ouvrez localhost:3000/JFK, puis /SFO, /LAX — même modèle, aéroport différent.

La page finale affichant les données de JFK, en anglais.

7. Internationaliser

  1. Traduisez d’abord les composants. Dans l’admin, ouvrez chaque composant (n’importe lequel — il n’a pas besoin d’être un élément d’interface) et cliquez sur Translate → Submit. Profound traduit son contenu dans les 35 langues en une seule fois, valeurs statiques incluses. Faites-le avant de modifier la route ou de toucher au CEL.

    Translate → Submit envoie un composant dans les 35 langues d’un coup.

  2. Ajoutez la dimension de langue. Dans Pages, modifiez le motif en /{language}/{airport_code}. Ajoutez un Dynamic Segment Mapping pour language → le composant système intégré language, champ slug code. Enregistrez et vérifiez que /en/JFK fonctionne.

    Ajout du segment {language} à la route.

  3. Orientez chaque champ traduisible vers la récupération traduite. Internationaliser la page signifie basculer tous les champs dépendants de la langue — pas seulement le titre — de documents.get(...) à documents.translated("airport", meta.params.airport_code, meta.params.language) :

    ChampCEL traduit
    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 (et .country)

    Laissez le code IATA et les coordonnées sur documents.get — ils sont identiques dans chaque langue. nav.brand et footer.text sont déjà couverts par la traduction du composant à l’étape 1.

Une fois ces trois actions terminées, /fr/SFO, /de/SFO, etc. s’affichent entièrement traduits.

Partie 3 — Production

1. Déployer : GitHub, puis Vercel

Poussez sur GitHub :

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

Importez dans Vercel : Add New → Project → importez le dépôt airports. Ajoutez les variables d’environnement — PROFOUND_API_KEY, NEXT_PUBLIC_PROFOUND_WEBSITE_ID, NEXT_PUBLIC_CMS_API_URL, et éventuellement NEXT_PUBLIC_BUNNY_CDN_URL — puis Deploy. Visitez /en/JFK et /fr/SFO. Chaque futur git push redéploie.

2. Prévisualisation en direct et édition in situ

Les deux sont fournis avec le squelette.

  • Prévisualisation en direct : le <Refresher> dans layout.tsx met à jour la page que vous prévisualisez lorsque vous modifiez et enregistrez dans l’admin — sans redéploiement.
  • Édition in situ : ajoutez ?edit_mode=true à n’importe quelle URL (par ex. …/en/JFK?edit_mode=true) pour afficher les superpositions d’édition. Les visiteurs publics voient toujours la page propre.

?edit_mode=true affiche l’éditeur en superposition sur la page en production.

Voilà la réalisation

Cinquante aéroports, 35 langues, en production — décrits une seule fois et alimentés par les données : une route, quatre composants React et une poignée de liaisons CEL. Le CMS conserve le contenu, votre code le rend, et CEL fait le lien.

Continue Reading
NextDeployments›