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", "lint:knip": "pnpx knip",
"play": "nuxi dev playground", "play": "nuxi dev playground",
"play:build": "nuxi build playground", "play:build": "nuxi build playground",
"play:generate": "nuxi generate playground",
"play:preview": "nuxi preview 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": "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", "test:prepare": "jiti ./test/prepare.ts",

View File

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

View File

@ -327,7 +327,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
// Whether we are prerendering route // Whether we are prerendering route
const _PAYLOAD_EXTRACTION = import.meta.prerender && process.env.NUXT_PAYLOAD_EXTRACTION && !ssrContext.noSSR && !isRenderingIsland 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) { if (import.meta.prerender) {
ssrContext.payload.prerenderedAt = Date.now() ssrContext.payload.prerenderedAt = Date.now()
} }