> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vulpy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Storefront content with Payload CMS

> Publish landing pages, posts, and category or product editorial with the Payload CMS that ships inside Vulpy Commerce.

Vulpy Commerce ships Payload CMS inside the storefront app for editorial content: block-based landing pages, category and product dressing, blog posts, media, and site-wide settings. Medusa stays the source of truth for commerce; Payload handles the words and pictures around it.

<Tip>
  **The fastest way is to ask Fox.** Fox works in the same Payload admin and can manage content operations for you.

  * Publish a landing page for our summer campaign.
  * Add a rich-text block to the About page.
</Tip>

## Open Payload admin

Local: [http://localhost:3000/admin](http://localhost:3000/admin). Production: `https://<shop-domain>/admin`.

Sign in with the shared admin credentials set at install.

## What Payload owns

| Collection or global                    | What it is                                                                                                                 |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `pages`                                 | Block-based landing pages (home, about, custom marketing pages)                                                            |
| `productContent`                        | Editorial blocks synced from Medusa product identity (Pro)                                                                 |
| `categoryContent`                       | Editorial blocks synced from Medusa categories, plus pseudo categories like `sale` and admin-created selection pages (Pro) |
| `posts`                                 | Rich text blog posts                                                                                                       |
| `media`                                 | Uploaded images and files (stored in `.data/payload-media` in production)                                                  |
| `contact-submissions`                   | Read-only inbox from the storefront contact form                                                                           |
| `site-settings`, `navigation`, `footer` | Site-wide globals                                                                                                          |

<Note>
  Medusa-synced fields (`title`, `handle`, `medusaCategoryId`) are read-only in Payload admin. Editorial fields (blocks, `h1`, `seo`) are writable.
</Note>

## Publish a landing page

<Steps>
  <Step title="Create a new page">
    In Payload admin, open **Pages** and click **Create new**. Set the slug and title.
  </Step>

  <Step title="Build the layout with blocks">
    Add blocks (hero, rich text, media, product grid, callouts). Reorder them by dragging. Each block renders through the storefront's block registry.
  </Step>

  <Step title="Set SEO metadata">
    Fill in `seo.title` and `seo.description`. These flow to the rendered page head.
  </Step>

  <Step title="Preview and publish">
    Use the preview URL to check the page against the storefront, then set the page to published.
  </Step>
</Steps>

## Selection pages (Pro)

Selection pages are curated landings without a Medusa category. Create a `categoryContent` entry with `kind: "selection"`, a custom `route`, and a `filterQuery`. The storefront middleware rewrites the public URL to `/selection/[handle]`, so shoppers see a clean URL like `/summer-edit`.

## Contact form

The storefront contact form uses a math captcha at `GET /api/contact/captcha` (HMAC signed with `PAYLOAD_SECRET`). Submissions land in the `contact-submissions` collection as a read-only inbox.

## Seed CMS defaults for local dev

When the Payload database is empty in non-production, the storefront falls back to `lib/cms/defaults.ts` so you always have something to click. To populate real content while `pnpm dev` is running:

```bash theme={null}
pnpm --filter @apps/storefront seed
```

<Warning>
  Production never serves seed chrome on Payload failures. If Payload is unavailable in production, the storefront renders an empty shell by design. Set `CMS_STRICT=1` if you want failures to rethrow instead.
</Warning>

<CardGroup cols={2}>
  <Card title="Manage catalog" icon="tags" href="/shop/catalog">
    Add editorial blocks on top of Medusa products and categories.
  </Card>

  <Card title="Analytics" icon="chart-line" href="/shop/analytics">
    Track how content pages perform, consent-gated.
  </Card>
</CardGroup>
