diff --git a/packages/next/src/views/Document/index.tsx b/packages/next/src/views/Document/index.tsx index d0ea1633a9e..8d1fafdb6f0 100644 --- a/packages/next/src/views/Document/index.tsx +++ b/packages/next/src/views/Document/index.tsx @@ -392,7 +392,9 @@ export const renderDocument = async ({ diff --git a/packages/ui/src/providers/LivePreview/index.tsx b/packages/ui/src/providers/LivePreview/index.tsx index 5bce1a3661d..27e72b2d571 100644 --- a/packages/ui/src/providers/LivePreview/index.tsx +++ b/packages/ui/src/providers/LivePreview/index.tsx @@ -98,6 +98,10 @@ export const LivePreviewProvider: React.FC = ({ incomingURL = formatAbsoluteURL(_incomingURL) } + if (!incomingURL) { + setIsLivePreviewing(false) + } + if (incomingURL !== url) { setAppIsReady(false) setURL(incomingURL) diff --git a/test/live-preview/collections/NoURL.ts b/test/live-preview/collections/ConditionalURL.ts similarity index 79% rename from test/live-preview/collections/NoURL.ts rename to test/live-preview/collections/ConditionalURL.ts index fde67517f06..c256df4b605 100644 --- a/test/live-preview/collections/NoURL.ts +++ b/test/live-preview/collections/ConditionalURL.ts @@ -1,7 +1,7 @@ import type { CollectionConfig } from 'payload' -export const NoURLCollection: CollectionConfig = { - slug: 'no-url', +export const ConditionalURL: CollectionConfig = { + slug: 'conditional-url', admin: { livePreview: { url: ({ data }) => (data?.enabled ? '/live-preview/static' : null), diff --git a/test/live-preview/collections/StaticURL.ts b/test/live-preview/collections/StaticURL.ts index e80cd3db51e..489f3c76b0b 100644 --- a/test/live-preview/collections/StaticURL.ts +++ b/test/live-preview/collections/StaticURL.ts @@ -4,7 +4,7 @@ export const StaticURLCollection: CollectionConfig = { slug: 'static-url', admin: { livePreview: { - url: '/live-preview/hello-world', + url: '/live-preview/static', }, }, fields: [ diff --git a/test/live-preview/config.ts b/test/live-preview/config.ts index 6631fd91a50..3d5cadd3cb4 100644 --- a/test/live-preview/config.ts +++ b/test/live-preview/config.ts @@ -6,9 +6,9 @@ import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js' import { MediaBlock } from './blocks/MediaBlock/index.js' import { Categories } from './collections/Categories.js' import { CollectionLevelConfig } from './collections/CollectionLevelConfig.js' +import { ConditionalURL } from './collections/ConditionalURL.js' import { CustomLivePreview } from './collections/CustomLivePreview.js' import { Media } from './collections/Media.js' -import { NoURLCollection } from './collections/NoURL.js' import { Pages } from './collections/Pages.js' import { Posts } from './collections/Posts.js' import { SSR } from './collections/SSR.js' @@ -68,7 +68,7 @@ export default buildConfigWithDefaults({ CollectionLevelConfig, StaticURLCollection, CustomLivePreview, - NoURLCollection, + ConditionalURL, ], globals: [Header, Footer], onInit: seed, diff --git a/test/live-preview/e2e.spec.ts b/test/live-preview/e2e.spec.ts index a913ff82df9..64b1a48a683 100644 --- a/test/live-preview/e2e.spec.ts +++ b/test/live-preview/e2e.spec.ts @@ -179,22 +179,47 @@ describe('Live Preview', () => { await expect.poll(async () => iframe.getAttribute('src')).toMatch(/\/live-preview/) }) - test('collection — does not render iframe when live preview url is falsy', async () => { - const noURL = new AdminUrlUtil(serverURL, 'no-url') + test('collection — does not render live preview when url is null', async () => { + const noURL = new AdminUrlUtil(serverURL, 'conditional-url') await page.goto(noURL.create) await page.locator('#field-title').fill('No URL') await saveDocAndAssert(page) + + // No toggler should render const toggler = page.locator('button#live-preview-toggler') await expect(toggler).toBeHidden() await expect(page.locator('iframe.live-preview-iframe')).toBeHidden() + // Check the `enabled` field const enabledCheckbox = page.locator('#field-enabled') await enabledCheckbox.check() await saveDocAndAssert(page) + // Toggler is present but not iframe await expect(toggler).toBeVisible() - await toggleLivePreview(page) - await expect(page.locator('iframe.live-preview-iframe')).toBeVisible() + await expect(page.locator('iframe.live-preview-iframe')).toBeHidden() + + // Toggle the iframe back on, which will save to prefs + // We need to explicitly test for this, as we don't want live preview to suddenly appear + await toggleLivePreview(page, { + targetState: 'on', + }) + + // Uncheck the `enabled` field + await enabledCheckbox.uncheck() + await saveDocAndAssert(page) + + // Toggler and iframe are gone + await expect(toggler).toBeHidden() + await expect(page.locator('iframe.live-preview-iframe')).toBeHidden() + + // Check the `enabled` field + await enabledCheckbox.check() + await saveDocAndAssert(page) + + // Toggler is present but still not iframe + await expect(toggler).toBeVisible() + await expect(page.locator('iframe.live-preview-iframe')).toBeHidden() }) test('collection — retains static URL across edits', async () => { @@ -204,12 +229,12 @@ describe('Live Preview', () => { await toggleLivePreview(page, { targetState: 'on' }) const iframe = page.locator('iframe.live-preview-iframe') - await expect.poll(async () => iframe.getAttribute('src')).toMatch(/\/live-preview\/hello/) + await expect.poll(async () => iframe.getAttribute('src')).toMatch(/\/live-preview\/static/) const titleField = page.locator('#field-title') await titleField.fill('New Title') await saveDocAndAssert(page) - await expect.poll(async () => iframe.getAttribute('src')).toMatch(/\/live-preview\/hello/) + await expect.poll(async () => iframe.getAttribute('src')).toMatch(/\/live-preview\/static/) }) test('collection csr — iframe reflects form state on change', async () => {