Kamaankamaan

Blog API: Headless-CMS-Inhalte in jedem Framework abrufen

Eine portable Blog API gibt schlichtes REST-JSON zurück, sodass Next.js, Nuxt, SvelteKit, Astro und reines React alle aus demselben Endpoint ziehen, ohne anbieterspezifisches SDK. Dieser Artikel zeigt die Antwortform und

Junaid Khalid
Junaid Khalid
29. Mai 2026 · 10 min read

Blog API: Wie du Headless-CMS-Inhalte in jedem Framework abrufst und renderst

Jedes Framework hat sein eigenes CMS-SDK-Tutorial. Die Next.js-Docs zeigen dir Contentful. Die Nuxt-Docs zeigen dir Sanity. Die SvelteKit-Docs zeigen dir Storyblok. Die Astro-Docs zeigen dir Strapi. Keines zeigt dir, was du eigentlich willst: einen Endpoint, eine JSON-Form, fünf Frontends, die ohne anbieterspezifisches SDK in einem von ihnen ziehen. Das Ergebnis sind Teams, die ein CMS wählen, in dessen Client-Bibliothek hängen bleiben und bei jedem Framework-Wechsel neu plattformieren. Eine Blog API, die einfaches REST-JSON zurückgibt, durchbricht dieses Muster. Dieser Artikel führt durch einen solchen Endpoint, die zurückgegebene Form und den exakten Fetch-Code für Next.js, Nuxt, SvelteKit, Astro und reines React.

Schnelle Erkenntnisse

  • Eine Blog API ist nur ein REST-Endpoint, der Artikel als JSON zurückgibt. Kein SDK nötig.
  • Derselbe Endpoint kann Next.js, Nuxt, SvelteKit, Astro und React mit unter 15 Zeilen Fetch-Code pro Framework bedienen.
  • Eine saubere Antwortform enthält id, title, slug, content (Markdown oder HTML), excerpt, featured_image_url, language und parent_article_id für Übersetzungen.
  • Kamaan ist die Kommandozentrale für Multi-Product-Gründer und Agenturen, die viele SaaS-Blogs betreiben: verwalte jeden Blog aus einem Dashboard und führe jede Operation über alle hinweg aus Claude, ChatGPT, Cursor oder jedem MCP-Client aus.
  • Die erste Verdrahtung dauert für einen Entwickler 40 bis 60 Minuten. Folgeblogs nutzen dasselbe Fetch-Muster wieder.

Warum eine portable Blog API mehr zählt als ein weiteres SDK

Die Aufgabe eines CMS ist es, Inhalte zu speichern und zurückzugeben. SDKs legen eine Hülle um diese Aufgabe. Hüllen fühlen sich am Anfang hilfreich an, werden dann zur Reibung. Du aktualisierst das Framework, das SDK bricht. Du wechselst das Framework, das SDK existiert nicht. Du startest ein zweites Produkt, du zahlst pro Space und pro Sitz für ein SDK, um das du bereits Glue-Code geschrieben hast. Eine schlichte REST-API überspringt all das. Wenn dein CMS JSON zurückgibt, kann dein Frontend es rendern.

Dieser Artikel verwendet die REST-API von Kamaan als laufendes Beispiel, weil sie eine flache, vorhersagbare JSON-Form zurückgibt und weil derselbe Endpoint jede Site in deinem Konto bedient. Das Muster unten funktioniert mit jedem CMS, das REST anbietet. Wenn du eine tiefere Einführung in die Architekturwahl willst, behandelt die Säule zu Blog zu einer SaaS hinzufügen, wann du Headless gegenüber einem In-App-Blog wählst. Der Begleittext zu was ist ein Headless CMS erklärt die zugrunde liegende Trennung zwischen Inhaltsspeicherung und Rendering.

So sieht derselbe Fetch auf einen Blick über alle fünf Frameworks aus:

