Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

Live Preview

With Live Preview you can render your front-end application directly within the Admin Panel. As you type, your changes take effect in real-time. No need to save a draft or publish your changes. This works in both Server-side as well as Client-side environments.

Live Preview works by rendering an iframe on the page that loads your front-end application. The Admin Panel communicates with your app through window.postMessage events. These events are emitted every time a change is made to the Document. Your app then listens for these events and re-renders itself with the data it receives.

To add Live Preview, use the admin.livePreview property in your Payload Config:

1
import { buildConfig } from 'payload'
2
3
const config = buildConfig({
4
// ...
5
admin: {
6
// ...
7
livePreview: {
8
url: 'http://localhost:3000',
9
collections: ['pages']
10
},
11
}
12
})

Options

Setting up Live Preview is easy. This can be done either globally through the Root Admin Config, or on individual Collection Admin Configs and Global Admin Configs. Once configured, a new "Live Preview" tab will appear at the top of enabled Documents. Navigating to this tab opens the preview window and loads your front-end application.

The following options are available:

PathDescription
url *String, or function that returns a string, pointing to your front-end application. This value is used as the iframe src. More details.
breakpointsArray of breakpoints to be used as “device sizes” in the preview window. Each item appears as an option in the toolbar. More details.
collectionsArray of collection slugs to enable Live Preview on.
globalsArray of global slugs to enable Live Preview on.

* An asterisk denotes that a property is required.

URL

The url property resolves to a string that points to your front-end application. This value is used as the src attribute of the iframe rendering your front-end. Once loaded, the Admin Panel will communicate directly with your app through window.postMessage events.

To set the URL, use the admin.livePreview.url property in your Payload Config:

1
import { buildConfig } from 'payload'
2
3
const config = buildConfig({
4
// ...
5
admin: {
6
// ...
7
livePreview: {
8
url: 'http://localhost:3000',
9
collections: ['pages'],
10
},
11
}
12
})

Dynamic URLs

You can also pass a function in order to dynamically format URLs. This is useful for multi-tenant applications, localization, or any other scenario where the URL needs to be generated based on the Document being edited.

To set dynamic URLs, set the admin.livePreview.url property in your Payload Config to a function:

1
import { buildConfig } from 'payload'
2
3
const config = buildConfig({
4
// ...
5
admin: {
6
// ...
7
livePreview: {
8
url: ({
9
data,
10
documentInfo,
11
locale
12
}) => `${data.tenant.url}${ // Multi-tenant top-level domain
13
documentInfo.slug === 'posts' ? `/posts/${data.slug}` : `${data.slug !== 'home' : `/${data.slug}` : ''}`
14
}${locale ? `?locale=${locale?.code}` : ''}`, // Localization query param
15
collections: ['pages'],
16
},
17
}
18
})

The following arguments are provided to the url function:

PathDescription
dataThe data of the Document being edited. This includes changes that have not yet been saved.
localeThe locale currently being edited (if applicable). More details.
collectionConfigThe Collection Admin Config of the Document being edited. More details.
globalConfigThe Global Admin Config of the Document being edited. More details.
reqThe Payload Request object.

If your application requires a fully qualified URL, such as within deploying to Vercel Preview Deployments, you can use the req property to build this URL:

1
url: (doc, { req }) => `${req.protocol}//${req.host}/${doc.slug}`

Breakpoints

The breakpoints property is an array of objects which are used as “device sizes” in the preview window. Each item will render as an option in the toolbar. When selected, the preview window will resize to the exact dimensions specified in that breakpoint.

To set breakpoints, use the admin.livePreview.breakpoints property in your Payload Config:

1
import { buildConfig } from 'payload'
2
3
const config = buildConfig({
4
// ...
5
admin: {
6
// ...
7
livePreview: {
8
url: 'http://localhost:3000',
9
breakpoints: [
10
{
11
label: 'Mobile',
12
name: 'mobile',
13
width: 375,
14
height: 667,
15
},
16
],
17
},
18
}
19
})

The following options are available for each breakpoint:

PathDescription
label *The label to display in the drop-down. This is what the user will see.
name *The name of the breakpoint.
width *The width of the breakpoint. This is used to set the width of the iframe.
height *The height of the breakpoint. This is used to set the height of the iframe.

* An asterisk denotes that a property is required.

The "Responsive" option is always available in the drop-down and requires no additional configuration. This is the default breakpoint that will be used on initial load. This option styles the iframe with a width and height of 100% so that it fills the screen at its maximum size and automatically resizes as the window changes size.

You may also explicitly resize the Live Preview by using the corresponding inputs in the toolbar. This will temporarily override the breakpoint selection to "Custom" until a predefined breakpoint is selected once again.

If you prefer to freely resize the Live Preview without the use of breakpoints, you can open it in a new window by clicking the button in the toolbar. This will close the iframe and open a new window which can be resized as you wish. Closing it will automatically re-open the iframe.

Example

For a working demonstration of this, check out the official Live Preview Example.

Next

Implementing Live Preview in your frontend