# payloadcms/website: the Payload marketing site, built in public with Payload itself

> The payloadcms/website repository is the source of Payload's own marketing site, a Next.js 15 application that uses Payload as its CMS and that also contains the entire frontend of Payload Cloud. It is a reference implementation rather than a template, and the documentation sync pipeline is the part most worth studying.

**payloadcms/website** — The official Next.js website for payloadcms.com

- Repository: https://github.com/payloadcms/website
- Website: https://payloadcms.com
- Stars: 642 · Forks: 193
- Language: TypeScript
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/payloadcms-website

## A marketing site that is also a demonstration

The README is explicit about the intent: the repository is for Payload's official website, and it was built completely in public using Payload itself. The stated purpose is to showcase a set of specific techniques. It shows how to use Next.js 15 with Payload's local API to its fullest extent, how to build a super dynamic light and dark mode into a Next site without any first-load flickering, how to render remotely stored docs from MDX to Next.js pages using just Payload with no external libraries, and how to use Stripe to build a custom SaaS integration. That framing matters for how you read the code. This is not a starter kit with the interesting parts removed, it is a working site where every feature has a reason, which is exactly why it is useful as a reference and exactly why it is not something you fork and deploy as your own site. The tech stack is listed as Payload, TypeScript, Next.js 15 with its new App Router, SCSS Modules, MDX for docs through the Lexical MDX Converter, GraphQL for Payload Cloud, and Stripe for Payload Cloud.

## The CMS and the frontend live in the same app

The section on the CMS is short and load-bearing. Payload is leveraged for everything that this site does, outside of its documentation which is all stored as Markdown in the Payload repo on GitHub, and both the CMS and the website frontend are found within the same app folder. That arrangement is the thing to understand. A typical headless CMS setup has a separate admin application and a separate frontend talking to it over HTTP, and the local API in Payload is what lets a Next.js app call the CMS directly in-process, without a network hop or a second deployment. The repository layout shows the parts of that. There is a src/ directory, a media/ directory for uploads, a public/ directory, a preview-runtimes/ directory, a Caddyfile for local proxying, vercel.json for the deployment, a next-sitemap.config.cjs for sitemap generation, an algolia.d.ts for search typing, a redirects.js for route management, and a cssVariables.cjs for the theming that the light and dark mode work depends on. The package dependencies are all Payload packages at the same version, 3.90.1, including db-mongodb, email-nodemailer, live-preview-react, next, plugin-form-builder, plugin-nested-docs and plugin-redirects.

## The docs pipeline: Markdown on GitHub, Lexical in the database

The most interesting mechanism in the repository is how documentation moves. The docs are stored in the Payload repo as Markdown files, and they are fetched when you press the Sync Docs button in the CMS. That button does four things: docs are pulled from the Payload repo on GitHub, the docs are converted from MDX to Lexical and stored in the CMS, the frontend docs pages are revalidated, and visiting the docs pages pulls the latest docs from the CMS and renders those lexical nodes to JSX. The round trip is more than a one-way import. Because the Lexical representation is what the CMS stores, the same document can be edited in a rich text editor and written back out to Markdown, and the .env example shows the credentials that make the write path work, with a GITHUB_ACCESS_TOKEN for reading, and COMMIT_DOCS_API_URL and COMMIT_DOCS_API_KEY for writing, alongside a note that you can run the payloadcms/gh-commit repo locally to handle it. The README also documents the reverse direction, a local preview route that reads MDX files from disk, converts them to Lexical on the fly and renders them, and states that this process will not make any changes to the database.

## Reading docs from a branch other than main

There is a routing detail here that makes the site usable against a work in progress. By default the docs are pulled from the main branch of the Payload repo on GitHub, but you can load the docs for a different branch by opening the /docs/dynamic/ route, which dynamically loads them every time you visit the page without needing to sync them in the CMS. The README gives the two URLs side by side, one pulling from the main branch and one pulling from the feat/myfeature branch via a branch query parameter. The write path is guarded in a matching way. To edit docs for a branch without touching markdown files, you use the branch selector in the CMS to pick the branch you want to work on, and after making changes and saving the document, the lexical docs are converted to MDX and pushed to the selected branch on GitHub. Two local preview routes exist as well, one for Payload 3 and one for Payload 4, each pointed at a docs directory through its own environment variable, and the local files are read, converted to lexical on the fly and rendered in the website.

## Running it locally needs a hosts file entry

The local setup is a short list, and the hosts file step is the one that trips people up. You clone the repo, run pnpm i, copy .env.example to .env, fill in the values for your own environment, run pnpm dev, and the site comes up. The catch is stated plainly: the locally running app must run on local.payloadcms.com:3000 because of http-only cookie policies and how the GitHub App redirects the user back to the site after authenticating. That means adding a line to your hosts file:

```env
127.0.0.1 local.payloadcms.com
```

