Skip to content

Commit

Permalink
examples: Add new cms-payload example. (#49616)
Browse files Browse the repository at this point in the history
This PR adds `cms-payload` to the examples folder. The demo provides a
NextJS frontend, built with Payload, which can be deployed together in a
single instance.

### Improving Documentation or adding/fixing Examples

- [x] The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- [x] Make sure the linting passes by running `pnpm build && pnpm lint`.
See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md

---------

Co-authored-by: Lee Robinson <me@leerob.io>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
  • Loading branch information
3 people committed Jun 16, 2023
1 parent 13c205f commit cca9dd1
Show file tree
Hide file tree
Showing 119 changed files with 3,777 additions and 0 deletions.
12 changes: 12 additions & 0 deletions examples/cms-payload/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
MONGODB_URI=mongodb://localhost/payload-vercel-functions
PAYLOAD_SECRET=YOUR_SECRET_HERE
PAYLOAD_CONFIG_PATH=dist/payload.config.js
NEXT_PUBLIC_APP_URL=http://localhost:3000
PAYLOAD_PUBLIC_CMS_URL=http://localhost:3000
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_REGION=
NEXT_PUBLIC_S3_ENDPOINT=
NEXT_PUBLIC_S3_BUCKET=
PAYLOAD_PRIVATE_REGENERATION_SECRET=
NEXT_PRIVATE_REGENERATION_SECRET=
171 changes: 171 additions & 0 deletions examples/cms-payload/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
.DS_Store
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

### Node Patch ###
# Serverless Webpack directories
.webpack/

# Optional stylelint cache

# SvelteKit build / generate output
.svelte-kit

### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets

# Local History for Visual Studio Code
.history/

# Built Visual Studio Code Extensions
*.vsix

### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide

# Support for Project snippet scope
.vscode/*.code-snippets

# Ignore code-workspaces
*.code-workspace

# End of https://www.toptal.com/developers/gitignore/api/node,visualstudiocode
.vercel

build
public/admin
1 change: 1 addition & 0 deletions examples/cms-payload/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
legacy-peer-deps=true
66 changes: 66 additions & 0 deletions examples/cms-payload/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Next + Payload Serverless Demo

This is a demo showing how to utilize `@payloadcms/next-payload` to deploy Payload serverlessly, in the same repo alongside of a NextJS app.

## Deploy your own

Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/cms-payload&project-name=cms-payload&repository-name=cms-payload)

## How to use

Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example:

```bash
npx create-next-app --example cms-payload cms-payload-app
```

```bash
yarn create next-app --example cms-payload cms-payload-app
```

```bash
pnpm create next-app --example cms-payload cms-payload-app
```

Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).

The only thing you need to do to deploy to Vercel is to ensure that you have a Mongo Atlas database connection string and an S3 bucket (if desired).

Fill out the same environment variables that are shown in the `.env.example` with your own values, and then you're good to go!

### Developing locally

To develop with this package locally, make sure you have the following required software:

1. MongoDB
2. Node + NPM / Yarn
3. An S3 bucket to store media (optional)

### Getting started

Follow the steps below to spin up a local dev environment:

1. Clone the repo
2. Run `yarn` or `npm install`
3. Run `cp .env.example .env` and fill out all ENV variables as shown
4. Run `yarn dev` to start up the dev server

From there, you can visit your admin panel via navigating to `http://localhost:3000/admin`. Go ahead and start working!

### Related examples

- [Strapi](/examples/cms-strapi)
- [Contentful](/examples/cms-contentful)
- [WordPress](/examples/cms-wordpress)
- [Sanity](/examples/cms-sanity)
- [DatoCMS](/examples/cms-datocms)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
2 changes: 2 additions & 0 deletions examples/cms-payload/app/(payload)/admin/[...slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Need to render the same component for anything within /admin
export { default } from '../page'
18 changes: 18 additions & 0 deletions examples/cms-payload/app/(payload)/admin/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use client'

import React from 'react'
import Root from 'payload/dist/admin/Root'

const PayloadAdmin = () => {
const [mounted, setMounted] = React.useState(false)

React.useEffect(() => {
setMounted(true)
}, [])

if (!mounted) return null

return <Root />
}

export default PayloadAdmin
52 changes: 52 additions & 0 deletions examples/cms-payload/app/(site)/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { notFound } from 'next/navigation'
import { getPayloadClient } from '../../../payload/payloadClient'
import Blocks from '../../../components/Blocks'
import { Hero } from '../../../components/Hero'
import { AdminBar } from '../../../components/AdminBar'
import { Metadata } from 'next'

export async function generateMetadata({
params: { slug },
}): Promise<Metadata> {
return {
title: slug,
}
}

const Page = async ({ params: { slug } }) => {
const payload = await getPayloadClient()

const pages = await payload.find({
collection: 'pages',
where: {
slug: {
equals: slug || 'home',
},
},
})

const page = pages.docs[0]

if (!page) return notFound()

return (
<>
<AdminBar adminBarProps={{ collection: 'pages', id: page.id }} />
<Hero {...page.hero} />
<Blocks blocks={page.layout} />
</>
)
}

export async function generateStaticParams() {
const payload = await getPayloadClient()

const pages = await payload.find({
collection: 'pages',
limit: 0,
})

return pages.docs.map(({ slug }) => ({ slug }))
}

export default Page
14 changes: 14 additions & 0 deletions examples/cms-payload/app/(site)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Layout from '../../components/Layout'
import { getPayloadClient } from '../../payload/payloadClient'

const SiteLayout = async ({ children }: { children: React.ReactNode }) => {
const payload = await getPayloadClient()

const mainMenu = await payload.findGlobal({
slug: 'main-menu',
})

return <Layout mainMenu={mainMenu}>{children}</Layout>
}

export default SiteLayout
3 changes: 3 additions & 0 deletions examples/cms-payload/app/(site)/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Page from './[slug]/page'

export default Page
11 changes: 11 additions & 0 deletions examples/cms-payload/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>{children}</body>
</html>
)
}

0 comments on commit cca9dd1

Please sign in to comment.