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)