Skip to content

Commit 3c4f8a3

Browse files
authored
fix(next): static live preview url corrupt after save (#13949)
As of #13631, statically defined live preview URLs become corrupt after the first save. For example, if you define your URL as a string like this: ```ts import type { CollectionConfig } from 'payload' const MyCollection: CollectionConfig = { // ... admin: { livePreview: { url: '/hello-world' } } } ``` On initial load, the iframe's src will evaluate to `.../hello-world` as expected, but from the first save onward, the url becomes `.../undefined`. This is because for statically defined URLs, the `livePreviewURL` property does not exist on the response. Despite this, we set it into state as undefined. This is true for both collections and globals. Initially reported on Discord here: https://discord.com/channels/967097582721572934/967097582721572937/1421166976113442847 --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211478736160152
1 parent ae34b6d commit 3c4f8a3

5 files changed

Lines changed: 62 additions & 4 deletions

File tree

packages/ui/src/views/Edit/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ export function DefaultEditView({
353353
setDocumentIsLocked(false)
354354
}
355355

356-
if (isLivePreviewEnabled) {
356+
if (livePreviewURL) {
357357
setLivePreviewURL(livePreviewURL)
358358
}
359359

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { CollectionConfig } from 'payload'
2+
3+
export const StaticURLCollection: CollectionConfig = {
4+
slug: 'static-url',
5+
admin: {
6+
livePreview: {
7+
url: '/live-preview/hello-world',
8+
},
9+
},
10+
fields: [
11+
{
12+
name: 'title',
13+
type: 'text',
14+
},
15+
],
16+
}

test/live-preview/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Pages } from './collections/Pages.js'
1111
import { Posts } from './collections/Posts.js'
1212
import { SSR } from './collections/SSR.js'
1313
import { SSRAutosave } from './collections/SSRAutosave.js'
14+
import { StaticURLCollection } from './collections/StaticURL.js'
1415
import { Tenants } from './collections/Tenants.js'
1516
import { Users } from './collections/Users.js'
1617
import { Footer } from './globals/Footer.js'
@@ -56,6 +57,7 @@ export default buildConfigWithDefaults({
5657
Categories,
5758
Media,
5859
CollectionLevelConfig,
60+
StaticURLCollection,
5961
],
6062
globals: [Header, Footer],
6163
onInit: seed,

test/live-preview/e2e.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,21 @@ describe('Live Preview', () => {
164164
await expect.poll(async () => iframe.getAttribute('src')).toMatch(/\/live-preview/)
165165
})
166166

167+
test('collection — retains static URL across edits', async () => {
168+
const util = new AdminUrlUtil(serverURL, 'static-url')
169+
await page.goto(util.create)
170+
await saveDocAndAssert(page)
171+
await toggleLivePreview(page, { targetState: 'on' })
172+
173+
const iframe = page.locator('iframe.live-preview-iframe')
174+
await expect.poll(async () => iframe.getAttribute('src')).toMatch(/\/live-preview\/hello/)
175+
176+
const titleField = page.locator('#field-title')
177+
await titleField.fill('New Title')
178+
await saveDocAndAssert(page)
179+
await expect.poll(async () => iframe.getAttribute('src')).toMatch(/\/live-preview\/hello/)
180+
})
181+
167182
test('collection csr — iframe reflects form state on change', async () => {
168183
await goToCollectionLivePreview(page, pagesURLUtil)
169184

test/live-preview/payload-types.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export interface Config {
7878
categories: Category;
7979
media: Media;
8080
'collection-level-config': CollectionLevelConfig;
81+
'static-url': StaticUrl;
8182
'payload-locked-documents': PayloadLockedDocument;
8283
'payload-preferences': PayloadPreference;
8384
'payload-migrations': PayloadMigration;
@@ -93,6 +94,7 @@ export interface Config {
9394
categories: CategoriesSelect<false> | CategoriesSelect<true>;
9495
media: MediaSelect<false> | MediaSelect<true>;
9596
'collection-level-config': CollectionLevelConfigSelect<false> | CollectionLevelConfigSelect<true>;
97+
'static-url': StaticUrlSelect<false> | StaticUrlSelect<true>;
9698
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
9799
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
98100
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
@@ -336,7 +338,7 @@ export interface Page {
336338
root: {
337339
type: string;
338340
children: {
339-
type: string;
341+
type: any;
340342
version: number;
341343
[k: string]: unknown;
342344
}[];
@@ -351,7 +353,7 @@ export interface Page {
351353
root: {
352354
type: string;
353355
children: {
354-
type: string;
356+
type: any;
355357
version: number;
356358
[k: string]: unknown;
357359
}[];
@@ -382,7 +384,7 @@ export interface Page {
382384
root: {
383385
type: string;
384386
children: {
385-
type: string;
387+
type: any;
386388
version: number;
387389
[k: string]: unknown;
388390
}[];
@@ -885,6 +887,16 @@ export interface CollectionLevelConfig {
885887
updatedAt: string;
886888
createdAt: string;
887889
}
890+
/**
891+
* This interface was referenced by `Config`'s JSON-Schema
892+
* via the `definition` "static-url".
893+
*/
894+
export interface StaticUrl {
895+
id: string;
896+
title?: string | null;
897+
updatedAt: string;
898+
createdAt: string;
899+
}
888900
/**
889901
* This interface was referenced by `Config`'s JSON-Schema
890902
* via the `definition` "payload-locked-documents".
@@ -927,6 +939,10 @@ export interface PayloadLockedDocument {
927939
| ({
928940
relationTo: 'collection-level-config';
929941
value: string | CollectionLevelConfig;
942+
} | null)
943+
| ({
944+
relationTo: 'static-url';
945+
value: string | StaticUrl;
930946
} | null);
931947
globalSlug?: string | null;
932948
user: {
@@ -1468,6 +1484,15 @@ export interface CollectionLevelConfigSelect<T extends boolean = true> {
14681484
updatedAt?: T;
14691485
createdAt?: T;
14701486
}
1487+
/**
1488+
* This interface was referenced by `Config`'s JSON-Schema
1489+
* via the `definition` "static-url_select".
1490+
*/
1491+
export interface StaticUrlSelect<T extends boolean = true> {
1492+
title?: T;
1493+
updatedAt?: T;
1494+
createdAt?: T;
1495+
}
14711496
/**
14721497
* This interface was referenced by `Config`'s JSON-Schema
14731498
* via the `definition` "payload-locked-documents_select".

0 commit comments

Comments
 (0)