Blog-API-Tutorial-Karte mit einem Kamaan-REST-Endpoint, gerendert von Next.js, Nuxt, SvelteKit, Astro und reinem React

Der Beispiel-Endpoint und die Antwortform

So sieht der Aufruf aus, den jedes Framework unten macht:

GET https://api.kamaan.io/v1/sites/{site_id}/articles?language=en&status=published
Authorization: Bearer kmn_pk_live_xxxxxxxxxxxxxxxx

Die Antwort ist ein JSON-Array von Artikeln. Jeder Eintrag sieht so aus:

{
  "id": "art_2k1nB7Vy8q",
  "title": "Blog API: How to Fetch and Render Headless CMS Content in Any Framework",
  "slug": "blog-api",
  "content": "# Blog API\n\nEvery framework has its own CMS SDK tutorial...",
  "excerpt": "One Kamaan endpoint, rendered five different ways.",
  "featured_image_url": "https://cdn.kamaan.io/img/km0013_featured.png",
  "language": "en",
  "parent_article_id": null,
  "status": "published",
  "published_at": "2026-05-29T10:14:00Z",
  "updated_at": "2026-05-29T10:14:00Z",
  "meta_title": "Blog API: One Endpoint, Five Frontends",
  "meta_description": "How to fetch and render headless CMS content...",
  "tags": ["headless-cms", "blog-api", "developer-integration"]
}

Einen einzelnen Artikel per Slug bekommst du so:

GET https://api.kamaan.io/v1/sites/{site_id}/articles/blog-api?language=en

Übersetzungen verweisen über parent_article_id zurück auf die Quelle. Um die deutsche Version desselben Beitrags zu bekommen, ändere language=en zu language=de. Es gibt keinen zusätzlichen Übersetzungs-Endpoint. Das Artikelobjekt hat dieselbe Form über alle Sprachen, also muss deine Routing-Schicht nicht auf Locale verzweigen.

Fetch Nummer eins: Next.js App Router

Server-Komponente, läuft zur Build-Zeit oder bei Bedarf mit Cache-Kontrolle:

// app/blog/page.tsx
const SITE_ID = process.env.KAMAAN_SITE_ID!;
const TOKEN = process.env.KAMAAN_TOKEN!;

async function getArticles() {
  const res = await fetch(
    `https://api.kamaan.io/v1/sites/${SITE_ID}/articles?language=en&status=published`,
    {
      headers: { Authorization: `Bearer ${TOKEN}` },
      next: { revalidate: 600 },
    },
  );
  if (!res.ok) throw new Error("Kamaan fetch failed");
  return res.json();
}

export default async function BlogIndex() {
  const articles = await getArticles();
  return (
    <ul>
      {articles.map((a: any) => (
        <li key={a.id}>
          <a href={`/blog/${a.slug}`}>{a.title}</a>
          <p>{a.excerpt}</p>
        </li>
      ))}
    </ul>
  );
}

Die Zeile next: { revalidate: 600 } weist Next.js an, die Antwort 10 Minuten zu cachen. Für einen Marketing-Blog, der ein paar Mal pro Woche veröffentlicht, ist das die richtige Voreinstellung. Wenn du reines Static willst, wechsle zu force-cache. Wenn du jede Anfrage frisch willst, wechsle zu no-store. Für das vollständige Muster inklusive Artikeldetailseite und Incremental Static Regeneration siehe den Next.js Headless-CMS-Leitfaden.

Fetch Nummer zwei: Nuxt 3

Derselbe Endpoint, useFetch-Composable, läuft serverseitig während des SSR:

<!-- pages/blog/index.vue -->
<script setup lang="ts">
const config = useRuntimeConfig();
const { data: articles } = await useFetch(
  `https://api.kamaan.io/v1/sites/${config.kamaanSiteId}/articles`,
  {
    query: { language: "en", status: "published" },
    headers: { Authorization: `Bearer ${config.kamaanToken}` },
    server: true,
  },
);
</script>

