LessTools
LESSCMSWizualny edytor stron z headless API LESSCOMMERCESklep, PIM i zamówienia w jednym LESSSEOWidoczność w Google, mierzona co dzień — wkrótce
Jedno konto i jedna faktura dla wszystkich. Poznaj LessTools →
← Blog
Technologia

Headless CMS z Nuxt/Next.js: integracja przez API

Nuxt z headless CMS daje pełną kontrolę nad frontendem i szybkie strony renderowane po stronie serwera. Pokazujemy, jak bezpiecznie połączyć Nuxt i Next.js z API, gdzie trzymać klucz, jak cache’ować odpowiedzi i jak odświeżać treści bez webhooków.

Nuxt z headless CMS to połączenie, w którym treści redaguje się w panelu CMS-a, a frontend w Nuxt pobiera je przez API i renderuje stronę po stronie serwera. Headless CMS to system zarządzania treścią bez własnej warstwy prezentacji – przechowuje i udostępnia treści, a o wyglądzie strony decyduje twój kod. W tym poradniku pokazujemy, jak bezpiecznie zintegrować Nuxt (i Next.js) z API, gdzie trzymać klucz, jak cache'ować odpowiedzi i jak odświeżać treści.

Najważniejsze w skrócie

  • W architekturze Nuxt z headless CMS przeglądarka rozmawia z twoim serwerem Nuxt, a dopiero serwer odpytuje API CMS-a.
  • Klucz API powinien być używany wyłącznie po stronie serwera i nigdy nie trafiać do kodu wysyłanego do przeglądarki.
  • W Nuxt prywatny klucz przechowuje się w runtimeConfig poza sekcją public, a zapytania do CMS-a wykonuje się w trasach serwerowych.
  • Cache odpowiedzi po stronie serwera skraca czas ładowania i zmniejsza liczbę zapytań do API.
  • Bez webhooków treści odświeża się w oparciu o czas (np. co kilka minut) albo przez ponowne zbudowanie strony.

Jak działa Nuxt z headless CMS

Przepływ danych w typowym wdrożeniu Nuxt z headless CMS wygląda tak:

  1. Redaktor publikuje treść w panelu CMS-a.
  2. Użytkownik otwiera stronę – żądanie trafia do serwera Nuxt (lub na edge, jeśli tam wdrażasz aplikację).
  3. Serwer pobiera treść z API, dołączając klucz w nagłówku, albo korzysta z odpowiedzi zapisanej w cache.
  4. Nuxt renderuje HTML i wysyła go do przeglądarki, a następnie aplikacja przejmuje interakcję.

Dzięki renderowaniu po stronie serwera wyszukiwarki dostają gotowy HTML z treścią, a użytkownik szybciej widzi stronę. Ten sam model działa w Next.js – zmienia się tylko składnia.

Klucz API tylko po stronie serwera

To najważniejsza zasada całej integracji. Wszystko, co trafia do przeglądarki, może zobaczyć każdy użytkownik: w źródle strony, w narzędziach deweloperskich albo w ruchu sieciowym. Nawet klucz do API tylko do odczytu nie powinien być publiczny – pozwala pobierać wszystkie opublikowane treści projektu z pominięciem twojej strony i obciążać API w twoim imieniu.

  • w Nuxt trzymaj klucz w runtimeConfig, ale nie w runtimeConfig.public;
  • w Next.js nie używaj prefiksu NEXT_PUBLIC_ dla klucza – takie zmienne trafiają do kodu klienta;
  • nie wywołuj API CMS-a bezpośrednio z komponentów, które mogą wykonać się w przeglądarce, np. przy nawigacji po stronie;
  • dodaj pliki .env do .gitignore, a w produkcji ustaw klucz w zmiennych środowiskowych hostingu;
  • jeśli klucz wycieknie, odwołaj go w panelu i wygeneruj nowy.

Integracja Nuxt z headless CMS krok po kroku

Załóżmy, że w CMS-ie masz kolekcję o kodzie realizacje. Najpierw konfigurujesz prywatny klucz i adres bazowy API:

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    // klucz prywatny: dostępny tylko na serwerze,
    // wartość ze zmiennej środowiskowej NUXT_LESSCMS_API_KEY
    lesscmsApiKey: '',
    lesscmsBase: 'https://api.lesscms.io/v1/moj-workspace/moj-projekt'
  }
})

Następnie tworzysz trasę serwerową, która jako jedyna rozmawia z CMS-em. defineCachedEventHandler zapisuje odpowiedź w cache serwera, a timeout chroni stronę przed zawieszeniem przy wolnej odpowiedzi API:

// server/api/realizacje.get.ts
export default defineCachedEventHandler(async () => {
  const { lesscmsApiKey, lesscmsBase } = useRuntimeConfig()
  return $fetch(`${lesscmsBase}/collections/realizacje`, {
    headers: { 'x-api-key': lesscmsApiKey },
    timeout: 10000
  })
}, { maxAge: 600 }) // odpowiedź w cache serwera przez 10 minut

Strona odpytuje już tylko twój endpoint, więc klucz nigdy nie opuszcza serwera – również przy nawigacji po stronie w przeglądarce:

// pages/realizacje/index.vue (fragment <script setup>)
const { data: realizacje, error } = await useFetch('/api/realizacje')

Obsłuż error w szablonie: pokaż komunikat albo ostatnią znaną wersję treści, zamiast pustej strony.

Ten sam wzorzec w Next.js

W Next.js z App Routerem komponenty serwerowe wykonują się wyłącznie na serwerze, więc możesz w nich bezpośrednio odczytać zmienną środowiskową:

