> ## Documentation Index
> Fetch the complete documentation index at: https://docs.frogbot.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Live Preview

> Render your front-end application in the Admin Panel and see document changes as you type.

Live Preview renders your front-end application directly within the Admin Panel. As you type, changes appear without saving a draft or publishing. It works with both [server-side](https://docs.frogbot.ai/live-preview/server.md) and [client-side](https://docs.frogbot.ai/live-preview/client.md) frontends.

The preview window loads your application in an iframe. The Admin Panel sends document changes through [`window.postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage), and the application re-renders with the data it receives.

Configure Live Preview with `admin.livePreview` in your [FrogBot config](https://docs.frogbot.ai/configuration/overview.md):

```ts theme={"theme":"tokyo-night"}
import { buildConfig } from 'frogbot'

export default buildConfig({
  admin: {
    livePreview: {
      url: 'http://localhost:3000',
      collections: ['pages'],
    },
  },
})
```

> [!NOTE]
>
> You can instead define `admin.livePreview` on an individual [collection](https://docs.frogbot.ai/configuration/collections.md#admin-options). Collection settings override root settings.

## Options

Once configured, a Live Preview button appears at the top of enabled documents.

A collection is enabled when its slug is in the root `collections` list or when it sets its own `admin.livePreview`. Its options are merged key by key over the root options, so a collection can override only `breakpoints` and keep the root `url`.

| Option | Type | Default | Description |
| - | - | - | - |
| `url` | `string \| null \| ((args: LivePreviewURLArgs) => string \| null \| undefined \| Promise<…>)` | None; no preview is shown | The iframe `src`. A function runs on the server for saved documents only, so new documents show no preview until they are saved. A function that throws or returns a non-string shows no preview; errors are logged. [More details](#url). |
| `breakpoints` | `{ label, name, width, height }[]` | `[]`; only Responsive | Device sizes available in the preview toolbar. [More details](#breakpoints). |
| `openByDefault` | `boolean` | `false` | Opens the preview window when a document loads, until the user toggles it. The user's last choice is saved per collection. |
| `collections` | `string[]` | `[]` | Root only. Collection slugs that use the root Live Preview options. |

### URL

The `url` property determines the iframe location. Use a function when it depends on the document, locale, or collection. The function runs on the server when a saved document opens and again after each save, including autosaves, so avoid expensive work inside it.

```ts theme={"theme":"tokyo-night"}
import { buildConfig } from 'frogbot'

export default buildConfig({
  admin: {
    livePreview: {
      url: ({ data, collectionConfig, locale }) =>
        `${data.tenant.url}${
          collectionConfig?.slug === 'posts'
            ? `/posts/${data.slug}`
            : `${data.slug !== 'home' ? `/${data.slug}` : ''}`
        }${locale.code ? `?locale=${locale.code}` : ''}`,
      collections: ['pages'],
    },
  },
})
```

| Argument | Type | Default | Description |
| - | - | - | - |
| `data` | `Record<string, unknown>` | Required | The saved document data. Unsaved form changes are not included. |
| `locale` | `{ code, label }` | Required | The locale being edited. `code` is the locale code, or `undefined` without localization; `label` is always an empty string. |
| `collectionConfig` | `SanitizedCollectionConfig` | Optional | The collection's sanitized configuration. [More details](https://docs.frogbot.ai/configuration/collections.md#admin-options). |
| `req` | `FrogBotRequest` | Required | The FrogBot request. The FrogBot instance is available at `req.frogbot`. |

The function can return an absolute or relative URL. Relative URLs use the protocol, domain, and port from the browser window.

```ts theme={"theme":"tokyo-night"}
url: ({ data, req }) => `${req.protocol}//${req.host}/${data.slug}`
```

Return `undefined` or `null` to disable Live Preview for a request or document:

```ts theme={"theme":"tokyo-night"}
url: ({ req }) => (req.user?.role === 'admin' ? '/hello-world' : null)
```

### Breakpoints

Breakpoints provide device sizes in the preview toolbar. Selecting one resizes the iframe to its configured dimensions.

```ts theme={"theme":"tokyo-night"}
import { buildConfig } from 'frogbot'

export default buildConfig({
  admin: {
    livePreview: {
      url: 'http://localhost:3000',
      breakpoints: [
        {
          label: 'Mobile',
          name: 'mobile',
          width: 375,
          height: 667,
        },
      ],
    },
  },
})
```

| Option | Type | Default | Description |
| - | - | - | - |
| `label` | `string` | Required | Label shown in the toolbar's breakpoint menu. |
| `name` | `string` | Required | Unique key for the breakpoint. |
| `width` | `number \| string` | Required | Iframe width in pixels. |
| `height` | `number \| string` | Required | Iframe height in pixels. |

The Responsive option is always available and fills the available area. Editors can also enter custom dimensions or open the preview in a separate resizable window.

> [!WARNING]
>
> A preview page that does not use a Live Preview hook or refresh component will load in the iframe but will not update as the document changes.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.