fix(nuxt): respect `app.cdnURL` for extracted payloads (#26668)

This commit is contained in:
Miha Sedej 2024-05-23 10:18:31 +02:00 committed by GitHub
parent feeef7cb4a
commit 59ad152ae3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 12 deletions

View File

@ -20,6 +20,7 @@
"lint:knip": "pnpx knip",
"play": "nuxi dev playground",
"play:build": "nuxi build playground",
"play:generate": "nuxi generate playground",
"play:preview": "nuxi preview playground",
"test": "pnpm test:fixtures && pnpm test:fixtures:dev && pnpm test:fixtures:webpack && pnpm test:unit && pnpm test:runtime && pnpm test:types && pnpm typecheck",
"test:prepare": "jiti ./test/prepare.ts",

View File

@ -1,7 +1,7 @@
import { hasProtocol, joinURL, withoutTrailingSlash } from 'ufo'
import { parse } from 'devalue'
import { useHead } from '@unhead/vue'
import { getCurrentInstance } from 'vue'
import { getCurrentInstance, onServerPrefetch } from 'vue'
import { useNuxtApp, useRuntimeConfig } from '../nuxt'
import { useRoute } from './router'
@ -16,9 +16,9 @@ interface LoadPayloadOptions {
}
/** @since 3.0.0 */
export function loadPayload (url: string, opts: LoadPayloadOptions = {}): Record<string, any> | Promise<Record<string, any>> | null {
export async function loadPayload (url: string, opts: LoadPayloadOptions = {}): Promise<Record<string, any> | null> {
if (import.meta.server || !payloadExtraction) { return null }
const payloadURL = _getPayloadURL(url, opts)
const payloadURL = await _getPayloadURL(url, opts)
const nuxtApp = useNuxtApp()
const cache = nuxtApp._payloadCache = nuxtApp._payloadCache || {}
if (payloadURL in cache) {
@ -39,26 +39,34 @@ export function loadPayload (url: string, opts: LoadPayloadOptions = {}): Record
return cache[payloadURL]
}
/** @since 3.0.0 */
export function preloadPayload (url: string, opts: LoadPayloadOptions = {}) {
const payloadURL = _getPayloadURL(url, opts)
useHead({
link: [
{ rel: 'modulepreload', href: payloadURL },
],
export function preloadPayload (url: string, opts: LoadPayloadOptions = {}): Promise<void> {
const nuxtApp = useNuxtApp()
const promise = _getPayloadURL(url, opts).then((payloadURL) => {
nuxtApp.runWithContext(() => useHead({
link: [
{ rel: 'modulepreload', href: payloadURL },
],
}))
})
if (import.meta.server) {
onServerPrefetch(() => promise)
}
return promise
}
// --- Internal ---
const filename = renderJsonPayloads ? '_payload.json' : '_payload.js'
function _getPayloadURL (url: string, opts: LoadPayloadOptions = {}) {
async function _getPayloadURL (url: string, opts: LoadPayloadOptions = {}) {
const u = new URL(url, 'http://localhost')
if (u.host !== 'localhost' || hasProtocol(u.pathname, { acceptRelative: true })) {
throw new Error('Payload URL must not include hostname: ' + url)
}
const config = useRuntimeConfig()
const hash = opts.hash || (opts.fresh ? Date.now() : config.app.buildId)
return joinURL(config.app.baseURL, u.pathname, filename + (hash ? `?${hash}` : ''))
const cdnURL = config.app.cdnURL
const baseOrCdnURL = cdnURL && await isPrerendered(url) ? cdnURL : config.app.baseURL
return joinURL(baseOrCdnURL, u.pathname, filename + (hash ? `?${hash}` : ''))
}
async function _importPayload (payloadURL: string) {

View File

@ -327,7 +327,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
// Whether we are prerendering route
const _PAYLOAD_EXTRACTION = import.meta.prerender && process.env.NUXT_PAYLOAD_EXTRACTION && !ssrContext.noSSR && !isRenderingIsland
const payloadURL = _PAYLOAD_EXTRACTION ? joinURL(ssrContext.runtimeConfig.app.baseURL, url, process.env.NUXT_JSON_PAYLOADS ? '_payload.json' : '_payload.js') + '?' + ssrContext.runtimeConfig.app.buildId : undefined
const payloadURL = _PAYLOAD_EXTRACTION ? joinURL(ssrContext.runtimeConfig.app.cdnURL || ssrContext.runtimeConfig.app.baseURL, url, process.env.NUXT_JSON_PAYLOADS ? '_payload.json' : '_payload.js') + '?' + ssrContext.runtimeConfig.app.buildId : undefined
if (import.meta.prerender) {
ssrContext.payload.prerenderedAt = Date.now()
}