// app/realizacje/page.tsx – komponent serwerowy
const BASE = 'https://api.lesscms.io/v1/moj-workspace/moj-projekt'

async function getRealizacje() {
  const res = await fetch(`${BASE}/collections/realizacje`, {
    headers: { 'x-api-key': process.env.LESSCMS_API_KEY! },
    next: { revalidate: 600 } // odświeżanie co 10 minut
  })
  if (!res.ok) throw new Error(`LessCMS API: ${res.status}`)
  return res.json()
}

export default async function Page() {
  const realizacje = await getRealizacje()
  return <ListaRealizacji dane={realizacje} />
}

Jeśli potrzebujesz danych w komponencie klienckim, udostępnij je przez Route Handler (app/api/.../route.ts), który działa jak serwerowy pośrednik.

Cache i odświeżanie treści bez webhooków

Część headless CMS-ów wysyła webhook po publikacji, co pozwala natychmiast odświeżyć konkretną stronę. Jeśli twój CMS tego nie oferuje, wybierasz jedną z poniższych strategii:

StrategiaJak działaKiedy wybrać
SSR bez cacheKażde żądanie odpytuje APIMały ruch, treść musi być zawsze aktualna
Cache czasowy (SWR, ISR)Odpowiedź żyje np. 5–10 minut, potem odświeża się w tleWiększość stron firmowych i blogów
Generowanie statyczneStrona budowana w całości przy deployuRzadkie zmiany; publikacja wymaga ponownego builda

Czas życia cache to kompromis: im krótszy, tym szybciej widać zmiany, ale tym więcej zapytań do API. Dla typowej strony firmowej kilka minut jest rozsądnym punktem wyjścia. W Nuxt z headless CMS ustawisz go w trasie serwerowej (maxAge) albo globalnie przez routeRules z opcją swr.

SEO w projekcie headless

W architekturze Nuxt z headless CMS za SEO odpowiada twój frontend. Meta tagi ustawiasz w Nuxt przez useSeoMeta, a w Next.js przez generateMetadata – na podstawie pól pobranych z API. Pamiętaj też o mapie strony, pliku robots.txt i przekierowaniach 301: jeśli CMS udostępnia je przez API, frontend może je odczytać zamiast utrzymywać ręcznie.

Typowe błędy przy integracji

W projektach Nuxt z headless CMS najczęściej powtarzają się te same potknięcia:

  • klucz w runtimeConfig.public lub w zmiennej NEXT_PUBLIC_;
  • brak timeoutu i obsługi błędów – awaria API kończy się pustą stroną;
  • brak cache – każda odsłona generuje zapytanie do CMS-a;
  • zakodowane na sztywno adresy URL zamiast tras pobieranych z CMS-a.

Jak to wygląda w LessCMS

  • Publiczne API tylko do odczytu zwraca wyłącznie opublikowane treści: strony, kolekcje, menu, bloki, elementy, przekierowania, sitemap, robots, trasy i konfigurację. Endpoint kolekcji ma postać https://api.lesscms.io/v1/{workspace}/{projekt}/collections/{kod}, a pełną dokumentację znajdziesz w Swaggerze pod /api-docs.
  • Klucze API per projekt przekazujesz w nagłówku x-api-key i możesz je w każdej chwili odwołać. Odpowiedzi zawierają nagłówki Cache-Tag.
  • LessCMS nie wysyła webhooków, dlatego w projekcie Nuxt z headless CMS stosuj cache czasowy (SWR lub ISR) albo ponowny build.
  • Nie musisz budować frontu: LessCMS może też sam renderować całą stronę (SSR na Nuxt) na twojej domenie, z automatycznym czyszczeniem cache Cloudflare po publikacji.

Więcej o modelowaniu kolekcji przeczytasz na stronie struktury treści, a o pracy programistów – w zakładce dla deweloperów.

Najczęstsze pytania

Czy Nuxt dobrze współpracuje z headless CMS?

Tak, Nuxt z headless CMS to popularne połączenie, bo framework ma wbudowane renderowanie po stronie serwera, trasy serwerowe i cache. Pozwala to bezpiecznie ukryć klucz API i serwować gotowy HTML wyszukiwarkom.

Czy mogę pobierać dane z headless CMS bezpośrednio w przeglądarce?

Technicznie tak, ale wtedy klucz API staje się publiczny. Bezpieczniej jest odpytywać CMS z serwera i udostępniać przeglądarce tylko gotowe dane przez własny endpoint.

Jak odświeżyć stronę Nuxt po publikacji treści w CMS-ie?

Najprościej ustawić krótki czas życia cache, np. kilka minut, dzięki czemu nowa treść pojawi się automatycznie. Jeśli CMS wysyła webhooki, możesz dodatkowo czyścić cache od razu po publikacji.

Czy headless CMS jest lepszy dla SEO niż tradycyjny?

Nie z definicji – o SEO decyduje renderowanie i jakość wdrożenia. Headless z SSR może być bardzo dobry, ale meta tagi, mapę strony i przekierowania musisz obsłużyć we frontendzie.

Czy do LessCMS potrzebuję własnego frontendu?

Nie. Możesz korzystać z LessCMS jako headless CMS z własnym Nuxtem lub Next.js albo pozwolić mu renderować całą stronę na twojej domenie.

Chcesz sprawdzić endpointy w praktyce? Zajrzyj na stronę API LessCMS, a potem wybierz plan w cenniku – konto założysz bez karty.

headless cmsnuxtnext.jsapi

Zbuduj taką stronę u siebie

Wizualny edytor, treść przez API i SEO w standardzie — w każdym planie.