Praktyczny przewodnik: zbuduj zmiędzynarodowiony katalog lotnisk w Profound CMS — jedna trasa parametryczna, która renderuje stronę dla każdego lotniska w 35 językach.
Zbuduj prawdziwy, zmiędzynarodowiony katalog lotnisk w Profound CMS: jeden wzorzec adresu URL, który renderuje stronę dla każdego lotniska w 35 językach. Ty piszesz kod Next.js i ręcznie tworzysz strukturę CMS; Claude Code (przez Profound MCP) zajmuje się trzema zadaniami — generuje dane lotnisk, podłącza system projektowy oraz tworzy cztery komponenty React. Trzy części: Przygotowanie, Budowa, Produkcja.
Obejrzyj pełny materiał wideo.
/{language}/{airport_code}.cms-renderer.curl -fsSL https://bun.sh/install | bashgh) oraz konto Vercel połączone z GitHubem.language) są wbudowane.cms-renderer z kluczem API poziomu odczytu.Stan końcowy: ok. 50 lotnisk w CMS, aplikacja podłączona do ich odczytu i gotowy system projektowy.
Zarejestruj się w Profound (uwierzytelnianie WorkOS) i utwórz witrynę o nazwie airports. Skopiuj dwie rzeczy: ID witryny (UUID w adresie URL panelu) oraz klucz API poziomu odczytu z Deployments → Create API key. Aplikacja tylko odczytuje, więc klucz odczytu w zupełności wystarczy.
bunx create-profound-next airports
cd airports
Dodaj swoje poświadczenia do .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
Uruchom bun dev i otwórz localhost:3000, aby potwierdzić połączenie.
airportW panelu przejdź do Components → Create new component i nazwij go airport. Dodaj sześć pól: code, name, city, country (Text) oraz latitude, longitude (Number). Oznacz code jako pole Route Slug i ustaw status na Active. Pozostaw wszystkie pola opcjonalne; nie dodawaj tagu UI Element.
Komponent airport — sześć pól, z code ustawionym jako Route Slug.
bun run generate-schemas
Polecenie zapisze airportSchema (Zod) oraz typ Airport do generated/cms-schemas.ts, a także potwierdzi poprawność poświadczeń.
Połącz MCP i uwierzytelnij się:
claude mcp add --transport http Profound http://107.21.107.99:8081/mcp
Serwer uwierzytelnia przez OAuth (WorkOS). W Claude Code uruchom /mcp, wybierz Profound i dokończ logowanie w przeglądarce — Claude Code poprosi Cię o to również automatycznie przy pierwszym wywołaniu narzędzia Profound. Gdy /mcp pokaże Profound jako connected, poproś Claude’a:
Wygeneruj pięćdziesiąt prawdziwych lotnisk — poprawne kody IATA, nazwy, miasta, kraje i współrzędne. Zapisz je jako JSON w folderze
data, zweryfikuj względem naszego komponentu lotnisk, a następnie utwórz każde jako opublikowany dokument przez Profound MCP, równolegle.
Otwórz airport → Variants, aby potwierdzić ok. 50 opublikowanych lotnisk. Aplikacja odczytuje za pomocą klucza API; MCP zapisuje w ramach własnej sesji WorkOS.
Około 50 lotnisk, załadowanych jako opublikowane warianty.
Szkielet jest dostarczany bez stylów. Umieść DESIGN.md (blok @theme Tailwind v4 plus tokeny) w katalogu głównym projektu — własny lub pobrany z refero.design. Następnie poproś Claude’a:
Przeczytaj DESIGN.md. Skonfiguruj Tailwind v4 i podłącz motyw oraz fonty. Użyj
next/fontdo fontów, bez importu Google w czasie wykonywania. Tylko stylowanie — żadnych stron ani komponentów.
Upewnij się, że src/app/globals.css zawiera @import "tailwindcss"; oraz blok @theme, a localhost:3000 prezentuje tokeny.
Zbuduj warstwę renderowania: elementy UI, komponenty React, trasę, wiązania CEL i tłumaczenia.
W panelu wybierz Create new component cztery razy (bez Route Slug). Dla każdego dodaj pola jako Text, o ile nie zaznaczono inaczej, ustaw status na Active i dodaj tag UI Element w Settings → Tags:
nav → brandheadline → title, subtitlebody → code, city, country, latitude (Number), longitude (Number)footer → textbody.latitude i body.longitude muszą być typu Number, aby odpowiadały komponentowi lotniska.
Każdy element UI jest osobnym komponentem — tutaj body, ustawiony na Active z tagiem UI Element.
Wszystkie cztery elementy UI obok komponentu airport.
bun run generate-schemas
Poproś Claude’a:
Zbuduj cztery komponenty React — nav, headline, body, footer — w katalogu
components/. Każdy przyjmuje pojedynczy propcontenttypowany jakoBlockComponentProps<T>zcms-renderer/lib/types, gdzieTto wygenerowany typ elementu, i odczytuje pola zcontent. Zarejestruj wszystkie cztery w rejestrze w trasie przechwytującej (catch-all) według nazwy komponentu. Ostyluj je naszym systemem projektowym, ale jako własne komponenty — nie kopiuj układu strony źródłowej. Nav: brand po lewej. Headline: nazwa lotniska z podtytułemcode · city, country. Body: panel szczegółów z kodem, miastem, krajem i współrzędnymi. Footer: jedna statyczna linia. Tylko układ i styl.
Claude tworzy cztery komponenty i uzupełnia rejestr w src/app/[...slug]/page.tsx:
const registry = { nav: Nav, headline: Headline, body: Body, footer: Footer };
Dwie zasady: każdy komponent odczytuje pola z content (nie jako osobne propy), a klucze w rejestrze muszą dokładnie odpowiadać nazwom komponentów w CMS — rozbieżność spowoduje pusty render.
W panelu przejdź do Pages → Create page i ustaw wzorzec /{airport_code}. W Dynamic Segment Mappings zmapuj airport_code na komponent airport, pole slug code. Zapisz — trafisz do Page Builder. Zweryfikuj, że /JFK działa.
Dodawanie elementu UI do strony z karty Custom.
Cztery elementy UI dodane do powiązania JFK w Page Builderze.
Wybierz powiązanie JFK → Add UI Element → zakładka Custom → dodaj nav, headline, body, footer w tej kolejności. Profound propaguje zestaw do każdego powiązania lotniska.
Wypełnij pola. Wartości statyczne (brand w nav, tekst w footerze): wpisz bezpośrednio. Wartości dynamiczne: przełącz na tryb dynamiczny i wpisz CEL. Wspólny odczyt to documents.get("airport", meta.params.airport_code).
| Pole | Wartość 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 (oraz .longitude) |
nav.brand, footer.text | ciągi statyczne |
Opublikuj stronę (prawy górny róg).
Otwórz localhost:3000/JFK, następnie /SFO, /LAX — ten sam szablon, różne lotnisko.
Gotowa strona renderująca dane JFK w języku angielskim.
Najpierw przetłumacz komponenty. W panelu otwórz każdy komponent (dowolny — nie musi to być element UI) i kliknij Translate → Submit. Profound przetłumaczy jego treść na wszystkie 35 języków naraz, włącznie ze statycznymi wartościami pól. Zrób to przed edycją trasy lub wiązań CEL.
Translate → Submit wysyła komponent do tłumaczenia na wszystkie 35 języków jednocześnie.
Dodaj wymiar językowy. W Pages zmień wzorzec na /{language}/{airport_code}. Dodaj Dynamic Segment Mapping dla language → wbudowany komponent systemowy language, pole slug code. Zapisz i sprawdź, że /en/JFK działa.
Dodawanie segmentu {language} do trasy.
Skieruj każde tłumaczalne pole na przetłumaczone dane. Internacjonalizacja strony wymaga zamiany każdego pola zależnego od języka — nie tylko nagłówka — z documents.get(...) na documents.translated("airport", meta.params.airport_code, meta.params.language):
| Pole | Przetłumaczona wartość CEL |
|---|---|
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 (oraz .country) |
Pozostaw kod IATA code i współrzędne na documents.get — są identyczne w każdym języku. nav.brand i footer.text zostały już pokryte przez tłumaczenie komponentu w kroku 1.
Po wykonaniu wszystkich trzech kroków /fr/SFO, /de/SFO itd. wczytują się w pełni przetłumaczone.
Wypchnij do GitHub:
git init
git add -A
git commit -m "Airport directory"
gh repo create airports --public --source=. --push
Zaimportuj do Vercel: Add New → Project → zaimportuj repozytorium airports. Dodaj zmienne środowiskowe — PROFOUND_API_KEY, NEXT_PUBLIC_PROFOUND_WEBSITE_ID, NEXT_PUBLIC_CMS_API_URL oraz opcjonalnie NEXT_PUBLIC_BUNNY_CDN_URL — następnie Deploy. Odwiedź /en/JFK i /fr/SFO. Każde kolejne git push wyzwala ponowne wdrożenie.
Obie funkcje są częścią szkieletu.
<Refresher> w layout.tsx odświeża stronę, którą podglądasz, gdy edytujesz i zapisujesz w panelu — bez ponownego wdrożenia.?edit_mode=true do dowolnego adresu (np. …/en/JFK?edit_mode=true), aby zobaczyć nakładki edycyjne. Publiczni odwiedzający nadal widzą czystą stronę.?edit_mode=true nakłada edytor na żywą stronę.
Pięćdziesiąt lotnisk, 35 języków, na żywo — opisane raz i wypełnione danymi: jedna trasa, cztery komponenty React i garść wiązań CEL. CMS przechowuje treści, Twój kod je renderuje, a CEL łączy jedno z drugim.