- PayloadCMS 3.64.0 + Next.js 15.4.7 + React 19.1.0 - PostgreSQL database configured - Plugins: form-builder, search, nested-docs, seo, redirects - Basic collections: Pages, Posts, Categories, Media, Users - Basic Header/Footer globals - Ready for Kit Digital grant enhancements
14 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
OGB Solutions is a personal branding website built on PayloadCMS 3.64.0 and Next.js 15.4.7. The project serves as Oscar Gimenez's professional portfolio and meets Kit Digital grant requirements for Spanish businesses.
Technology Stack:
- PayloadCMS 3.64.0 (headless CMS)
- Next.js 15.4.7 (App Router)
- React 19.1.0
- PostgreSQL (via @payloadcms/db-postgres)
- TypeScript 5.7.3
- TailwindCSS 3.4.3 + shadcn/ui
- Lexical editor for rich text
- pnpm (package manager)
Related Project: This project is derived from /home/oscar/daemez.io/x/daemez.solutions, a B2B corporate site. When adding features, you may reference Daemez for structure but adapt content and tone for personal branding rather than corporate B2B.
Essential Commands
Development
# Install dependencies
pnpm install
# Start development server (http://localhost:3000)
pnpm dev
# Build for production
pnpm build
# Start production server
pnpm start
# Dev with production mode (clean build + start)
pnpm dev:prod
Code Quality
# Run linter
pnpm lint
# Fix linting issues
pnpm lint:fix
# Run all tests (integration + e2e)
pnpm test
# Run integration tests only (Vitest)
pnpm test:int
# Run e2e tests only (Playwright)
pnpm test:e2e
PayloadCMS Operations
# Generate TypeScript types from Payload config
pnpm generate:types
# Generate import map for admin panel
pnpm generate:importmap
# Access Payload CLI directly
pnpm payload [command]
Database Operations (PostgreSQL)
Local development: The Postgres adapter has push: true enabled for development, allowing schema changes without migrations. This is safe ONLY when pointing to a local database.
Creating migrations (when deploying to production):
# Create a new migration after schema changes
pnpm payload migrate:create
# Run pending migrations on server
pnpm payload migrate
Important: Never run migrations with push: true against production data.
Architecture
Monorepo Structure
This is a monorepo with backend (PayloadCMS) and frontend (Next.js) in the same codebase:
src/
├── app/ # Next.js App Router
│ ├── (frontend)/ # Public website routes
│ └── (payload)/ # PayloadCMS admin panel
├── collections/ # Payload collections (data models)
│ ├── Pages/ # Landing pages with layout builder
│ ├── Posts/ # Blog posts with rich content
│ ├── Media/ # Uploads (images, files)
│ ├── Categories/ # Taxonomy for organizing posts
│ └── Users/ # Authentication-enabled users
├── globals/ # Site-wide settings
│ ├── Header/ # Navigation configuration
│ └── Footer/ # Footer configuration
├── blocks/ # Reusable content blocks for layout builder
│ ├── ArchiveBlock/ # Post listings
│ ├── CallToAction/ # CTA sections
│ ├── Content/ # Rich text content
│ ├── MediaBlock/ # Image/video blocks
│ ├── Banner/ # Alert/announcement banners
│ ├── Code/ # Syntax-highlighted code blocks
│ └── Form/ # Contact forms
├── heros/ # Hero section variants
│ ├── HighImpact/ # Full-screen hero
│ ├── MediumImpact/ # Standard hero
│ ├── LowImpact/ # Minimal hero
│ └── PostHero/ # Blog post hero
├── components/ # React components
├── fields/ # Reusable Payload field configs
├── access/ # Access control policies
├── hooks/ # Payload lifecycle hooks
├── utilities/ # Helper functions
└── payload.config.ts # Main Payload configuration
Key Architectural Patterns
1. Layout Builder System
Pages use a blocks-based layout builder that allows content editors to compose pages from reusable blocks. Each block has:
config.ts- Payload field configurationComponent.tsx- React component for frontend rendering- Server-side rendering via Next.js App Router
2. Draft Preview & Live Preview
Both Pages and Posts support:
- Draft mode: Preview unpublished content via secure tokens
- Live preview: Real-time preview in admin panel while editing
- Scheduled publishing: Uses Payload jobs queue for timed publication
3. On-Demand Revalidation
Hooks automatically revalidate Next.js cache when content changes:
revalidatePage- Triggered on page updatesrevalidatePost- Triggered on post updatesrevalidateHeader- Triggered on navigation changesrevalidateFooter- Triggered on footer changes
4. SEO Integration
Using @payloadcms/plugin-seo for comprehensive SEO management:
- Auto-generates meta tags
- Open Graph support
- Twitter Card support
- Sitemap generation (via
next-sitemap)
5. Access Control
Three-tier access system:
authenticated- Only logged-in usersauthenticatedOrPublished- Users or published content (public)anyone- Public access
Collections enforce access at the API level, not just UI.
Collections Deep Dive
Pages Collection
- Purpose: Marketing pages, landing pages, about, contact
- Features: Layout builder with hero variants, draft preview, SEO
- Blocks Available: CallToAction, Content, MediaBlock, Archive, FormBlock
- URL Pattern:
/{slug}(homepage is slug: "home")
Posts Collection
- Purpose: Blog articles, news, thought leadership
- Features: Rich text editor (Lexical), categories, related posts, author attribution
- Content Blocks: Banner, Code, MediaBlock (inline content blocks)
- URL Pattern:
/posts/{slug}
Media Collection
- Purpose: Asset management (images, videos, files)
- Features: Focal point selection, manual resizing, responsive image optimization
- Storage: Uses Sharp for image processing
Categories Collection
- Purpose: Taxonomy for organizing posts
- Features: Nested categories (via
@payloadcms/plugin-nested-docs) - Current Limitations: Basic implementation (name + slug only)
Users Collection
- Purpose: Admin authentication
- Features: Access to admin panel, content authorship
- Security: Authentication required for all CMS operations
Important Conventions
Path Aliases
TypeScript path aliases are configured in tsconfig.json:
@/*→src/*(all source files)@payload-config→src/payload.config.ts(Payload config)
Admin Component References
Payload admin components use file-based imports with hash notation:
components: {
RowLabel: '@/Header/RowLabel#RowLabel'
}
Hook Execution
Payload hooks run in this order:
beforeValidatebeforeChangeafterChangeafterReadafterDelete
Use beforeChange for data transformation, afterChange for side effects (like revalidation).
Environment Variables
Required variables (see .env.example):
DATABASE_URI- PostgreSQL connection stringPAYLOAD_SECRET- JWT encryption keyNEXT_PUBLIC_SERVER_URL- Base URL for links/CORSCRON_SECRET- For scheduled publishing authenticationPREVIEW_SECRET- For secure draft previews
Plugin Configuration
Active Plugins
- @payloadcms/plugin-form-builder - Contact forms with email notifications
- @payloadcms/plugin-search - Full-text search (currently posts only)
- @payloadcms/plugin-nested-docs - Hierarchical categories
- @payloadcms/plugin-seo - Meta tags, Open Graph, Twitter Cards
- @payloadcms/plugin-redirects - URL redirect management
Plugin Configuration Location
All plugins configured in src/plugins/index.ts. When adding new collections to search, update the searchPlugin collections array.
Testing Strategy
Integration Tests (Vitest)
- Location:
tests/int/**/*.int.spec.ts - Purpose: Test Payload API endpoints, hooks, access control
- Environment: jsdom with React testing library
- Run:
pnpm test:int
E2E Tests (Playwright)
- Location:
tests/e2e/**/*.e2e.spec.ts - Purpose: Test full user flows, admin panel, frontend
- Browser: Chromium (Desktop Chrome)
- Run:
pnpm test:e2e
Running Single Tests
# Single integration test
pnpm exec vitest run tests/int/api.int.spec.ts
# Single e2e test
pnpm exec playwright test tests/e2e/frontend.e2e.spec.ts
Grant Requirements (Kit Digital)
This project must meet Spanish government grant requirements. Ensure these features remain functional:
Mandatory Features
- ✅ Minimum 3 pages (home, about, contact)
- ✅ Responsive design (mobile, tablet, desktop)
- ✅ Contact form functionality
- ✅ WCAG 2.1 AA accessibility compliance
- ✅ Self-managed CMS (PayloadCMS admin)
- ✅ SEO optimization (meta tags, sitemap)
- ✅ 12-month hosting and domain in beneficiary name
Testing Accessibility
# Run Playwright accessibility tests
pnpm test:e2e
# Manual check: Chrome DevTools Lighthouse
# 1. pnpm dev
# 2. Open http://localhost:3000
# 3. Chrome DevTools → Lighthouse → Run accessibility audit
Development Workflow
Adding a New Collection
- Create collection file in
src/collections/CollectionName/index.ts - Define fields, access control, hooks
- Register in
src/payload.config.tscollections array - Run
pnpm generate:typesto update TypeScript types - Add to search plugin if searchable (in
src/plugins/index.ts) - Create migration if deploying to production:
pnpm payload migrate:create
Adding a New Block
- Create block directory in
src/blocks/BlockName/ - Add
config.ts(Payload field config) - Add
Component.tsx(React rendering component) - Register block in relevant collection (Pages or Posts)
- Add to
RenderBlocks.tsxfor frontend rendering
Adding a New Page
- Log into admin:
http://localhost:3000/admin - Navigate to Pages collection
- Click "Create New"
- Set slug (e.g., "about" → URL:
/about) - Choose hero type
- Build layout with blocks
- Configure SEO metadata
- Save as draft or publish
Modifying Header/Footer
- Navigate to Globals → Header or Footer in admin
- Modify navigation items
- Changes automatically revalidate frontend via hooks
- For code changes, edit
src/Header/config.tsorsrc/Footer/config.ts
Common Pitfalls
TypeScript Errors After Schema Changes
Problem: TypeScript errors about missing fields after changing Payload config.
Solution: Always run pnpm generate:types after modifying collections/globals.
Image Not Loading
Problem: Uploaded images return 404. Solution:
- Check
NEXT_PUBLIC_SERVER_URLin.env - Verify Sharp installation:
pnpm rebuild sharp - Check
next.config.jsremotePatterns configuration
Draft Preview Not Working
Problem: Preview links return 404 or show published version. Solution:
- Verify
PREVIEW_SECRETin.env - Check
generatePreviewPathutility is correctly configured - Ensure draft is saved before previewing
Revalidation Not Triggering
Problem: Content changes don't appear on frontend immediately. Solution:
- Check hooks are registered in collection config
- Verify Next.js is running in dev mode (revalidation is automatic)
- In production, check
afterChangehooks are executing
Migration Conflicts
Problem: pnpm payload migrate fails with conflicts.
Solution:
- Never run migrations against a database with
push: true - Set
push: falseinpayload.config.tsfor production databases - Manually resolve migration conflicts in generated SQL files
Project-Specific Notes
Personal Branding vs Corporate
This is a personal branding website, not corporate B2B. When adding features:
- Use first-person tone ("I", "my work") not third-person ("we", "our services")
- Focus on portfolio/projects, not services/products
- CTAs should be "Hire Me", "Get in Touch", not "Request Demo"
Future Enhancements Planned
Based on OGB_SETUP_GUIDE.md, these collections may be added:
- Projects - Portfolio items, case studies
- Skills - Technology expertise tags
- Experience - Career timeline
- Speaking - Conference talks, publications
When implementing these, reference /home/oscar/daemez.io/x/daemez.solutions/src/collections/ for structural inspiration.
Localization
Currently English-only. Multilingual support may be added via:
// In payload.config.ts
localization: {
locales: [
{ label: 'English', code: 'en' },
{ label: 'Español', code: 'es' },
],
defaultLocale: 'en',
fallback: true,
}
Deployment
Vercel Deployment
This project is configured for Vercel deployment:
- PostgreSQL: Use Vercel Postgres or external database
- Environment variables: Configure in Vercel dashboard
- Build command:
pnpm build - Output directory:
.next - Install command:
pnpm install
Manual Deployment
- Build project:
pnpm build - Run migrations:
pnpm payload migrate - Start server:
pnpm start - Configure reverse proxy (nginx) to point to port 3000
- Use PM2 or similar for process management
Resources
- Payload CMS Docs
- Next.js App Router Docs
- Project Setup Guide - Detailed setup instructions
- Related Project - Reference for advanced features