obsidian/wiki/tech-patterns/payload-cms-admin-panel-location.md
2026-05-15 15:13:56 +01:00

134 lines
5 KiB
Markdown

---
title: "Payload CMS — Custom Admin Panel Location"
aliases: [payload-admin-route, payload-custom-route, payload-admin-location]
tags: [payload-cms, nextjs, admin-panel, routing, configuration]
sources: [raw/admin__admin-panel-location.md]
created: 2026-05-15
updated: 2026-05-15
---
# Payload CMS — Custom Admin Panel Location
Payload is flexible about where the Admin Panel lives in a Next.js App Router project. You can rename the route, nest it deeper, or co-locate it with custom admin dashboards.
## Default Folder Structure
```
app/ (or src/app/)
└── (payload)/
├── admin/
│ ├── [[...segments]]/
│ │ ├── not-found.tsx
│ │ └── page.tsx
│ └── importMap.js ← auto-generated, never edit manually
├── api/
│ └── [...slug]/route.ts
├── custom.scss
└── layout.tsx ← safe to edit despite the "DO NOT MODIFY" warning
```
## Scenario 1 — Rename the Route (`/admin` → `/dashboard`)
1. **Config:**
```ts
buildConfig({ routes: { admin: '/dashboard' } })
```
2. **Move folder:** `mv app/(payload)/admin app/(payload)/dashboard`
3. **Update `layout.tsx` import:**
```ts
import { importMap } from './dashboard/importMap.js'
```
4. Restart dev server.
## Scenario 2 — Move the Entire `(payload)` Folder
Moves both Admin UI and REST API under a custom prefix (e.g. `/admin/content`).
> **Gotcha:** `(payload)/admin/` is a Next.js route segment, so placing `(payload)` at `app/admin/content/(payload)` gives you `/admin/content/admin`, not `/admin/content`.
**Config:**
```ts
buildConfig({
routes: {
admin: '/admin/content/admin',
api: '/admin/content/api',
graphQL: '/admin/content/api/graphql',
graphQLPlayground: '/admin/content/api/graphql-playground',
},
admin: {
importMap: {
baseDir: path.resolve(dirname, './src/app/admin/content/(payload)'),
importMapFile: path.resolve(
dirname,
'./src/app/admin/content/(payload)/admin/importMap.js',
),
},
},
})
```
**Steps:**
1. `mkdir -p app/admin/content && mv app/(payload) app/admin/content/(payload)`
2. Verify `layout.tsx` import path (usually stays `'./admin/importMap.js'`)
3. `pnpm payload generate:importmap`
## Scenario 3 — Multiple Admin Dashboards
```
app/admin/
├── content/(payload)/ ← Payload CMS
├── platform/ ← custom admin
└── page.tsx ← landing page choosing between admins
```
Same config as Scenario 2; just add your custom routes alongside `(payload)`.
## Auto-Generated vs Safe-to-Edit Files
| File | Auto-Generated? | Safe to Edit? |
|------|----------------|--------------|
| `layout.tsx` | No (created once by create-payload-app) | **Yes** — update import paths here |
| `admin/importMap.js` | **Yes** (startup, HMR, manual cmd) | **No** — configure via `admin.importMap` |
| `admin/[[...segments]]/page.tsx` | No | Rarely needed |
| `api/[...slug]/route.ts` | No | Rarely needed |
| `custom.scss` | No | Yes |
> **Note:** The "DO NOT MODIFY" comment in `layout.tsx` is misleading — it was generated once during `create-payload-app` and Payload **never** overwrites it. Safe to edit import paths.
## `importMap.js` Regeneration Triggers
- App startup (dev or prod build)
- HMR (when component files change)
- `pnpm payload generate:importmap` (manual)
Never edit `importMap.js` directly — configure paths via `admin.importMap.baseDir` / `importMapFile`.
## Troubleshooting
| Symptom | Fix |
|---------|-----|
| Import map not found | Check `admin.importMap.importMapFile` is absolute; run `pnpm payload generate:importmap` |
| `layout.tsx` import error | Path must be relative from `layout.tsx` → `importMap.js`; verify after folder move |
| Admin panel 404 | Verify `routes.admin` matches actual folder structure; ensure entire `(payload)` was moved |
| Custom components not loading | Check `admin.importMap.baseDir`; regenerate import map |
## Key Takeaways
- `routes.admin` in Payload config **must match** the actual Next.js folder path.
- When you rename/move `admin/`, update the `import { importMap }` line in `layout.tsx`.
- Moving `(payload)` deeper adds its subfolder names to the URL — plan the nesting accordingly.
- `importMap.js` is always auto-generated; configure its location via `admin.importMap`, never edit the file.
- `layout.tsx` is **safe to edit** despite the generated-file warning.
- After any folder move, run `pnpm payload generate:importmap` to be safe.
## Related Articles
- [[wiki/tech-patterns/payload-cms-installation|Payload CMS — Installation & Setup]]
- [[wiki/tech-patterns/payload-cms-access-control-overview|Payload CMS — Access Control Overview]]
- [[wiki/tech-patterns/payload-cms-admin-accessibility|Payload CMS — Admin Panel Accessibility]]
- [[wiki/tech-patterns/nextjs-fastapi-fullstack|Next.js + FastAPI Fullstack Pattern]]
## Sources
- `raw/admin__admin-panel-location.md`
- https://payloadcms.com/docs/admin/admin-panel-location