Theme
Integration: Nuxt 3
Status: Produktiv seit 2026-05-20. Funktioniert mit Nuxt 3.x und der Nuxt-Bridge.
60-Sekunden-Setup
bash
# In deinem Nuxt-Projekt:
npx @peacock/cli init nuxtWas passiert:
- Erkennung:
nuxt.config.{js,mjs,ts}odernuxtinpackage.json. .env: FügtNUXT_PUBLIC_PEACOCK_API_BASE_URL,NUXT_PUBLIC_PEACOCK_SPACE,NUXT_PEACOCK_TOKENidempotent hinzu.pages/[...slug].vuewird scaffold-iert mituseAsyncData+ serverseitigem Fetch.- Druckt den Install-Befehl für dein erkanntes Package-Manager.
Manuell danach:
bash
pnpm add @peacock/sdk-js
# .env mit echten Werten füllen
pnpm devnuxt.config.ts
Füge die runtimeConfig-Sektion hinzu — Nuxt liest dann NUXT_*-Env-Vars automatisch:
ts
export default defineNuxtConfig({
runtimeConfig: {
peacockToken: '', // gefüllt von NUXT_PEACOCK_TOKEN (server-only)
public: {
peacockApiBaseUrl: '', // gefüllt von NUXT_PUBLIC_PEACOCK_API_BASE_URL
peacockSpace: '', // gefüllt von NUXT_PUBLIC_PEACOCK_SPACE
},
},
});Schlüssel ohne public:-Wrapping sind server-only und nie im Client-Bundle.
Generierte Sample-Page
pages/[...slug].vue:
vue
<script setup lang="ts">
import { makeApi } from '@peacock/sdk-js';
const route = useRoute();
const config = useRuntimeConfig();
const slugSegments = (route.params['slug'] ?? []) as string[];
const path = '/' + slugSegments.join('/');
const { data: story, error } = await useAsyncData(
`story-${path}`,
async () => {
const api = makeApi(config.peacockToken as string, {
baseUrl: config.public.peacockApiBaseUrl as string,
});
const result = await api.cdnStory(config.public.peacockSpace as string, path);
if (result.status !== 'ok') {
throw createError({ statusCode: 404, statusMessage: 'Story not found' });
}
return result.data.data;
},
);
if (error.value) throw error.value;
</script>
<template>
<main>
<pre>{{ story?.content }}</pre>
</main>
</template>Der Fetch passiert serverseitig beim ersten Request (useAsyncData), Nuxt hydratet den Client mit dem Ergebnis — kein zusätzlicher API-Roundtrip im Browser.
Eigene Block-Renderer
Map jeden _component auf eine Vue-Komponente:
vue
<script setup lang="ts">
import Hero from '~/components/peacock/Hero.vue';
import FAQ from '~/components/peacock/FAQ.vue';
import TextImage from '~/components/peacock/TextImage.vue';
const blockMap: Record<string, Component> = {
hero: Hero,
faq: FAQ,
text_image: TextImage,
};
</script>
<template>
<component
v-for="(block, i) in (story?.content.body as any[])"
:key="i"
:is="blockMap[block._component] ?? 'div'"
v-bind="block"
/>
</template>Caching & Performance
useAsyncData cached den ersten Server-Fetch in den payload.json der Page — Folge-Navigationen via Nuxt-Router lösen keinen erneuten Peacock-Call aus. Bei force: true (z.B. nach Webhook) wird neu geholt.
Für Edge-Deploys (Cloudflare Pages mit Nitro-Preset cloudflare): der cdnStory()-Endpoint setzt ETag + Cache-Control: max-age=60, stale-while-revalidate=300, also bekommst du SWR-Caching gratis.
Was noch fehlt
- Dedicated
@peacock/nuxt-Modul: Phase-9-Polish (auto-imports, devtools-tab). Heute ist das SDK-Pattern oben vollständig funktional.