frontend.blogwoman.de/CLAUDE.md
CCS Admin f92601a1d4 docs: add contracts package reference to CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:11:10 +00:00

8.1 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

BlogWoman.de frontend - a Next.js 16 application consuming Payload CMS as a headless backend. This is a multi-tenant system where Tenant ID 9 (slug: blogwoman) is the target tenant.

Tech Stack: Next.js 16, React 19, TypeScript, Tailwind CSS 4 Backend API: https://cms.c2sgmbh.de/api (Production) Package Manager: pnpm

Commands

pnpm dev          # Development server (localhost:3000)
pnpm build        # Production build
pnpm start        # Start production server
pnpm lint         # ESLint

Environment Variables

Create .env.local:

NEXT_PUBLIC_PAYLOAD_URL=https://cms.c2sgmbh.de
NEXT_PUBLIC_API_URL=https://cms.c2sgmbh.de/api
NEXT_PUBLIC_TENANT_ID=9
NEXT_PUBLIC_TENANT_SLUG=blogwoman
NEXT_PUBLIC_SITE_URL=https://blogwoman.de
NEXT_PUBLIC_UMAMI_HOST=https://analytics.c2sgmbh.de
NEXT_PUBLIC_UMAMI_WEBSITE_ID=<website-id>

Shared Contracts Package

This project uses @c2s/payload-contracts for the API client layer.

Architecture:

  • src/lib/cms.ts — Shared PayloadClient instance (tenant: blogwoman, ID: 9)
  • src/lib/api.ts — API functions powered by contracts client
  • src/lib/types.ts — Local type aliases (simplified for component compatibility)

Contracts Repo: github:complexcaresolutions/payload-contracts

// How the API client works (src/lib/cms.ts)
import { createPayloadClient } from "@c2s/payload-contracts/api-client"
export const cms = createPayloadClient({
  baseUrl: process.env.NEXT_PUBLIC_PAYLOAD_URL!,
  tenantId: process.env.NEXT_PUBLIC_TENANT_ID!,
})

// Usage in api.ts — tenant isolation is automatic
const page = await cms.pages.getPage("home")
const posts = await cms.posts.getPosts({ type: "blog", limit: 10 })
const nav = await cms.navigation.getNavigation("header")

Type Bridge: Local types in types.ts use simplified interfaces (e.g., meta instead of seo). The api.ts bridges between contracts types and local types via as unknown as. This will be cleaned up when components are aligned with real CMS types.

Block Catalog: See node_modules/@c2s/payload-contracts/docs/BLOCK_CATALOG.md for all 43 block definitions.

Updating Contracts:

pnpm update @c2s/payload-contracts
# Check for work orders in node_modules/@c2s/payload-contracts/work-orders/

Architecture

Directory Structure

src/
├── app/                    # Next.js App Router
│   ├── layout.tsx          # Root layout (Header/Footer/Analytics)
│   ├── page.tsx            # Home page
│   ├── [slug]/page.tsx     # Dynamic pages from Payload
│   ├── blog/               # Blog routes
│   ├── serien/             # BlogWoman YouTube series pages
│   └── favoriten/          # BlogWoman affiliate products
├── components/
│   ├── layout/             # Header, Footer, Navigation, MobileMenu
│   ├── blocks/             # CMS block components (see Block System below)
│   ├── ui/                 # Reusable UI components
│   └── analytics/          # UmamiScript
├── lib/
│   ├── api.ts              # Payload API client functions
│   ├── types.ts            # TypeScript types
│   └── structuredData.ts   # JSON-LD helpers for SEO
└── hooks/
    └── useAnalytics.ts     # Umami event tracking

API Pattern - CRITICAL

Every API call MUST include tenant filtering:

const PAYLOAD_URL = process.env.NEXT_PUBLIC_PAYLOAD_URL
const TENANT_ID = process.env.NEXT_PUBLIC_TENANT_ID

// CORRECT - always filter by tenant
fetch(`${PAYLOAD_URL}/api/pages?where[tenant][equals]=${TENANT_ID}&where[slug][equals]=about`)

// WRONG - will return 403 or empty results
fetch(`${PAYLOAD_URL}/api/pages?where[slug][equals]=about`)

Block System

