Skip to content

Commit

Permalink
fix(templates): seeding in website template moved to a separate route…
Browse files Browse the repository at this point in the history
… so timeout can be customised (payloadcms#9327)
  • Loading branch information
paulpopus authored Nov 19, 2024
1 parent 5d2b0b3 commit 26cb1e1
Show file tree
Hide file tree
Showing 17 changed files with 11,741 additions and 58 deletions.
30 changes: 15 additions & 15 deletions templates/website/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Go to Payload Cloud and [clone this template](https://payloadcms.com/new/clone/w
Use the `create-payload-app` CLI to clone this template directly to your machine:

```bash
pnpx create-payload-app@beta my-project -t website
pnpx create-payload-app my-project -t website
```

#### Method 3
Expand All @@ -63,13 +63,13 @@ The Payload config is tailored specifically to the needs of most websites. It is

### Collections

See the [Collections](https://payloadcms.com/docs/beta/configuration/collections) docs for details on how to extend this functionality.
See the [Collections](https://payloadcms.com/docs/configuration/collections) docs for details on how to extend this functionality.

- #### Users (Authentication)

Users are auth-enabled collections that have access to the admin panel and unpublished content. See [Access Control](#access-control) for more details.

For additional help, see the official [Auth Example](https://github.com/payloadcms/payload/tree/beta/examples/auth) or the [Authentication](https://payloadcms.com/docs/beta/authentication/overview#authentication-overview) docs.
For additional help, see the official [Auth Example](https://github.com/payloadcms/payload/tree/examples/auth) or the [Authentication](https://payloadcms.com/docs/authentication/overview#authentication-overview) docs.

- #### Posts

Expand All @@ -85,7 +85,7 @@ See the [Collections](https://payloadcms.com/docs/beta/configuration/collections

- #### Categories

A taxonomy used to group posts together. Categories can be nested inside of one another, for example "News > Technology". See the official [Payload Nested Docs Plugin](https://payloadcms.com/docs/beta/plugins/nested-docs) for more details.
A taxonomy used to group posts together. Categories can be nested inside of one another, for example "News > Technology". See the official [Payload Nested Docs Plugin](https://payloadcms.com/docs/plugins/nested-docs) for more details.

### Globals

Expand All @@ -107,7 +107,7 @@ Basic access control is setup to limit access to various content based based on
- `posts`: Everyone can access published posts, but only users can create, update, or delete them.
- `pages`: Everyone can access published pages, but only users can create, update, or delete them.

For more details on how to extend this functionality, see the [Payload Access Control](https://payloadcms.com/docs/beta/access-control/overview#access-control) docs.
For more details on how to extend this functionality, see the [Payload Access Control](https://payloadcms.com/docs/access-control/overview#access-control) docs.

## Layout Builder

Expand All @@ -123,31 +123,31 @@ Each block is fully designed and built into the front-end website that comes wit

## Lexical editor

A deep editorial experience that allows complete freedom to focus just on writing content without breaking out of the flow with support for Payload blocks, media, links and other features provided out of the box. See [Lexical](https://payloadcms.com/docs/beta/lexical/overview) docs.
A deep editorial experience that allows complete freedom to focus just on writing content without breaking out of the flow with support for Payload blocks, media, links and other features provided out of the box. See [Lexical](https://payloadcms.com/docs/lexical/overview) docs.

## Draft Preview

All posts and pages are draft-enabled so you can preview them before publishing them to your website. To do this, these collections use [Versions](https://payloadcms.com/docs/beta/configuration/collections#versions) with `drafts` set to `true`. This means that when you create a new post, project, or page, it will be saved as a draft and will not be visible on your website until you publish it. This also means that you can preview your draft before publishing it to your website. To do this, we automatically format a custom URL which redirects to your front-end to securely fetch the draft version of your content.
All posts and pages are draft-enabled so you can preview them before publishing them to your website. To do this, these collections use [Versions](https://payloadcms.com/docs/configuration/collections#versions) with `drafts` set to `true`. This means that when you create a new post, project, or page, it will be saved as a draft and will not be visible on your website until you publish it. This also means that you can preview your draft before publishing it to your website. To do this, we automatically format a custom URL which redirects to your front-end to securely fetch the draft version of your content.

Since the front-end of this template is statically generated, this also means that pages, posts, and projects will need to be regenerated as changes are made to published documents. To do this, we use an `afterChange` hook to regenerate the front-end when a document has changed and its `_status` is `published`.

For more details on how to extend this functionality, see the official [Draft Preview Example](https://github.com/payloadcms/payload/tree/beta/examples/draft-preview).
For more details on how to extend this functionality, see the official [Draft Preview Example](https://github.com/payloadcms/payload/tree/examples/draft-preview).

## Live preview

In addition to draft previews you can also enable live preview to view your end resulting page as you're editing content with full support for SSR rendering. See [Live preview docs](https://payloadcms.com/docs/beta/live-preview/overview) for more details.
In addition to draft previews you can also enable live preview to view your end resulting page as you're editing content with full support for SSR rendering. See [Live preview docs](https://payloadcms.com/docs/live-preview/overview) for more details.

## SEO

This template comes pre-configured with the official [Payload SEO Plugin](https://payloadcms.com/docs/beta/plugins/seo) for complete SEO control from the admin panel. All SEO data is fully integrated into the front-end website that comes with this template. See [Website](#website) for more details.
This template comes pre-configured with the official [Payload SEO Plugin](https://payloadcms.com/docs/plugins/seo) for complete SEO control from the admin panel. All SEO data is fully integrated into the front-end website that comes with this template. See [Website](#website) for more details.

## Search

This template also pre-configured with the official [Payload Saerch Plugin](https://payloadcms.com/docs/beta/plugins/search) to showcase how SSR search features can easily be implemented into Next.js with Payload. See [Website](#website) for more details.
This template also pre-configured with the official [Payload Saerch Plugin](https://payloadcms.com/docs/plugins/search) to showcase how SSR search features can easily be implemented into Next.js with Payload. See [Website](#website) for more details.

## Redirects

If you are migrating an existing site or moving content to a new URL, you can use the `redirects` collection to create a proper redirect from old URLs to new ones. This will ensure that proper request status codes are returned to search engines and that your users are not left with a broken link. This template comes pre-configured with the official [Payload Redirects Plugin](https://payloadcms.com/docs/beta/plugins/redirects) for complete redirect control from the admin panel. All redirects are fully integrated into the front-end website that comes with this template. See [Website](#website) for more details.
If you are migrating an existing site or moving content to a new URL, you can use the `redirects` collection to create a proper redirect from old URLs to new ones. This will ensure that proper request status codes are returned to search engines and that your users are not left with a broken link. This template comes pre-configured with the official [Payload Redirects Plugin](https://payloadcms.com/docs/plugins/redirects) for complete redirect control from the admin panel. All redirects are fully integrated into the front-end website that comes with this template. See [Website](#website) for more details.

## Website

Expand Down Expand Up @@ -207,7 +207,7 @@ To run Payload in production, you need to build and start the Admin panel. To do

1. Invoke the `next build` script by running `pnpm build` or `npm run build` in your project root. This creates a `.next` directory with a production-ready admin bundle.
1. Finally run `pnpm start` or `npm run start` to run Node in production and serve Payload from the `.build` directory.
1. When you're ready to go live, see [Deployment](#deployment) for more details.
1. When you're ready to go live, see Deployment below for more details.

### Deploying to Payload Cloud

Expand Down Expand Up @@ -258,7 +258,7 @@ export default buildConfig({
// ...
```
There is also a simplified [one click deploy](https://github.com/payloadcms/payload/tree/beta/templates/with-vercel-postgres) to Vercel should you need it.
There is also a simplified [one click deploy](https://github.com/payloadcms/payload/tree/templates/with-vercel-postgres) to Vercel should you need it.
### Self-hosting
Expand All @@ -267,7 +267,7 @@ Before deploying your app, you need to:
1. Ensure your app builds and serves in production. See [Production](#production) for more details.
2. You can then deploy Payload as you would any other Node.js or Next.js application either directly on a VPS, DigitalOcean's Apps Platform, via Coolify or more. More guides coming soon.
You can also deploy your app manually, check out the [deployment documentation](https://payloadcms.com/docs/beta/production/deployment) for full details.
You can also deploy your app manually, check out the [deployment documentation](https://payloadcms.com/docs/production/deployment) for full details.
## Questions
Expand Down
2 changes: 1 addition & 1 deletion templates/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"graphql": "^16.8.2",
"jsonwebtoken": "9.0.2",
"lucide-react": "^0.378.0",
"next": "15.0.0",
"next": "^15",
"payload": "latest",
"payload-admin-bar": "^1.0.6",
"prism-react-renderer": "^2.3.1",
Expand Down
2 changes: 1 addition & 1 deletion templates/website/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions templates/website/src/app/(frontend)/next/seed/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import jwt from 'jsonwebtoken'
import { createLocalReq, getPayload } from 'payload'
import { seed } from '@/endpoints/seed'
import config from '@payload-config'

const payloadToken = 'payload-token'
export const maxDuration = 60 // This function can run for a maximum of 60 seconds

export async function POST(
req: Request & {
cookies: {
get: (name: string) => {
value: string
}
}
},
): Promise<Response> {
const payload = await getPayload({ config })
const token = req.cookies.get(payloadToken)?.value

let user

try {
user = jwt.verify(token, payload.secret)
} catch (error) {
payload.logger.error('Error verifying token for live preview:', error)
}

if (!user) {
return new Response('Action forbidden.', { status: 403 })
}

try {
// Create a Payload request object to pass to the Local API for transactions
// At this point you should pass in a user, locale, and any other context you need for the Local API
const payloadReq = await createLocalReq({ user }, payload)

await seed({ payload, req: payloadReq })

return Response.json({ success: true })
} catch {
return new Response('Error seeding data.')
}
}
2 changes: 1 addition & 1 deletion templates/website/src/collections/Media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const Media: CollectionConfig = {
{
name: 'alt',
type: 'text',
required: true,
//required: true,
},
{
name: 'caption',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.seedButton {
appearance: none;
background: none;
border: none;
padding: 0;
text-decoration: underline;

&:hover {
cursor: pointer;
opacity: 0.85;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import React, { Fragment, useCallback, useState } from 'react'
import { toast } from '@payloadcms/ui'

import './index.scss'

const SuccessMessage: React.FC = () => (
<div>
Database seeded! You can now{' '}
Expand All @@ -20,19 +22,53 @@ export const SeedButton: React.FC = () => {
const handleClick = useCallback(
async (e) => {
e.preventDefault()
if (loading || seeded) return

if (seeded) {
toast.info('Database already seeded.')
return
}
if (loading) {
toast.info('Seeding already in progress.')
return
}
if (error) {
toast.error(`An error occurred, please refresh and try again.`)
return
}

setLoading(true)

try {
await fetch('/api/seed')
setSeeded(true)
toast.success(<SuccessMessage />, { duration: 5000 })
toast.promise(
new Promise((resolve, reject) => {
try {
fetch('/next/seed', { method: 'POST', credentials: 'include' })
.then((res) => {
if (res.ok) {
resolve(true)
setSeeded(true)
} else {
reject('An error occurred while seeding.')
}
})
.catch((error) => {
reject(error)
})
} catch (error) {
reject(error)
}
}),
{
loading: 'Seeding with data....',
success: <SuccessMessage />,
error: 'An error occurred while seeding.',
},
)
} catch (err) {
setError(err)
}
},
[loading, seeded],
[loading, seeded, error],
)

let message = ''
Expand All @@ -42,9 +78,9 @@ export const SeedButton: React.FC = () => {

return (
<Fragment>
<a href="/api/seed" onClick={handleClick} rel="noopener noreferrer" target="_blank">
<button className="seedButton" onClick={handleClick}>
Seed your database
</a>
</button>
{message}
</Fragment>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const ImageMedia: React.FC<MediaProps> = (props) => {

width = fullWidth!
height = fullHeight!
alt = altFromResource
alt = altFromResource || ''

src = `${process.env.NEXT_PUBLIC_SERVER_URL}${url}`
}
Expand Down
6 changes: 3 additions & 3 deletions templates/website/src/payload-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ export interface Config {
user: User & {
collection: 'users';
};
jobs?: {
jobs: {
tasks: unknown;
workflows?: unknown;
workflows: unknown;
};
}
export interface UserAuthOperations {
Expand Down Expand Up @@ -138,7 +138,7 @@ export interface Page {
*/
export interface Media {
id: string;
alt: string;
alt?: string | null;
caption?: {
root: {
type: string;
Expand Down
10 changes: 0 additions & 10 deletions templates/website/src/payload.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { Media } from './collections/Media'
import { Pages } from './collections/Pages'
import { Posts } from './collections/Posts'
import { Users } from './collections/Users'
import { seedHandler } from './endpoints/seedHandler'
import { Footer } from './Footer/config'
import { Header } from './Header/config'
import { plugins } from './plugins'
Expand Down Expand Up @@ -66,15 +65,6 @@ export default buildConfig({
// database-adapter-config-end
collections: [Pages, Posts, Media, Categories, Users],
cors: [process.env.NEXT_PUBLIC_SERVER_URL || ''].filter(Boolean),
endpoints: [
// The seed endpoint is used to populate the database with some example data
// You should delete this endpoint before deploying your site to production
{
handler: seedHandler,
method: 'get',
path: '/seed',
},
],
globals: [Header, Footer],
plugins: [
...plugins,
Expand Down
2 changes: 1 addition & 1 deletion templates/with-vercel-website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"graphql": "^16.8.2",
"jsonwebtoken": "9.0.2",
"lucide-react": "^0.378.0",
"next": "15.0.0",
"next": "^15",
"payload": "latest",
"payload-admin-bar": "^1.0.6",
"prism-react-renderer": "^2.3.1",
Expand Down
Loading

0 comments on commit 26cb1e1

Please sign in to comment.