The README gives the locations, /etc/hosts on Mac and C:\Windows\System32\drivers\etc\hosts on Windows. The .env example explains the variables that matter. DATABASE_URI points at a local MongoDB, PAYLOAD_SECRET is the signing secret, NEXT_PUBLIC_SITE_URL and NEXT_PUBLIC_CLOUD_CMS_URL are the two site URLs, and NEXT_PRIVATE_DRAFT_SECRET and NEXT_PRIVATE_REVALIDATION_KEY are the values used to preview draft pages and revalidate them. The dev script itself runs a preview style generation step before starting Next dev with the webpack flag, and the build script is longer, generating preview styles, generating LLM files, running a payload migrate, and only then building.

## Payload Cloud lives in the same repository

The repository is not only the marketing site. It also contains the source code for Payload Cloud, described as a one-click integration to deploy production-ready instances of your Payload apps directly from your GitHub repo, with a blog post linked for the details, and the README emphasises that the entire frontend of Payload Cloud has been built in public and is included within the repository. That is the reason the .env example carries Stripe variables, NEXT_PUBLIC_GITHUB_REDIRECT_URI, NEXT_PUBLIC_GITHUB_CLIENT_ID and a GITHUB_ACCESS_TOKEN marked for the cloud platform only. It is also the reason the repository has a lot of surface area for something that looks like a marketing site. The public surface is enormous: the docs pages, a Stripe integration, Algolia Docsearch for the community help search, a Discord scrape using DISCORD_TOKEN and DISCORD_SCRAPE_CHANNEL_ID, a newsletter form id, Google and Facebook pixel ids, a Vercel cron key, and a set of server-side analytics variables for the documentation and the LLM-readable files, including GA4_AI_MEASUREMENT_ID, GA4_AI_API_SECRET and LLMS_ANALYTICS_ENABLED. A separate caddy script and the Caddyfile exist for local proxying, and the vite-based preview-runtimes directory hints at isolated component previews.

## Where this repository is the wrong base

Three limits are clear. The first is that it is an application, not a template. The dependencies include plugins for form building, nested docs and redirects, a MongoDB adapter, a Nodemailer email adapter, live preview for React, a large set of @faceless-ui components for the cloud frontend, and Algolia, Stripe and Discord integrations, so a fork brings a commercial pricing page and a GitHub App OAuth flow with it. The second is version coupling. The code targets Next.js 15 with the App Router, Payload 3.90.1 and the Lexical rich text editor, and the docs routes even carry separate paths for Payload 2, 3 and 4 with DOCS_DIR_V2, DOCS_DIR_V3 and DOCS_DIR_V4 all present in the environment example, so a project on an older Payload would be porting rather than adopting. The third is operational. The site is a single app that owns the CMS, the frontend and the cloud dashboard, deployed with vercel.json and a Vercel cron job, so running it in production means taking on a Next.js deployment, a MongoDB instance and a set of third-party credentials, none of which the README treats as a decision you make.

## Conclusion

payloadcms/website suits a developer who wants to see a real Next.js 15 application built on Payload's own local API, with the CMS and the frontend in one app folder, a live preview of the rich text editor, and a working example of syncing documentation between GitHub and a database. It is the wrong starting point for a general website, because the app is full of Payload Cloud pricing, Stripe integration, Algolia search and Discord scraping that your project will not want, and the wrong starting point for a Payload 2 project because the code targets current Payload and Next.js versions. Verify first which Payload major you are on, since the repository carries routes and environment variables for three doc versions at once, and note that the last push was on 2026-10-16 with the package version at 1.0.4.

## FAQ

### How do I run the Payload website locally?

Clone the repo, run pnpm i, copy .env.example to .env, fill in the values, and run pnpm dev. The app must run on local.payloadcms.com:3000, so you also add 127.0.0.1 local.payloadcms.com to your hosts file for the http-only cookie policy and the GitHub App redirect to work.

### How does the documentation get from GitHub into the website?

The docs are stored as Markdown in the Payload repo on GitHub and fetched by the Sync Docs button in the CMS, which converts MDX to Lexical, stores it in the CMS, revalidates the frontend docs pages and then renders those lexical nodes to JSX on visit.

### Can I preview documentation from a branch other than main?

Yes. Opening the /docs/dynamic/ route loads the docs dynamically every time, and a branch query parameter selects the branch, for example a feat/myfeature branch. There is also a local preview route, /docs/local/ for Payload 3 and /docs/local/v4/ for Payload 4, which reads local markdown files and converts them to lexical on the fly without changing the database.

### Does this repository contain more than the marketing site?

Yes. The README states the repository also contains the source code for Payload Cloud, a one-click integration to deploy production-ready instances of your Payload apps from a GitHub repo, and that the entire Payload Cloud frontend was built in public and is included in the repository.

### Under what licence is the Payload website available?

Open source under the terms of the MIT license, with the LICENSE file at the repository root and the package manifest declaring the same licence with the package marked private.

## Sources

- [Issues](https://github.com/payloadcms/website/issues)
- [License: MIT](https://github.com/payloadcms/website/blob/main/LICENSE)
- [payloadcms/website on GitHub](https://github.com/payloadcms/website)
- [Project website](https://payloadcms.com)
- [README](https://github.com/payloadcms/website/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/payloadcms-website