Pages from Payload contain a layout array of blocks. Each block has a blockType field:

Block Type Purpose
hero-block Hero banner with image
hero-slider-block Multi-slide hero carousel
text-block Rich text content
image-text-block Image + text side-by-side
card-grid-block Card grid layout
cta-block Call-to-action section
posts-list-block Blog/news listing
testimonials-block Customer testimonials
faq-block FAQ accordion (with JSON-LD)
newsletter-block Newsletter signup form
contact-form-block Contact form
video-block Video embed
favorites-block Affiliate products (BlogWoman)
series-block YouTube series overview (BlogWoman)
series-detail-block Series hero (BlogWoman)
video-embed-block Privacy-mode video embed

Block Renderer pattern:

// src/components/blocks/index.tsx
export function BlockRenderer({ blocks }) {
  return blocks.map(block => {
    const Component = blockComponents[block.blockType]
    return Component ? <Component {...block} /> : null
  })
}

BlogWoman-Specific Collections

Beyond standard CMS collections (pages, posts, testimonials), BlogWoman uses:

  • favorites - Affiliate products with categories (fashion, beauty, travel, tech, home) and badges (investment-piece, daily-driver, grfi-approved, new, bestseller)
  • series - YouTube series with branding (logo, cover image, brand color)

API Endpoints Reference

Endpoint Purpose
GET /api/pages?where[tenant][equals]=9 Fetch pages
GET /api/posts?where[tenant][equals]=9 Fetch blog posts
GET /api/navigations?where[tenant][equals]=9&where[type][equals]=header Get navigation
GET /api/site-settings?where[tenant][equals]=9 Site configuration
GET /api/favorites?where[tenant][equals]=9 Affiliate products
GET /api/series?where[tenant][equals]=9 YouTube series
POST /api/newsletter/subscribe Newsletter signup (body: email, tenantId, source)
POST /api/form-submissions Contact form submission

API Documentation: https://cms.c2sgmbh.de/api/docs (Swagger UI)

Design System (Styleguide)

Philosophy: "Editorial Warmth" - Premium but approachable, like a lifestyle magazine.

Colors (60/30/10 Rule)

Name Hex Use
Ivory #F7F3EC Backgrounds (60%)
Sand #C6A47E Cards, modules (30%)
Espresso #2B2520 Text, headlines
Brass #B08D57 Primary buttons, highlights (10%)
Bordeaux #6B1F2B Accent for P&L series
Rosé #D4A5A5 SPARK series accent
Gold #C9A227 Premium badges
Soft White #FBF8F3 Cards, surfaces
Warm Gray #DDD4C7 Borders

Forbidden: Neon colors, pure black (#000), pure white (#FFF), cold blue.

Typography

  • Headlines: Playfair Display (600 weight)
  • Body/UI: Inter (400, 500, 600)
  • NO CAPSLOCK HEADLINES - use uppercase only for small labels with letter-spacing

Series Pills (BlogWoman)

YouTube series use color-coded pills:

  • GRFI: Sand background
  • Investment: Brass background
  • P&L: Bordeaux background
  • SPARK: Rosé background
  • Inner Circle: Gold background

SEO Requirements

  1. Meta tags from page.meta field
  2. JSON-LD for Organization, FAQPage, Article schemas
  3. Open Graph tags for social sharing
  4. Sitemap available at: https://cms.c2sgmbh.de/sitemap.xml

Analytics (Umami)

Umami is cookieless and DSGVO-compliant - runs without consent banner.

// Track custom events
import { useAnalytics } from '@/hooks/useAnalytics'
const { trackEvent, trackNewsletterSubscribe, trackAffiliateClick } = useAnalytics()

Documentation References

Document Path
Styleguide /docs/guides/styleguide.md
Universal Features /docs/architecture/UNIVERSAL_FEATURES.md
API Guide /docs/api/API_ANLEITUNG.md
SEO /docs/guides/SEO_ERWEITERUNG.md
Analytics /docs/architecture/Analytics.md
Frontend Guide /docs/guides/FRONTEND.md
Development Prompt /prompts/2026-01-20_blogwoman-frontend-entwicklung.md

Import Alias

@/* maps to ./src/* (configured in tsconfig.json)