Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 5 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
30 changes: 19 additions & 11 deletions packages/nuxt/src/app/composables/payload.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion packages/nuxt/src/core/runtime/nitro/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down