# apps/cms -- Payload CMS Admin Shell ## Purpose **THIN SHELL ONLY** -- this app exists solely to serve the Payload CMS admin panel via Next.js. All CMS logic (collections, globals, hooks, access control, `payload.config.ts`) lives in `@repo/cms-core`. This app contains no custom CMS code beyond Next.js routing boilerplate that Payload generates automatically. ## Port: 3001 ```bash pnpm dev --filter @repo/cms # http://localhost:3001/admin ``` Requires PostgreSQL running first: ```bash docker compose up -d postgres # Starts PostgreSQL on port 5432 ``` ## Hard Rules - **NEVER** add collections, globals, hooks, or access control in this app -- put them in `@repo/cms-core` - **NEVER** import from `@repo/core/infrastructure` - **NEVER** modify auto-generated files (marked with "THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD") - All CMS configuration changes go in `packages/cms-core/` ## Key Files | File | Purpose | |---|---| | `next.config.mjs` | Next.js config wrapped with `withPayload()` from `@payloadcms/next` | | `tsconfig.json` | TypeScript config with `@payload-config` path alias | | `src/app/(payload)/layout.tsx` | Auto-generated Payload root layout (DO NOT MODIFY) | | `src/app/(payload)/admin/[[...segments]]/page.tsx` | Auto-generated catch-all admin page (DO NOT MODIFY) | | `src/app/(payload)/admin/[[...segments]]/not-found.tsx` | Auto-generated 404 page (DO NOT MODIFY) | | `src/app/(payload)/importMap.js` | Auto-generated Payload import map (DO NOT MODIFY) | | `src/app/(payload)/custom.scss` | Custom SCSS overrides for admin panel styling | ## @payload-config Alias The `tsconfig.json` defines a path alias that points to the config in `@repo/cms-core`: ```json { "compilerOptions": { "paths": { "@payload-config": [ "../../packages/cms-core/src/payload.config.ts" ] } } } ``` When Payload or auto-generated files import `@payload-config`, it resolves to `packages/cms-core/src/payload.config.ts`. This is how the thin shell delegates all configuration to `@repo/cms-core`. ## next.config.mjs The Next.js config is minimal -- just the `withPayload` wrapper: ```javascript import { withPayload } from "@payloadcms/next/withPayload"; /** @type {import('next').NextConfig} */ const nextConfig = {}; export default withPayload(nextConfig); ``` `withPayload()` adds the necessary webpack aliases, module resolution, and middleware for Payload to work within Next.js. ## Auto-Generated Files The files under `src/app/(payload)/` are generated by Payload and should NOT be manually edited: - **`layout.tsx`** -- Wraps the admin panel with `RootLayout` from `@payloadcms/next/layouts`, injects config and importMap - **`admin/[[...segments]]/page.tsx`** -- Catch-all route that renders `RootPage` from `@payloadcms/next/views` - **`admin/[[...segments]]/not-found.tsx`** -- 404 handler using `NotFoundPage` from `@payloadcms/next/views` - **`importMap.js`** -- Maps Payload component paths for the admin UI If you need to regenerate these files, Payload will do so automatically during dev/build. ## Type Generation To regenerate Payload TypeScript types after changing collections/globals: ```bash cd apps/cms && pnpm generate:types # Equivalent to: payload generate:types # Output goes to: packages/cms-core/src/payload-types.ts ``` ## Dependencies | Dependency | Purpose | |---|---| | `@repo/cms-core` | All Payload configuration (collections, globals, hooks, config) | | `@payloadcms/next` | Next.js integration for Payload (withPayload, admin UI views) | | `@payloadcms/ui` | Payload admin panel React components | | `payload` | Payload CMS core | | `next` | Next.js 15 framework | | `react` / `react-dom` | React 19 runtime | | `sharp` | Image processing for Payload uploads | ## Cross-References - **ALL CMS configuration:** `packages/cms-core/` -- see `packages/cms-core/AGENTS.md` - **CMS client for querying data:** `packages/cms-client/` -- see `packages/cms-client/AGENTS.md` - **Core business logic:** `packages/core/` -- see `packages/core/AGENTS.md`