diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index ac83951f3d..9978172c62 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -5,6 +5,9 @@ import { useNuxtApp } from '../nuxt' import { createError } from './error' import { onNuxtReady } from './ready' +// @ts-expect-error virtual file +import { asyncDataDefaults } from '#build/nuxt.config.mjs' + export type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error' export type _Transform = (input: Input) => Output @@ -146,6 +149,7 @@ export function useAsyncData< options.lazy = options.lazy ?? false options.immediate = options.immediate ?? true + options.deep = options.deep ?? asyncDataDefaults.deep const hasCachedData = () => ![null, undefined].includes(options.getCachedData!(key) as any) @@ -153,7 +157,7 @@ export function useAsyncData< if (!nuxt._asyncData[key] || !options.immediate) { nuxt.payload._errors[key] ??= null - const _ref = options.deep !== true ? shallowRef : ref + const _ref = options.deep ? ref : shallowRef nuxt._asyncData[key] = { data: _ref(options.getCachedData!(key) ?? options.default!()), diff --git a/packages/nuxt/src/app/composables/fetch.ts b/packages/nuxt/src/app/composables/fetch.ts index f969cece81..90b3a6e060 100644 --- a/packages/nuxt/src/app/composables/fetch.ts +++ b/packages/nuxt/src/app/composables/fetch.ts @@ -3,10 +3,14 @@ import type { NitroFetchRequest, TypedInternalResponse, AvailableRouterMethod as import type { MaybeRef, Ref } from 'vue' import { computed, reactive, unref } from 'vue' import { hash } from 'ohash' + import { useRequestFetch } from './ssr' import type { AsyncData, AsyncDataOptions, KeysOf, MultiWatchSources, PickFrom } from './asyncData' import { useAsyncData } from './asyncData' +// @ts-expect-error virtual file +import { fetchDefaults } from '#build/nuxt.config.mjs' + // support uppercase methods, detail: https://github.com/nuxt/nuxt/issues/22313 type AvailableRouterMethod = _AvailableRouterMethod | Uppercase<_AvailableRouterMethod> @@ -113,6 +117,7 @@ export function useFetch< } = opts const _fetchOptions = reactive({ + ...fetchDefaults, ...fetchOptions, cache: typeof opts.cache === 'boolean' ? undefined : opts.cache }) diff --git a/packages/nuxt/src/core/templates.ts b/packages/nuxt/src/core/templates.ts index b4fce2091d..6b6cbb27af 100644 --- a/packages/nuxt/src/core/templates.ts +++ b/packages/nuxt/src/core/templates.ts @@ -338,6 +338,11 @@ export const publicPathTemplate: NuxtTemplate = { export const nuxtConfigTemplate = { filename: 'nuxt.config.mjs', getContents: (ctx: TemplateContext) => { + const fetchDefaults = { + ...ctx.nuxt.options.experimental.defaults.useFetch, + baseURL: undefined, + headers: undefined + } return [ ...Object.entries(ctx.nuxt.options.app).map(([k, v]) => `export const ${camelCase('app-' + k)} = ${JSON.stringify(v)}`), `export const renderJsonPayloads = ${!!ctx.nuxt.options.experimental.renderJsonPayloads}`, @@ -348,6 +353,8 @@ export const nuxtConfigTemplate = { `export const devPagesDir = ${ctx.nuxt.options.dev ? JSON.stringify(ctx.nuxt.options.dir.pages) : 'null'}`, `export const devRootDir = ${ctx.nuxt.options.dev ? JSON.stringify(ctx.nuxt.options.rootDir) : 'null'}`, `export const nuxtLinkDefaults = ${JSON.stringify(ctx.nuxt.options.experimental.defaults.nuxtLink)}`, + `export const asyncDataDefaults = ${JSON.stringify(ctx.nuxt.options.experimental.defaults.useAsyncData)}`, + `export const fetchDefaults = ${JSON.stringify(fetchDefaults)}`, `export const vueAppRootContainer = ${ctx.nuxt.options.app.rootId ? `'#${ctx.nuxt.options.app.rootId}'` : `'body > ${ctx.nuxt.options.app.rootTag}'`}` ].join('\n\n') } diff --git a/packages/schema/build.config.ts b/packages/schema/build.config.ts index 12b9c19376..708081b43f 100644 --- a/packages/schema/build.config.ts +++ b/packages/schema/build.config.ts @@ -21,6 +21,7 @@ export default defineBuildConfig({ externals: [ // Type imports '#app/components/nuxt-link', + 'ofetch', 'vue-router', '@nuxt/telemetry', 'vue-bundle-renderer', diff --git a/packages/schema/package.json b/packages/schema/package.json index b4a571373c..606546c6e1 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -41,6 +41,7 @@ "h3": "1.8.2", "ignore": "5.2.4", "nitropack": "2.6.3", + "ofetch": "^1.3.3", "unbuild": "latest", "unctx": "2.3.1", "vite": "4.5.0", diff --git a/packages/schema/src/config/experimental.ts b/packages/schema/src/config/experimental.ts index 804034164c..4b63a5691e 100644 --- a/packages/schema/src/config/experimental.ts +++ b/packages/schema/src/config/experimental.ts @@ -258,7 +258,15 @@ export default defineUntypedSchema({ /** @type {typeof import('#app/components/nuxt-link')['NuxtLinkOptions']} */ nuxtLink: { componentName: 'NuxtLink' - } + }, + /** + * Options that apply to `useAsyncData` (and also therefore `useFetch`) + */ + useAsyncData: { + deep: true + }, + /** @type {Pick} */ + useFetch: {} } } }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e8b6c71023..e6f91b579d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -490,6 +490,9 @@ importers: nitropack: specifier: 2.6.3 version: 2.6.3 + ofetch: + specifier: ^1.3.3 + version: 1.3.3 unbuild: specifier: latest version: 2.0.0(typescript@5.2.2)