Closes #12785. Although your live preview URL can be dynamic based on document data, it is never recalculated after initial mount. This means if your URL is dependent of document data that was just changed, such as a "slug" field, the URL of the iframe does not reflect that change as expected until the window is refreshed or you navigate back. This also means that server-side live preview will crash when your front-end attempts to query using a slug that no longer exists. Here's the general flow: slug changes, autosave runs, iframe refreshes (url has old slug), 404. Now, we execute your live preview function on submit within form state, and the window responds to the new URL as expected, refreshing itself without losing its connection. Here's the result: https://github.com/user-attachments/assets/7dd3b147-ab6c-4103-8b2f-14d6bc889625 --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211094211063140
137 lines
3.1 KiB
TypeScript
137 lines
3.1 KiB
TypeScript
import type { AcceptedLanguages, I18n, I18nClient } from '@payloadcms/translations'
|
|
import type {
|
|
ImportMap,
|
|
Locale,
|
|
Payload,
|
|
PayloadRequest,
|
|
SanitizedConfig,
|
|
SanitizedPermissions,
|
|
TypedUser,
|
|
} from 'payload'
|
|
|
|
import { initI18n } from '@payloadcms/translations'
|
|
import { headers as getHeaders } from 'next/headers.js'
|
|
import {
|
|
createLocalReq,
|
|
executeAuthStrategies,
|
|
getAccessResults,
|
|
getPayload,
|
|
getRequestLanguage,
|
|
parseCookies,
|
|
} from 'payload'
|
|
|
|
import { getRequestLocale } from './getRequestLocale.js'
|
|
import { selectiveCache } from './selectiveCache.js'
|
|
|
|
type Result = {
|
|
cookies: Map<string, string>
|
|
headers: Awaited<ReturnType<typeof getHeaders>>
|
|
languageCode: AcceptedLanguages
|
|
locale?: Locale
|
|
permissions: SanitizedPermissions
|
|
req: PayloadRequest
|
|
}
|
|
|
|
type PartialResult = {
|
|
i18n: I18nClient
|
|
languageCode: AcceptedLanguages
|
|
payload: Payload
|
|
responseHeaders: Headers
|
|
user: null | TypedUser
|
|
}
|
|
|
|
// Create cache instances for different parts of our application
|
|
const partialReqCache = selectiveCache<PartialResult>('partialReq')
|
|
const reqCache = selectiveCache<Result>('req')
|
|
|
|
/**
|
|
* Initializes a full request object, including the `req` object and access control.
|
|
* As access control and getting the request locale is dependent on the current URL and
|
|
*/
|
|
export const initReq = async function ({
|
|
canSetHeaders,
|
|
configPromise,
|
|
importMap,
|
|
key,
|
|
overrides,
|
|
}: {
|
|
canSetHeaders?: boolean
|
|
configPromise: Promise<SanitizedConfig> | SanitizedConfig
|
|
importMap: ImportMap
|
|
key: string
|
|
overrides?: Parameters<typeof createLocalReq>[0]
|
|
}): Promise<Result> {
|
|
const headers = await getHeaders()
|
|
const cookies = parseCookies(headers)
|
|
|
|
const partialResult = await partialReqCache.get(async () => {
|
|
const config = await configPromise
|
|
const payload = await getPayload({ config, cron: true, importMap })
|
|
const languageCode = getRequestLanguage({
|
|
config,
|
|
cookies,
|
|
headers,
|
|
})
|
|
|
|
const i18n: I18nClient = await initI18n({
|
|
config: config.i18n,
|
|
context: 'client',
|
|
language: languageCode,
|
|
})
|
|
|
|
const { responseHeaders, user } = await executeAuthStrategies({
|
|
canSetHeaders,
|
|
headers,
|
|
payload,
|
|
})
|
|
|
|
return {
|
|
i18n,
|
|
languageCode,
|
|
payload,
|
|
responseHeaders,
|
|
user,
|
|
}
|
|
}, 'global')
|
|
|
|
return reqCache.get(async () => {
|
|
const { i18n, languageCode, payload, responseHeaders, user } = partialResult
|
|
|
|
const { req: reqOverrides, ...optionsOverrides } = overrides || {}
|
|
|
|
const req = await createLocalReq(
|
|
{
|
|
req: {
|
|
headers,
|
|
host: headers.get('host'),
|
|
i18n: i18n as I18n,
|
|
responseHeaders,
|
|
user,
|
|
...(reqOverrides || {}),
|
|
},
|
|
...(optionsOverrides || {}),
|
|
},
|
|
payload,
|
|
)
|
|
|
|
const locale = await getRequestLocale({
|
|
req,
|
|
})
|
|
|
|
req.locale = locale?.code
|
|
|
|
const permissions = await getAccessResults({
|
|
req,
|
|
})
|
|
|
|
return {
|
|
cookies,
|
|
headers,
|
|
languageCode,
|
|
locale,
|
|
permissions,
|
|
req,
|
|
}
|
|
}, key)
|
|
}
|