Supports live preview conditions. This is essentially access control for
live preview, where you may want to restrict who can use it based on
certain criteria, such as the current user or document data.
To do this, simply return null or undefined from your live preview url
functions:
```ts
url: ({ req }) => (req.user?.role === 'admin' ? '/hello-world' : null)
```
This is also useful for pages which derive their URL from document data,
e.g. a slug field, do not attempt to render the live preview window
until the URL is fully formatted.
For example, if you have a page in your front-end with the URL structure
of `/posts/[slug]`, the slug field is required before the page can
properly load. However, if the slug is not a required field, or when
drafts and/or autosave is enabled, the slug field might not yet have
data, leading to `/posts/undefined` or similar.
```ts
url: ({ data }) => data?.slug ? `/${data.slug}` : null
```
---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
- https://app.asana.com/0/0/1211513433305000
182 lines
9.5 KiB
Plaintext
182 lines
9.5 KiB
Plaintext
---
|
|
title: Live Preview
|
|
label: Overview
|
|
order: 10
|
|
desc: With Live Preview you can render your front-end application directly within the Admin Panel. Your changes take effect as you type. No save needed.
|
|
keywords: live preview, preview, live, iframe, iframe preview, visual editing, design
|
|
---
|
|
|
|
With Live Preview you can render your front-end application directly within the [Admin Panel](../admin/overview). 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](./server) as well as [Client-side](./client) 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`](https://developer.mozilla.org/en-US/docs/Web/API/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](../configuration/overview):
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload'
|
|
|
|
const config = buildConfig({
|
|
// ...
|
|
admin: {
|
|
// ...
|
|
// highlight-start
|
|
livePreview: {
|
|
url: 'http://localhost:3000',
|
|
collections: ['pages'],
|
|
},
|
|
// highlight-end
|
|
},
|
|
})
|
|
```
|
|
|
|
<Banner type="warning">
|
|
**Reminder:** Alternatively, you can define the `admin.livePreview` property
|
|
on individual [Collection Admin
|
|
Configs](../configuration/collections#admin-options) and [Global Admin
|
|
Configs](../configuration/globals#admin-options). Settings defined here will
|
|
be merged into the top-level as overrides.
|
|
</Banner>
|
|
|
|
## Options
|
|
|
|
Setting up Live Preview is easy. This can be done either globally through the [Root Admin Config](../admin/overview), or on individual [Collection Admin Configs](../configuration/collections#admin-options) and [Global Admin Configs](../configuration/globals#admin-options). Once configured, a new "Live Preview" button will appear at the top of enabled Documents. Toggling this button opens the preview window and loads your front-end application.
|
|
|
|
The following options are available:
|
|
|
|
| Path | Description |
|
|
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| **`url`** | String, or function that returns a string, pointing to your front-end application. This value is used as the iframe `src`. [More details](#url). |
|
|
| **`breakpoints`** | Array of breakpoints to be used as “device sizes” in the preview window. Each item appears as an option in the toolbar. [More details](#breakpoints). |
|
|
| **`collections`** | Array of collection slugs to enable Live Preview on. |
|
|
| **`globals`** | Array of global slugs to enable Live Preview on. |
|
|
|
|
### 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](../configuration/overview):
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload'
|
|
|
|
const config = buildConfig({
|
|
// ...
|
|
admin: {
|
|
// ...
|
|
livePreview: {
|
|
url: 'http://localhost:3000', // highlight-line
|
|
collections: ['pages'],
|
|
},
|
|
},
|
|
})
|
|
```
|
|
|
|
#### 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.
|
|
|
|
This is also useful for conditionally rendering Live Preview, similar to access control. See [Conditional Rendering](./conditional-rendering) for more details.
|
|
|
|
To set dynamic URLs, set the `admin.livePreview.url` property in your [Payload Config](../configuration/overview) to a function:
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload'
|
|
|
|
const config = buildConfig({
|
|
// ...
|
|
admin: {
|
|
// ...
|
|
livePreview: {
|
|
// highlight-start
|
|
url: ({ data, collectionConfig, locale }) =>
|
|
`${data.tenant.url}${
|
|
collectionConfig.slug === 'posts'
|
|
? `/posts/${data.slug}`
|
|
: `${data.slug !== 'home' ? `/${data.slug}` : ''}`
|
|
}${locale ? `?locale=${locale?.code}` : ''}`, // Localization query param
|
|
collections: ['pages'],
|
|
},
|
|
// highlight-end
|
|
},
|
|
})
|
|
```
|
|
|
|
The following arguments are provided to the `url` function:
|
|
|
|
| Path | Description |
|
|
| ---------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
| **`data`** | The data of the Document being edited. This includes changes that have not yet been saved. |
|
|
| **`locale`** | The locale currently being edited (if applicable). [More details](../configuration/localization). |
|
|
| **`collectionConfig`** | The Collection Admin Config of the Document being edited. [More details](../configuration/collections#admin-options). |
|
|
| **`globalConfig`** | The Global Admin Config of the Document being edited. [More details](../configuration/globals#admin-options). |
|
|
| **`req`** | The Payload Request object. |
|
|
|
|
You can return either an absolute URL or relative URL from this function. If you don't know the URL of your frontend at build-time, you can return a relative URL, and in that case, Payload will automatically construct an absolute URL by injecting the protocol, domain, and port from your browser window. Returning a relative URL is helpful for platforms like Vercel where you may have preview deployment URLs that are unknown at build time.
|
|
|
|
If your application requires a fully qualified URL, or you are attempting to preview with a frontend on a different domain, you can use the `req` property to build this URL:
|
|
|
|
```ts
|
|
url: ({ data, req }) => `${req.protocol}//${req.host}/${data.slug}`
|
|
```
|
|
|
|
#### Conditional Rendering
|
|
|
|
You can conditionally render Live Preview by returning `undefined` or `null` from the `url` function. This is similar to access control, where you may want to restrict who can use Live Preview based on certain criteria, such as the current user or document data.
|
|
|
|
For example, you could check the user's role and only enable Live Preview if they have the appropriate permissions:
|
|
|
|
```ts
|
|
url: ({ req }) => (req.user?.role === 'admin' ? '/hello-world' : null)
|
|
```
|
|
|
|
### 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](../configuration/overview):
|
|
|
|
```ts
|
|
import { buildConfig } from 'payload'
|
|
|
|
const config = buildConfig({
|
|
// ...
|
|
admin: {
|
|
// ...
|
|
livePreview: {
|
|
url: 'http://localhost:3000',
|
|
// highlight-start
|
|
breakpoints: [
|
|
{
|
|
label: 'Mobile',
|
|
name: 'mobile',
|
|
width: 375,
|
|
height: 667,
|
|
},
|
|
],
|
|
// highlight-end
|
|
},
|
|
},
|
|
})
|
|
```
|
|
|
|
The following options are available for each breakpoint:
|
|
|
|
| Path | Description |
|
|
| --------------- | --------------------------------------------------------------------------- |
|
|
| **`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](https://github.com/payloadcms/payload/tree/main/examples/live-preview).
|