# Frontend Conventions This document defines conventions for all frontend repos consuming Payload CMS via `@c2s/payload-contracts`. ## Setup ### Install Contracts Package (Git dependency) ```json { "dependencies": { "@c2s/payload-contracts": "github:complexcaresolutions/payload-contracts" } } ``` ```bash pnpm install ``` ### Environment Variables Every frontend needs these in `.env.local`: ```env NEXT_PUBLIC_PAYLOAD_URL=https://cms.c2sgmbh.de NEXT_PUBLIC_TENANT_ID= NEXT_PUBLIC_TENANT_SLUG= NEXT_PUBLIC_SITE_URL=https:// NODE_ENV=production ``` ### API Client Initialization ```typescript // 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 ```typescript // 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 ```typescript // src/components/blocks/HeroBlock.tsx import type { BlockByType } from '@c2s/payload-contracts/types' import { getImageUrl } from '@c2s/payload-contracts/types' type Props = Omit, '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