<template>
  <ul>
    <li v-for="a in articles" :key="a.id">
      <NuxtLink :to="`/blog/${a.slug}`">{{ a.title }}</NuxtLink>
      <p>{{ a.excerpt }}</p>
    </li>
  </ul>
</template>

useFetch dedupliziert den Aufruf automatisch zwischen Server-Render und Client-Hydration. Die Runtime-Config hält den Token aus dem Client-Bundle heraus.

Fetch Nummer drei: SvelteKit

Die Load-Funktion auf der Serverseite gibt dir volle Kontrolle über Cache-Header:

// routes/blog/+page.server.ts
import { KAMAAN_SITE_ID, KAMAAN_TOKEN } from "$env/static/private";

export async function load({ fetch, setHeaders }) {
  const res = await fetch(
    `https://api.kamaan.io/v1/sites/${KAMAAN_SITE_ID}/articles?language=en&status=published`,
    { headers: { Authorization: `Bearer ${KAMAAN_TOKEN}` } },
  );
  setHeaders({ "cache-control": "public, max-age=600" });
  return { articles: await res.json() };
}
<!-- routes/blog/+page.svelte -->
<script lang="ts">
  export let data;
</script>

<ul>
  {#each data.articles as a (a.id)}
    <li>
      <a href={`/blog/${a.slug}`}>{a.title}</a>
      <p>{a.excerpt}</p>
    </li>
  {/each}
</ul>

Fetch Nummer vier: Astro

Astro holt standardmäßig zur Build-Zeit, was perfekt zu einem inhaltslastigen Blog passt:

---
// src/pages/blog/index.astro
const SITE_ID = import.meta.env.KAMAAN_SITE_ID;
const TOKEN = import.meta.env.KAMAAN_TOKEN;

const res = await fetch(
  `https://api.kamaan.io/v1/sites/${SITE_ID}/articles?language=en&status=published`,
  { headers: { Authorization: `Bearer ${TOKEN}` } },
);
const articles = await res.json();
---

<ul>
  {articles.map((a) => (
    <li>
      <a href={`/blog/${a.slug}`}>{a.title}</a>
      <p>{a.excerpt}</p>
    </li>
  ))}
</ul>

Wenn du Astro auf SSR-Modus umstellst, läuft derselbe Code bei jeder Anfrage. Keine Codeänderungen.

Fetch Nummer fünf: reines React (Vite)

Client-seitiger Fetch in einer einfachen React-App. Nützlich, wenn der Blog in einem authentifizierten SaaS-Dashboard lebt:

// src/pages/Blog.tsx
import { useEffect, useState } from "react";

const SITE_ID = import.meta.env.VITE_KAMAAN_SITE_ID;
const TOKEN = import.meta.env.VITE_KAMAAN_TOKEN;

export function Blog() {
  const [articles, setArticles] = useState<any[]>([]);
  useEffect(() => {
    fetch(
      `https://api.kamaan.io/v1/sites/${SITE_ID}/articles?language=en&status=published`,
      { headers: { Authorization: `Bearer ${TOKEN}` } },
    )
      .then((r) => r.json())
      .then(setArticles);
  }, []);
  return (
    <ul>
      {articles.map((a) => (
        <li key={a.id}>
          <a href={`/blog/${a.slug}`}>{a.title}</a>
          <p>{a.excerpt}</p>
        </li>
      ))}
    </ul>
  );
}

Für eine clientseitige React-App stelle einen schreibgeschützten öffentlichen Token bereit. Versende niemals ein Schreib-Token an den Browser.

Hier dasselbe Bild als einzelne Referenzkarte: ein Endpoint oben, der Dateipfad, an dem der Fetch jedes Frameworks lebt, darunter.

Infografik mit einem Kamaan-REST-Endpoint, abgerufen von Next.js, Nuxt, SvelteKit, Astro und React, jeweils mit Dateipfad

Zwei reale Szenarien

Szenario eins: ein Solo-Gründer mit drei SaaS-Produkten. Jedes Produkt hat seine eigene Marketing-Site auf einem anderen Stack, zu unterschiedlichen Zeitpunkten gewählt. Produkt A läuft auf Next.js, Produkt B auf Astro, Produkt C auf einem reinen React-Dashboard. Ohne portable Blog API pflegt der Gründer drei verschiedene CMS-Integrationen, drei verschiedene Content-Workflows und drei verschiedene Rechnungen. Mit einem Kamaan-Konto und drei Sites darunter läuft dasselbe Fetch-Muster oben auf allen dreien. Neue Artikel, in Claude entworfen, landen über den MCP-Server in der richtigen Site, und jedes Frontend zieht sie bei der nächsten Revalidierung. Gesamte Integrationszeit über alle drei Frontends: unter drei Stunden.

Szenario zwei: eine kleine Agentur mit sieben Kunden-SaaS-Blogs. Die Agentur möchte nicht sieben CMS-UIs an sieben Kunden vermitteln. Sie betreiben alle sieben Blogs aus einem Kamaan-Dashboard, geben jedem Kunden einen Editor-Sitz, auf seine Site beschränkt, und lassen ihr Content-Team aus einem einzigen ChatGPT-Fenster über alle sieben hinweg im Batch schreiben. Jede Kunden-Site nutzt das Framework, in dem die Agentur sie gebaut hat, und holt dieselbe JSON-Form.

Wo Kamaan ins Bild passt

Kamaan ist die Kommandozentrale für Multi-Product-Gründer und Agenturen, die viele SaaS-Blogs betreiben: verwalte jeden Blog aus einem Dashboard und führe jede Operation über alle hinweg aus Claude, ChatGPT, Cursor oder jedem MCP-Client aus. Der oben gezeigte REST-Endpoint hat dieselbe Form über jede Site in deinem Konto. Auto-Multilingual Delivery bedeutet, dass Übersetzungen bei der Veröffentlichung automatisch erscheinen, zurückgegeben vom selben Articles-Endpoint mit language=de, language=fr und so weiter. Das Feld parent_article_id verknüpft jede Übersetzung zurück mit ihrer englischen Quelle, sodass deine Routing-Schicht Locale-Varianten ohne zweite Anfrage auflösen kann.

Der Preis liegt bei 19 Dollar pro Monat, pauschal, unbegrenzte Sites, keine Gebühren pro Site, pro Space oder pro Sitz. Der erste Monat ist gratis, keine Kreditkarte zum Start, jederzeit kündbar. Ein Lifetime-Plan ist verfügbar für Teams, die lieber einmal zahlen. KI-Übersetzungskredite werden nur verbraucht, wenn Kamaan übersetzt. Wenn du eigene Übersetzungen aus Claude oder ChatGPT einfügst, kostet der Upload nichts.

Die CMS-Seite des ersten Publikationszyklus dauert rund 14 Minuten von der Anmeldung bis zum ersten veröffentlichten Beitrag. Die Entwickler-Integration, der Teil, den dieser Artikel behandelt, dauert ehrlich 40 bis 60 Minuten für die erste Verdrahtung inklusive Umgebungsvariablen, Index-Route, Detail-Route und Sitemap. Danach nutzt jede neue Site denselben Fetch wieder.

FAQ

Was ist eine Blog API?

Eine Blog API ist ein HTTP-Endpoint, der Blogartikel als strukturierte Daten zurückgibt, in der Regel JSON. Dein Frontend-Code ruft den Endpoint auf, empfängt die Artikel und rendert sie, wie du willst. Das CMS kümmert sich um Speicherung, Bearbeitung und Veröffentlichung. Das Frontend kümmert sich um die Darstellung.

Brauche ich ein anbieterspezifisches SDK, um eine Blog API zu nutzen?

Nein. Die in jedem modernen JavaScript-Runtime eingebaute native Fetch-Funktion reicht. SDKs können Komfort hinzufügen (typisierte Antworten, Retry-Logik, Bildtransformationen), aber sie binden dich auch. Ein REST-Endpoint, der einfaches JSON zurückgibt, funktioniert mit jedem Framework, in jedem Jahr, in jeder Version.

Kann dieselbe Blog API mehrere Frontends bedienen?

Ja. Das ist der Sinn von Headless. Du kannst dieselben Artikel auf einer Next.js-Marketing-Site, einer Astro-Doku-Site und einem React-Dashboard gleichzeitig rendern, alle aus einem Endpoint. Dem CMS ist es egal, wie der Inhalt gerendert wird.

Wie behandle ich Übersetzungen aus einer Blog API?

Suche ein CMS, das Übersetzungen als separate Artikelobjekte zurückgibt, mit der Quelle über ein Parent-Feld verknüpft. Kamaan nutzt parent_article_id. Um die deutsche Version zu holen, übergib language=de an demselben Articles-Endpoint. Vermeide CMS, die Übersetzungen in ein einzelnes Artikelobjekt verschachteln, weil das jedes Frontend zwingt, die Locale-Logik zu parsen.

Soll ich Antworten der Blog API cachen?

Ja, in fast jedem Fall. Marketing-Blog-Inhalte ändern sich nicht oft. Für Static-Export-Frameworks wie Astro oder Next.js mit Revalidate findet der Fetch zur Build-Zeit oder in einem langen Intervall statt. Für SSR-Frameworks ist ein Cache von 5 bis 10 Minuten meist sicher. Überspringe den Cache nur, wenn Vorschau-Entwürfe für eingeloggte Redakteure sofort erscheinen sollen.

Was ist mit Vorschau-Entwürfen?

Übergib status=draft und füge einen Auth-Header oder einen Preview-Token hinzu, den deine Redakteure tragen. Die meisten Teams liefern eine separate /preview/[slug]-Route, die Entwurfsinhalte hinter einem Login-Gate holt.

Wie rendere ich Markdown, das die API zurückgibt?

Wähle einen Markdown-Parser, der zu deinem Runtime passt. Für React funktioniert react-markdown. Für Vue vue-markdown-render. Für Svelte svelte-markdown. Für Astro die eingebaute Komponente. Das CMS sollte rohes Markdown zurückgeben, damit jedes Frontend es nach seinen Vorlieben sanitisieren kann.

Wie unterscheidet sich das von Contentful oder Sanity?

Contentful und Sanity exponieren beide REST-Endpoints, also funktioniert das Fetch-Muster oben auch gegen sie. Die Unterschiede liegen im Preismodell und in der operativen Oberfläche. Kamaan berechnet pauschal 19 Dollar pro Monat für unbegrenzte Sites und gibt dir KI-Orchestrierung über MCP, sodass du jede Blog-Operation aus Claude, ChatGPT oder Cursor ausführen kannst.

Weiterführend auf Kamaan

Mit Kamaan loslegen

Kamaan ist die Kommandozentrale für Multi-Product-Gründer und Agenturen, die viele SaaS-Blogs betreiben: verwalte jeden Blog aus einem Dashboard und führe jede Operation über alle hinweg aus Claude, ChatGPT, Cursor oder jedem MCP-Client aus. Auto-Multilingual Delivery bedeutet, dass eine Übersetzung auf jeder Locale automatisch erscheint, wenn du veröffentlichst. Multi-Site Management bedeutet ein Konto, eine Rechnung, jeder Blog, den du betreibst. Die in diesem Artikel gezeigte REST API Delivery hat dieselbe Form über jede Site in deinem Konto.

Der Preis liegt bei 19 Dollar pro Monat, pauschal, unbegrenzte Sites, keine Gebühren pro Site, pro Space oder pro Sitz. Der erste Monat ist gratis, keine Kreditkarte zum Start, jederzeit kündbar. Ein Lifetime-Plan ist verfügbar, wenn du lieber einmal zahlen willst. Probier es bei deinem nächsten Blog aus und behalte den Fetch-Code, den du bereits geschrieben hast.

Frequently asked

FAQ · 8 ITEMS
Was ist eine Blog API?

Eine Blog API ist ein HTTP-Endpoint, der Blogartikel als strukturierte Daten zurückgibt, in der Regel JSON. Dein Frontend-Code ruft den Endpoint auf, empfängt die Artikel und rendert sie, wie du willst. Das CMS kümmert sich um Speicherung, Bearbeitung und Veröffentlichung. Das Frontend kümmert sich um die Darstellung.

Brauche ich ein anbieterspezifisches SDK, um eine Blog API zu nutzen?

Nein. Die in jedem modernen JavaScript-Runtime eingebaute native Fetch-Funktion reicht. SDKs können Komfort hinzufügen (typisierte Antworten, Retry-Logik, Bildtransformationen), aber sie binden dich auch. Ein REST-Endpoint, der einfaches JSON zurückgibt, funktioniert mit jedem Framework, in jedem Jahr, in jeder Version.

Kann dieselbe Blog API mehrere Frontends bedienen?

Ja. Das ist der Sinn von Headless. Du kannst dieselben Artikel auf einer Next.js-Marketing-Site, einer Astro-Doku-Site und einem React-Dashboard gleichzeitig rendern, alle aus einem Endpoint. Dem CMS ist es egal, wie der Inhalt gerendert wird.

Wie behandle ich Übersetzungen aus einer Blog API?

Suche ein CMS, das Übersetzungen als separate Artikelobjekte zurückgibt, mit der Quelle über ein Parent-Feld verknüpft. Kamaan nutzt `parent_article_id`. Um die deutsche Version zu holen, übergib `language=de` an demselben Articles-Endpoint. Vermeide CMS, die Übersetzungen in ein einzelnes Artikelobjekt verschachteln, weil das jedes Frontend zwingt, die Locale-Logik zu parsen.

Soll ich Antworten der Blog API cachen?

Ja, in fast jedem Fall. Marketing-Blog-Inhalte ändern sich nicht oft. Für Static-Export-Frameworks wie Astro oder Next.js mit Revalidate findet der Fetch zur Build-Zeit oder in einem langen Intervall statt. Für SSR-Frameworks ist ein Cache von 5 bis 10 Minuten meist sicher. Überspringe den Cache nur, wenn Vorschau-Entwürfe für eingeloggte Redakteure sofort erscheinen sollen.

Was ist mit Vorschau-Entwürfen?

Übergib `status=draft` und füge einen Auth-Header oder einen Preview-Token hinzu, den deine Redakteure tragen. Die meisten Teams liefern eine separate `/preview/[slug]`-Route, die Entwurfsinhalte hinter einem Login-Gate holt.

Wie rendere ich Markdown, das die API zurückgibt?

Wähle einen Markdown-Parser, der zu deinem Runtime passt. Für React funktioniert `react-markdown`. Für Vue `vue-markdown-render`. Für Svelte `svelte-markdown`. Für Astro die eingebaute Komponente. Das CMS sollte rohes Markdown zurückgeben, damit jedes Frontend es nach seinen Vorlieben sanitisieren kann.

Wie unterscheidet sich das von Contentful oder Sanity?

Contentful und Sanity exponieren beide REST-Endpoints, also funktioniert das Fetch-Muster oben auch gegen sie. Die Unterschiede liegen im Preismodell und in der operativen Oberfläche. Kamaan berechnet pauschal 19 Dollar pro Monat für unbegrenzte Sites und gibt dir KI-Orchestrierung über MCP, sodass du jede Blog-Operation aus Claude, ChatGPT oder Cursor ausführen kannst.

Junaid Khalid
Written by
Junaid Khalid

Junaid Khalid is the founder of Kamaan, a headless blog CMS that auto-publishes in five languages and lets you manage every product blog from one dashboard.