Implement live preview

This commit is contained in:
tobias 2024-06-24 11:53:43 +02:00
parent 4dfe80213e
commit 5d652dc606
6 changed files with 82 additions and 4 deletions

View File

@ -26,6 +26,8 @@
"@payloadcms/plugin-nested-docs": "3.0.0-beta.35", "@payloadcms/plugin-nested-docs": "3.0.0-beta.35",
"@payloadcms/richtext-lexical": "3.0.0-beta.40", "@payloadcms/richtext-lexical": "3.0.0-beta.40",
"@payloadcms/ui": "3.0.0-beta.40", "@payloadcms/ui": "3.0.0-beta.40",
"@payloadcms/live-preview": "3.0.0-beta.35",
"@payloadcms/live-preview-react": "3.0.0-beta.35",
"babel-plugin-react-compiler": "^0.0.0-experimental-592953e-20240517", "babel-plugin-react-compiler": "^0.0.0-experimental-592953e-20240517",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"deepmerge": "^4.3.1", "deepmerge": "^4.3.1",

View File

@ -28,6 +28,7 @@ import Authors from '@payload/collections/Authors'
import Posts from '@payload/collections/Posts' import Posts from '@payload/collections/Posts'
import Users from '@payload/collections/Users' import Users from '@payload/collections/Users'
import Pages from '@payload/collections/Pages' import Pages from '@payload/collections/Pages'
import { COLLECTION_SLUG_PAGE, COLLECTION_SLUG_POST } from '@/app/(payload)/collections/config'
const filename = fileURLToPath(import.meta.url) const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename) const dirname = path.dirname(filename)
@ -40,6 +41,12 @@ export default buildConfig({
password: 'test', password: 'test',
prefillOnly: true, prefillOnly: true,
}, },
livePreview: {
url: ({ data, locale }) =>
//TODO: Rewrite to collection_slug/preview/
`${process.env.BASE_URL}/preview${data.path}${locale ? `?locale=${locale.code}` : ''}`,
collections: [COLLECTION_SLUG_PAGE],
},
}, },
editor: lexicalEditor(), editor: lexicalEditor(),
secret: process.env.PAYLOAD_SECRET || '', secret: process.env.PAYLOAD_SECRET || '',

View File

