frontend.blogwoman.de/prompts/ANLEITUNG-PLANUNGS-KI-FRONTEND.md
CCS Admin dcfc48f5ce Add documentation and BlogWoman frontend development prompt
- Add API documentation (API_ANLEITUNG.md)
- Add architecture docs (UNIVERSAL_FEATURES.md, Analytics.md)
- Add guides (FRONTEND.md, SEO_ERWEITERUNG.md, styleguide.md)
- Add Planungs-KI prompt template (ANLEITUNG-PLANUNGS-KI-FRONTEND.md)
- Add BlogWoman frontend development prompt with:
  - Tenant-ID 9 configuration
  - Design system based on styleguide
  - BlogWoman-specific blocks (Favorites, Series, VideoEmbed)
  - API patterns with tenant isolation
  - SEO and Analytics integration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 21:24:13 +00:00

730 lines
19 KiB
Markdown

# Anleitung: Frontend-Prompt-Erstellung für Payload CMS
*Für Planungs-KIs zur Erstellung von Entwicklungs-Prompts*
---
## Übersicht
Diese Anleitung erklärt, wie du als Planungs-KI einen strukturierten Prompt für die Entwicklung eines Next.js-Frontends erstellst, das Daten aus einem Payload CMS über die REST-API bezieht.
### Architektur-Kontext
```
┌─────────────────────────────────────────────────────────────────┐
│ ARCHITEKTUR │
│ │
│ ┌──────────────────┐ ┌──────────────────────────────┐ │
│ │ PAYLOAD CMS │ │ NEXT.JS FRONTEND │ │
│ │ (Headless) │ REST │ │ │
│ │ │◄────────►│ • Server Components │ │
│ │ cms.c2sgmbh.de │ API │ • Client Components │ │
│ │ /api/* │ │ • API Routes │ │
│ └──────────────────┘ └──────────────────────────────┘ │
│ │
│ Tech-Stack: │
│ • Payload CMS 3.69.0 • Next.js 15.5.9 │
│ • PostgreSQL 17 • React 19.2.3 │
│ • Multi-Tenant-fähig • TypeScript │
│ • Lokalisierung: DE/EN • Tailwind CSS │
└─────────────────────────────────────────────────────────────────┘
```
---
## Teil 1: Benötigte Dateien für die Planungs-KI
### Pflicht-Dateien (unbedingt bereitstellen)
| Datei | Zweck | Wo erhältlich |
|-------|-------|---------------|
| **OpenAPI Spec** | Vollständige API-Dokumentation mit allen Endpoints, Schemas und Parametern | `https://cms.c2sgmbh.de/api/openapi.json` |
| **FRONTEND.md** | Umgebungskonfiguration, API-URLs, Development-Workflow | Projektdokumentation |
| **API_ANLEITUNG.md** | Authentifizierung, Rate-Limits, Collection-Übersicht | Projektdokumentation |
### Empfohlene Zusatz-Dateien
| Datei | Zweck |
|-------|-------|
| **UNIVERSAL_FEATURES.md** | Block-Typen, Collection-Felder, Layout-Optionen |
| **KONZEPT-KI-ANLEITUNG.md** | Block-Konfigurationen mit JSON-Beispielen |
| **payload-types.ts** | TypeScript-Typen für alle Collections (generiert aus Payload) |
### Optional für komplexe Projekte
| Datei | Zweck |
|-------|-------|
| **Analytics.md** | Umami-Integration, Event-Tracking |
| **SEO_ERWEITERUNG.md** | SEO-Konfiguration, Meta-Tags, Structured Data |
---
## Teil 2: API-Struktur verstehen
### Basis-URLs
```
Production API: https://cms.c2sgmbh.de/api
Development API: https://pl.porwoll.tech/api
Swagger UI: https://cms.c2sgmbh.de/api/docs
OpenAPI JSON: https://cms.c2sgmbh.de/api/openapi.json
```
### Tenant-System (Multi-Mandanten)
**Kritisch:** Jeder API-Call muss den Tenant filtern!
```typescript
// RICHTIG: Mit Tenant-Filter
const response = await fetch(
'https://cms.c2sgmbh.de/api/pages?where[tenant][equals]=4&where[slug][equals]=home'
)
// FALSCH: Ohne Tenant → 403 Forbidden oder leere Ergebnisse
const response = await fetch(
'https://cms.c2sgmbh.de/api/pages?where[slug][equals]=home'
)
```
### Tenant-IDs
| ID | Name | Slug | Domain |
|----|------|------|--------|
| 1 | porwoll.de | porwoll | porwoll.de |
| 4 | Complex Care Solutions GmbH | c2s | complexcaresolutions.de |
| 5 | Gunshin | gunshin | gunshin.de |
| ... | (weitere Tenants) | ... | ... |
### Lokalisierung
```typescript
// Deutsche Inhalte (Standard)
fetch('/api/posts?locale=de')
// Englische Inhalte
fetch('/api/posts?locale=en')
// Alle Sprachen gleichzeitig
fetch('/api/posts?locale=all')
```
---
## Teil 3: Collections-Referenz
### Core Collections
| Collection | Slug | Beschreibung | Öffentlich |
|------------|------|--------------|------------|
| Pages | `pages` | Seiten mit Block-Layouts | Ja |
| Media | `media` | Bilder, Dokumente (11 responsive Sizes) | Ja |
| Tenants | `tenants` | Mandanten-Verwaltung | Nein |
| Users | `users` | Benutzer mit Tenant-Zuordnung | Nein |
### Content Collections
| Collection | Slug | Beschreibung |
|------------|------|--------------|
| Posts | `posts` | Blog, News, Presse, Ankündigungen |
| Categories | `categories` | Kategorien für Posts |
| Tags | `tags` | Tags für Posts |
| Authors | `authors` | Autoren für Posts |
| Testimonials | `testimonials` | Kundenbewertungen |
| FAQs | `faqs` | Häufig gestellte Fragen |
| Team | `team` | Team-Mitglieder |
| Services | `services` | Leistungen/Dienstleistungen |
| Service Categories | `service-categories` | Kategorien für Services |
### Portfolio & Media
| Collection | Slug | Beschreibung |
|------------|------|--------------|
| Portfolios | `portfolios` | Portfolio-Galerien |
| Portfolio Categories | `portfolio-categories` | Kategorien |
| Videos | `videos` | Video-Bibliothek (YouTube/Vimeo/Upload) |
| Video Categories | `video-categories` | Kategorien |
### Kommunikation
| Collection | Slug | Beschreibung |
|------------|------|--------------|
| Newsletter Subscribers | `newsletter-subscribers` | Abonnenten (DSGVO) |
| Form Submissions | `form-submissions` | Formular-Eingaben |
| Contact Requests | `contact-requests` | Kontaktanfragen |
### Konfiguration
| Collection | Slug | Beschreibung |
|------------|------|--------------|
| Site Settings | `site-settings` | Logo, Farben, SEO-Defaults |
| Navigations | `navigations` | Header, Footer, Mobile-Nav |
| Cookie Configurations | `cookie-configurations` | Cookie-Banner-Settings |
| Redirects | `redirects` | URL-Weiterleitungen |
---
## Teil 4: Block-Typen für Pages
Die `pages` Collection verwendet ein Block-basiertes Layout-System. Jede Page hat ein `layout`-Array mit Blocks.
### Verfügbare Block-Typen
#### Layout-Blocks
| Block | Slug | Beschreibung |
|-------|------|--------------|
| Hero | `hero-block` | Hauptbanner mit Bild, Text, CTA |
| Hero Slider | `hero-slider-block` | Karussell mit mehreren Slides |
| Text | `text-block` | Rich-Text-Inhalt (Lexical) |
| Image-Text | `image-text-block` | Bild + Text nebeneinander |
| Card Grid | `card-grid-block` | Karten im Grid-Layout |
| CTA | `cta-block` | Call-to-Action Sektion |
| Divider | `divider-block` | Visueller Trenner |
#### Content-Blocks (laden Collection-Daten)
| Block | Slug | Datenquelle |
|-------|------|-------------|
| Posts List | `posts-list-block` | Posts Collection |
| Testimonials | `testimonials-block` | Testimonials Collection |
| FAQ | `faq-block` | FAQs Collection |
| Team | `team-block` | Team Collection |
| Services | `services-block` | Services Collection |
| Newsletter | `newsletter-block` | Newsletter-Anmeldung |
#### Interaktive Blocks
| Block | Slug | Beschreibung |
|-------|------|--------------|
| Contact Form | `contact-form-block` | Kontaktformular |
| Timeline | `timeline-block` | Chronologische Darstellung |
| Process Steps | `process-steps-block` | Prozess-Visualisierung |
| Video | `video-block` | Video-Einbettung |
### Block-Konfiguration Beispiele
```json
// Hero Block
{
"blockType": "hero-block",
"heading": "Willkommen",
"subheading": "Untertitel",
"backgroundImage": "<media-id>",
"ctaText": "Mehr erfahren",
"ctaLink": "/ueber-uns",
"alignment": "center",
"overlay": true,
"overlayOpacity": 0.5
}
// Posts List Block
{
"blockType": "posts-list-block",
"heading": "Neueste Artikel",
"type": "blog",
"categories": ["<category-id>"],
"limit": 6,
"layout": "grid",
"showPagination": true
}
// FAQ Block
{
"blockType": "faq-block",
"heading": "Häufige Fragen",
"displayMode": "selected",
"selectedFaqs": ["<faq-id-1>", "<faq-id-2>"],
"layout": "accordion",
"expandFirst": true,
"showSchema": true
}
// Testimonials Block
{
"blockType": "testimonials-block",
"heading": "Kundenstimmen",
"displayMode": "all",
"limit": 6,
"layout": "slider"
}
```
---
## Teil 5: API-Patterns für Frontend
### Seite laden
```typescript
// lib/api.ts
const PAYLOAD_URL = process.env.NEXT_PUBLIC_PAYLOAD_URL
const TENANT_ID = process.env.NEXT_PUBLIC_TENANT_ID
export async function getPage(slug: string, locale = 'de') {
const res = await fetch(
`${PAYLOAD_URL}/api/pages?` +
`where[tenant][equals]=${TENANT_ID}&` +
`where[slug][equals]=${slug}&` +
`where[status][equals]=published&` +
`locale=${locale}&` +
`depth=2`,
{ next: { revalidate: 60 } }
)
const data = await res.json()
return data.docs[0] || null
}
```
### Posts laden
```typescript
export async function getPosts(options: {
type?: 'blog' | 'news' | 'press'
category?: string
limit?: number
page?: number
locale?: string
}) {
const params = new URLSearchParams({
'where[tenant][equals]': TENANT_ID,
'where[status][equals]': 'published',
'sort': '-publishedAt',
'limit': String(options.limit || 10),
'page': String(options.page || 1),
'locale': options.locale || 'de',
'depth': '1'
})
if (options.type) {
params.append('where[type][equals]', options.type)
}
if (options.category) {
params.append('where[categories][contains]', options.category)
}
const res = await fetch(`${PAYLOAD_URL}/api/posts?${params}`)
return res.json()
}
```
### Navigation laden
```typescript
export async function getNavigation(type: 'header' | 'footer' | 'mobile') {
const res = await fetch(
`${PAYLOAD_URL}/api/navigations?` +
`where[tenant][equals]=${TENANT_ID}&` +
`where[type][equals]=${type}&` +
`depth=2`
)
const data = await res.json()
return data.docs[0] || null
}
```
### Site Settings laden
```typescript
export async function getSiteSettings() {
const res = await fetch(
`${PAYLOAD_URL}/api/site-settings?` +
`where[tenant][equals]=${TENANT_ID}&` +
`depth=2`
)
const data = await res.json()
return data.docs[0] || null
}
```
### Newsletter-Anmeldung
```typescript
export async function subscribeNewsletter(email: string, firstName?: string) {
const res = await fetch(`${PAYLOAD_URL}/api/newsletter/subscribe`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email,
firstName,
tenantId: Number(TENANT_ID),
source: 'website'
})
})
return res.json()
}
```
### Kontaktformular
```typescript
export async function submitContactForm(data: {
name: string
email: string
phone?: string
subject: string
message: string
}) {
const res = await fetch(`${PAYLOAD_URL}/api/form-submissions`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
form: 1, // Form-ID aus Payload
submissionData: [
{ field: 'name', value: data.name },
{ field: 'email', value: data.email },
{ field: 'phone', value: data.phone || '' },
{ field: 'subject', value: data.subject },
{ field: 'message', value: data.message }
]
})
})
return res.json()
}
```
---
## Teil 6: Prompt-Struktur für Frontend-Entwicklung
### Template
```markdown
# Frontend [Projektname] - Entwicklungs-Prompt
## Kontext
**Projektverzeichnis:** /pfad/zum/frontend
**Tech-Stack:** Next.js 15.5.9, React 19.2.3, TypeScript, Tailwind CSS
**API-Basis:** https://cms.c2sgmbh.de/api
**Tenant-ID:** [ID]
**Tenant-Slug:** [slug]
**Domain:** [domain.de]
### Referenz-Dokumente
- OpenAPI Spec: [Pfad oder URL zur openapi.json]
- Payload Types: [Pfad zur payload-types.ts]
---
## Environment Variables
```env
NEXT_PUBLIC_PAYLOAD_URL=https://cms.c2sgmbh.de
NEXT_PUBLIC_API_URL=https://cms.c2sgmbh.de/api
NEXT_PUBLIC_TENANT_ID=[ID]
NEXT_PUBLIC_TENANT_SLUG=[slug]
NEXT_PUBLIC_SITE_URL=https://[domain.de]
# Analytics (optional)
NEXT_PUBLIC_UMAMI_HOST=https://analytics.c2sgmbh.de
NEXT_PUBLIC_UMAMI_WEBSITE_ID=[website-id]
```
---
## Aufgaben
### 1. Projektstruktur
```
src/
├── app/
│ ├── layout.tsx # Root-Layout mit Header/Footer
│ ├── page.tsx # Startseite
│ ├── [slug]/
│ │ └── page.tsx # Dynamische Seiten
│ ├── blog/
│ │ ├── page.tsx # Blog-Übersicht
│ │ └── [slug]/
│ │ └── page.tsx # Blog-Artikel
│ └── api/ # Optional: Proxy-Routes
├── components/
│ ├── layout/
│ │ ├── Header.tsx
│ │ ├── Footer.tsx
│ │ └── Navigation.tsx
│ ├── blocks/ # Block-Komponenten (je Block)
│ │ ├── HeroBlock.tsx
│ │ ├── TextBlock.tsx
│ │ ├── ImageTextBlock.tsx
│ │ ├── CardGridBlock.tsx
│ │ ├── PostsListBlock.tsx
│ │ ├── TestimonialsBlock.tsx
│ │ ├── FAQBlock.tsx
│ │ ├── TeamBlock.tsx
│ │ ├── ServicesBlock.tsx
│ │ ├── NewsletterBlock.tsx
│ │ ├── CTABlock.tsx
│ │ ├── ContactFormBlock.tsx
│ │ └── index.tsx # Block-Renderer
│ └── ui/ # Wiederverwendbare UI-Komponenten
├── lib/
│ ├── api.ts # API-Funktionen
│ ├── utils.ts # Hilfsfunktionen
│ └── types.ts # TypeScript-Typen
└── styles/
└── globals.css # Tailwind + Custom Styles
```
### 2. API-Integration
#### 2.1 API-Client erstellen
**Datei:** `src/lib/api.ts`
Implementiere Funktionen für:
- `getPage(slug, locale)` - Seite laden
- `getPosts(options)` - Blog-Posts laden
- `getNavigation(type)` - Navigation laden
- `getSiteSettings()` - Site-Settings laden
- `getCategories()` - Kategorien laden
- `subscribeNewsletter(email, firstName)` - Newsletter
- `submitForm(formId, data)` - Formular absenden
**Wichtig:**
- Immer `where[tenant][equals]=${TENANT_ID}` mitgeben
- Caching mit `next: { revalidate: 60 }` für statische Daten
- Error-Handling implementieren
### 3. Block-Komponenten
Für jeden Block-Typ eine React-Komponente erstellen.
#### 3.1 Block-Renderer
**Datei:** `src/components/blocks/index.tsx`
```typescript
import { HeroBlock } from './HeroBlock'
import { TextBlock } from './TextBlock'
// ... weitere Imports
const blockComponents = {
'hero-block': HeroBlock,
'text-block': TextBlock,
'image-text-block': ImageTextBlock,
// ... weitere Mappings
}
export function BlockRenderer({ blocks }) {
return (
<>
{blocks?.map((block, index) => {
const Component = blockComponents[block.blockType]
if (!Component) return null
return <Component key={index} {...block} />
})}
</>
)
}
```
#### 3.2 [Block-Name] Block
**Datei:** `src/components/blocks/[BlockName]Block.tsx`
[Für jeden benötigten Block beschreiben:]
- Props-Interface (aus API-Response)
- Tailwind-Styling
- Responsive Verhalten
- Interaktivität (falls Client Component)
### 4. Seiten
#### 4.1 Layout
**Datei:** `src/app/layout.tsx`
- Header mit Navigation laden
- Footer mit Navigation laden
- Site-Settings für Meta-Tags
- Cookie-Banner (DSGVO)
#### 4.2 Dynamische Seiten
**Datei:** `src/app/[slug]/page.tsx`
- Seite aus API laden
- Metadata generieren
- BlockRenderer für Layout
- 404 bei nicht gefundener Seite
### 5. SEO & Meta
- `generateMetadata()` für jede Seite
- Open Graph Tags
- JSON-LD für FAQ-Blocks (Schema.org)
- Sitemap aus `/api/sitemap.xml`
- robots.txt
### 6. Cookie-Banner
- Cookie-Konfiguration aus API laden
- Consent-State in localStorage
- Consent an Backend loggen
- Analytics erst nach Consent laden
---
## Erfolgskriterien
- [ ] `pnpm lint` ohne Errors
- [ ] `pnpm build` erfolgreich
- [ ] Alle Block-Typen gerendert
- [ ] Navigation funktioniert
- [ ] Blog-Übersicht und Detailseiten
- [ ] Kontaktformular sendet Daten
- [ ] Newsletter-Anmeldung funktioniert
- [ ] SEO-Meta-Tags korrekt
- [ ] Mobile-responsive
- [ ] Lighthouse Score > 90
---
## Escape Hatch
Nach 15 Iterationen ohne Fortschritt:
- Dokumentiere Blocker in BLOCKERS.md
- Liste versuchte Lösungen auf
- Output <promise>BLOCKED</promise>
---
## Fertig?
Wenn ALLE Aufgaben erledigt sind:
<promise>FRONTEND_COMPLETE</promise>
```
---
## Teil 7: Checkliste für Planungs-KI
### Vor der Prompt-Erstellung
- [ ] OpenAPI Spec liegt vor (`openapi.json`)
- [ ] Tenant-ID und Slug bekannt
- [ ] Domain(s) bekannt
- [ ] Design-Vorgaben/Mockups vorhanden (optional)
- [ ] Block-Typen für Seiten definiert
### Im Prompt enthalten
- [ ] Projektverzeichnis angegeben
- [ ] Tech-Stack spezifiziert
- [ ] Environment Variables definiert
- [ ] API-Patterns mit Tenant-Filter
- [ ] Alle benötigten Block-Komponenten gelistet
- [ ] Seiten-Struktur beschrieben
- [ ] Erfolgskriterien messbar formuliert
- [ ] Escape Hatch für Blockaden
- [ ] Promise-Token am Ende
### Dateien zur Übergabe an Entwicklungs-KI
1. **PROMPT.md** - Dein erstellter Prompt
2. **openapi.json** - API-Spezifikation
3. **payload-types.ts** - TypeScript-Typen (falls verfügbar)
4. **Design-Assets** - Mockups, Styleguide (falls vorhanden)
---
## Teil 8: Beispiel-Prompt (Kurzversion)
```markdown
# Frontend porwoll.de - Phase 1
## Kontext
- **Verzeichnis:** /home/frontend/porwoll.de
- **API:** https://cms.c2sgmbh.de/api
- **Tenant-ID:** 1
- **Referenz:** /docs/openapi.json
## Aufgaben
### 1. Setup
- Next.js 15 Projekt initialisieren
- Tailwind CSS konfigurieren
- Environment Variables setzen
### 2. API-Client
- `src/lib/api.ts` mit allen Fetch-Funktionen
- Tenant-Filter in jedem Call
### 3. Blocks
Komponenten für:
- HeroBlock
- TextBlock
- ImageTextBlock
- PostsListBlock
- FAQBlock
- NewsletterBlock
- CTABlock
- ContactFormBlock
### 4. Seiten
- `/` - Startseite
- `/[slug]` - Dynamische Seiten
- `/blog` - Blog-Übersicht
- `/blog/[slug]` - Blog-Artikel
### 5. Layout
- Header mit Navigation
- Footer mit Navigation
- Cookie-Banner
## Erfolgskriterien
- [ ] Build erfolgreich
- [ ] Alle Blocks rendern
- [ ] API-Calls funktionieren
## Fertig?
<promise>PHASE1_DONE</promise>
```
---
## Anhang: API Query-Parameter Referenz
### Filtering (where)
```
where[field][equals]=value
where[field][not_equals]=value
where[field][contains]=value
where[field][in]=value1,value2
where[field][greater_than]=value
where[field][less_than]=value
where[field][exists]=true
```
### Sorting
```
sort=fieldName # Aufsteigend
sort=-fieldName # Absteigend
```
### Pagination
```
limit=10 # Ergebnisse pro Seite
page=1 # Seitennummer
```
### Depth (Relations)
```
depth=0 # Keine Relations laden
depth=1 # Eine Ebene Relations
depth=2 # Zwei Ebenen (Default)
```
### Lokalisierung
```
locale=de # Deutsche Inhalte
locale=en # Englische Inhalte
locale=all # Alle Sprachen
```
---
*Anleitung erstellt: Januar 2026*
*Für: Complex Care Solutions GmbH - Payload CMS Multi-Tenant*