payload-contracts/docs/FRONTEND_CONVENTIONS.md
Martin Porwoll 715783dbf3 docs: add frontend conventions, CI/CD templates, and deployment scripts
- Frontend conventions document (setup, patterns, workflow)
- CI workflow template for GitHub Actions
- Staging deploy workflow template
- Plesk post-deploy script template

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 17:53:09 +00:00

2.6 KiB

Frontend Conventions

This document defines conventions for all frontend repos consuming Payload CMS via @c2s/payload-contracts.

Setup

Install Contracts Package (Git dependency)

{
  "dependencies": {
    "@c2s/payload-contracts": "github:complexcaresolutions/payload-contracts"
  }
}
pnpm install

Environment Variables

Every frontend needs these in .env.local:

NEXT_PUBLIC_PAYLOAD_URL=https://cms.c2sgmbh.de
NEXT_PUBLIC_TENANT_ID=<tenant-id>
NEXT_PUBLIC_TENANT_SLUG=<tenant-slug>
NEXT_PUBLIC_SITE_URL=https://<domain>
NODE_ENV=production

API Client Initialization

// 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!,
})

Block Renderer Setup

// src/components/blocks/index.tsx
import { createBlockRenderer } from '@c2s/payload-contracts/blocks'
import { HeroBlock } from './HeroBlock'
import { TextBlock } from './TextBlock'
// ... import site-specific block components

export const BlockRenderer = createBlockRenderer({
  'hero-block': HeroBlock,
  'text-block': TextBlock,
  // Register only blocks this site uses
})

Git Workflow

Branch Purpose Deployment
develop Active development Staging (sv-frontend)
main Production-ready Plesk auto-deploy

Commit Conventions

feat: add hero block component
fix: correct image aspect ratio in card grid
refactor: extract shared section header component

TypeScript Standards

  • Strict mode enabled
  • Import types from @c2s/payload-contracts, never define CMS types locally
  • Use BlockByType<'hero-block'> for block component props
  • All API calls through the shared client, never raw fetch to CMS

Block Component Pattern

// src/components/blocks/HeroBlock.tsx
import type { BlockByType } from '@c2s/payload-contracts/types'
import { getImageUrl } from '@c2s/payload-contracts/types'

type Props = Omit<BlockByType<'hero-block'>, 'blockType'>

export function HeroBlock({ title, subtitle, image, ctaButtons }: Props) {
  const imageUrl = getImageUrl(image, 'xlarge')
  // ... render
}

Updating Contracts

When a work order arrives:

  1. pnpm update @c2s/payload-contracts (or pnpm install for Git deps)
  2. Check node_modules/@c2s/payload-contracts/work-orders/ for instructions
  3. Implement changes
  4. pnpm build to verify types
  5. Commit and push to develop
  6. Test on staging
  7. Merge to main for production deploy