@ -15,6 +15,12 @@ importers:
'@payloadcms/db-mongodb': '@payloadcms/db-mongodb':
specifier: 3.0.0-beta.40 specifier: 3.0.0-beta.40
version: 3.0.0-beta.40(@aws-sdk/client-sso-oidc@3.588.0)(payload@3.0.0-beta.40(@swc/core@1.5.24(@swc/helpers@0.5.11))(@swc/types@0.1.7)(graphql@16.8.1)(typescript@5.4.5)) version: 3.0.0-beta.40(@aws-sdk/client-sso-oidc@3.588.0)(payload@3.0.0-beta.40(@swc/core@1.5.24(@swc/helpers@0.5.11))(@swc/types@0.1.7)(graphql@16.8.1)(typescript@5.4.5))
'@payloadcms/live-preview':
specifier: 3.0.0-beta.35
version: 3.0.0-beta.35
'@payloadcms/live-preview-react':
specifier: 3.0.0-beta.35
version: 3.0.0-beta.35(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522)
'@payloadcms/next': '@payloadcms/next':
specifier: 3.0.0-beta.40 specifier: 3.0.0-beta.40
version: 3.0.0-beta.40(graphql@16.8.1)(monaco-editor@0.49.0)(next@15.0.0-rc.0(babel-plugin-react-compiler@0.0.0-experimental-938cd9a-20240601)(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522)(sass@1.77.4))(payload@3.0.0-beta.40(@swc/core@1.5.24(@swc/helpers@0.5.11))(@swc/types@0.1.7)(graphql@16.8.1)(typescript@5.4.5))(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522)(types-react@19.0.0-beta.2)(typescript@5.4.5) version: 3.0.0-beta.40(graphql@16.8.1)(monaco-editor@0.49.0)(next@15.0.0-rc.0(babel-plugin-react-compiler@0.0.0-experimental-938cd9a-20240601)(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522)(sass@1.77.4))(payload@3.0.0-beta.40(@swc/core@1.5.24(@swc/helpers@0.5.11))(@swc/types@0.1.7)(graphql@16.8.1)(typescript@5.4.5))(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522)(types-react@19.0.0-beta.2)(typescript@5.4.5)
@ -712,6 +718,15 @@ packages:
graphql: ^16.8.1 graphql: ^16.8.1
payload: 3.0.0-beta.40 payload: 3.0.0-beta.40
'@payloadcms/live-preview-react@3.0.0-beta.35':
resolution: {integrity: sha512-OAkuNILhSpFnHuUOThZ2c1D3DzHA3liUpgxG5VnbnMJzYThR7XE7R3jkeCEs+7V3bpy+oKyNxEZAc/jqufMhzA==}
peerDependencies:
react: ^18.2.0 || ^19.0.0
react-dom: ^18.2.0 || ^19.0.0
'@payloadcms/live-preview@3.0.0-beta.35':
resolution: {integrity: sha512-t0JdtfYYc4xU8F/3dj0iwaSoPhc/n2XXe6qsEKYtuKqFRNs00aX2fm1FSrQ8HG1onWnu7g+1VnEjsJeajnT7hw==}
'@payloadcms/next@3.0.0-beta.40': '@payloadcms/next@3.0.0-beta.40':
resolution: {integrity: sha512-B/6uXGyrp0L8J6afSZ2hgB8pWe69O7PTdEDT0MG6gUAIg+EVxn54kFqA8YsR5l68Fa8q5xOPrliBfd58OAOYng==} resolution: {integrity: sha512-B/6uXGyrp0L8J6afSZ2hgB8pWe69O7PTdEDT0MG6gUAIg+EVxn54kFqA8YsR5l68Fa8q5xOPrliBfd58OAOYng==}
engines: {node: '>=18.20.2'} engines: {node: '>=18.20.2'}
@ -4476,6 +4491,14 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- typescript - typescript
'@payloadcms/live-preview-react@3.0.0-beta.35(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522)':
dependencies:
'@payloadcms/live-preview': 3.0.0-beta.35
react: 19.0.0-rc-f994737d14-20240522
react-dom: 19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522)
'@payloadcms/live-preview@3.0.0-beta.35': {}
'@payloadcms/next@3.0.0-beta.40(graphql@16.8.1)(monaco-editor@0.49.0)(next@15.0.0-rc.0(babel-plugin-react-compiler@0.0.0-experimental-938cd9a-20240601)(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522)(sass@1.77.4))(payload@3.0.0-beta.40(@swc/core@1.5.24(@swc/helpers@0.5.11))(@swc/types@0.1.7)(graphql@16.8.1)(typescript@5.4.5))(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522)(types-react@19.0.0-beta.2)(typescript@5.4.5)': '@payloadcms/next@3.0.0-beta.40(graphql@16.8.1)(monaco-editor@0.49.0)(next@15.0.0-rc.0(babel-plugin-react-compiler@0.0.0-experimental-938cd9a-20240601)(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522)(sass@1.77.4))(payload@3.0.0-beta.40(@swc/core@1.5.24(@swc/helpers@0.5.11))(@swc/types@0.1.7)(graphql@16.8.1)(typescript@5.4.5))(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522)(types-react@19.0.0-beta.2)(typescript@5.4.5)':
dependencies: dependencies:
'@dnd-kit/core': 6.0.8(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522) '@dnd-kit/core': 6.0.8(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522)

View File

@ -0,0 +1,23 @@
import PreviewBlocks from '@/components/PreviewBlocks'
import { getCurrentUser } from '@/lib/payload'
import { COLLECTION_SLUG_PAGE } from '@payload/collections/config'
import { getDocument } from '@/utils/getDocument'
import { unstable_noStore as noStore } from 'next/cache'
import { notFound } from 'next/navigation'
const PreviewCatchAllPage = async ({ params }: { params: { path: string[] } }) => {
noStore()
const [user, page] = await Promise.all([
getCurrentUser(),
getDocument({
collection: COLLECTION_SLUG_PAGE,
path: params.path,
depth: 3,
cache: false,
}),
])
if (!user || !page) notFound()
return <PreviewBlocks initialData={page} locale="" url={process.env.BASE_URL || ''} />
}
export default PreviewCatchAllPage

View File

@ -36,13 +36,13 @@ const slugField: Slug = (fieldToUse = 'title', overrides = {}) => {
index: true, index: true,
required: false, // Need to be false so that we can use beforeValidate hook to set slug. required: false, // Need to be false so that we can use beforeValidate hook to set slug.
admin: { admin: {
position: 'sidebar' position: 'sidebar',
}, },
hooks: { hooks: {
beforeValidate: [formatSlug(fieldToUse)] beforeValidate: [formatSlug(fieldToUse)],
} },
}, },
overrides overrides,
) )
} }

View File

@ -0,0 +1,23 @@
'use client'
import Blocks from '@/components/Blocks'
import type { Page } from 'types/payload-types'
import { useLivePreview } from '@payloadcms/live-preview-react'
export default function PreviewBlocks({
initialData,
locale,
url,
}: {
initialData?: Page | null
locale: string
url: string
}) {
const { data } = useLivePreview({
serverURL: url,
depth: 3,
initialData: initialData,
})
return <Blocks blocks={data?.blocks || []} locale={locale} />
}