diff --git a/docs/3.api/3.utils/prerender-routes.md b/docs/3.api/3.utils/prerender-routes.md
new file mode 100644
index 0000000000..f672364210
--- /dev/null
+++ b/docs/3.api/3.utils/prerender-routes.md
@@ -0,0 +1,20 @@
+---
+description: prerenderRoutes hints to Nitro to prerender an additional route.
+---
+
+# `prerenderRoutes`
+
+When prerendering, you can hint to Nitro to prerender additional paths, even if their URLs do not show up in the HTML of the generated page.
+
+`prerenderRoutes` can only be called within component setup functions, plugins, and route middleware.
+
+```js
+const route = useRoute()
+
+prerenderRoutes('/')
+prerenderRoutes(['/', '/about'])
+```
+
+::alert{icon=👉}
+In the browser, or if called outside prerendering, `prerenderRoutes` will have no effect.
+::
diff --git a/docs/3.api/4.advanced/2.kit.md b/docs/3.api/4.advanced/2.kit.md
index 25d4cd3c3b..811b95fa8e 100644
--- a/docs/3.api/4.advanced/2.kit.md
+++ b/docs/3.api/4.advanced/2.kit.md
@@ -88,7 +88,7 @@ description: Nuxt Kit provides composable utilities to help interacting with Nux
- `addDevServerHandler (handler)`
- `useNitro()` (only usable after `ready` hook)
- `addServerPlugin`
-- `addPrerenderRoutes`
+- `prerenderRoutes`
### Resolving
diff --git a/packages/kit/src/nitro.ts b/packages/kit/src/nitro.ts
index 9f46e41241..02f84eef6b 100644
--- a/packages/kit/src/nitro.ts
+++ b/packages/kit/src/nitro.ts
@@ -45,7 +45,7 @@ export function addServerPlugin (plugin: string) {
/**
* Adds routes to be prerendered
*/
-export function addPrerenderRoutes (routes: string | string[]) {
+export function prerenderRoutes (routes: string | string[]) {
const nuxt = useNuxt()
if (!Array.isArray(routes)) {
routes = [routes]
diff --git a/packages/nuxt/src/app/components/nuxt-island.ts b/packages/nuxt/src/app/components/nuxt-island.ts
index 0de8298589..6daaab8d26 100644
--- a/packages/nuxt/src/app/components/nuxt-island.ts
+++ b/packages/nuxt/src/app/components/nuxt-island.ts
@@ -11,7 +11,7 @@ import type { FetchResponse } from 'ofetch'
import type { NuxtIslandResponse } from '../../core/runtime/nitro/renderer'
import { getFragmentHTML, getSlotProps } from './utils'
import { useNuxtApp, useRuntimeConfig } from '#app/nuxt'
-import { useRequestEvent } from '#app/composables/ssr'
+import { prerenderRoutes, useRequestEvent } from '#app/composables/ssr'
// @ts-expect-error virtual file
import { remoteComponentIslands } from '#build/nuxt.config.mjs'
@@ -127,7 +127,7 @@ export default defineComponent({
if (import.meta.server && import.meta.prerender) {
const hints = r.headers.get('x-nitro-prerender')
if (hints) {
- appendResponseHeader(event, 'x-nitro-prerender', hints)
+ prerenderRoutes(hints)
}
}
setPayload(key, result)
diff --git a/packages/nuxt/src/app/composables/index.ts b/packages/nuxt/src/app/composables/index.ts
index 25a7b3b660..a815dbd05e 100644
--- a/packages/nuxt/src/app/composables/index.ts
+++ b/packages/nuxt/src/app/composables/index.ts
@@ -23,7 +23,7 @@ export { useFetch, useLazyFetch } from './fetch'
export type { FetchResult, UseFetchOptions } from './fetch'
export { useCookie } from './cookie'
export type { CookieOptions, CookieRef } from './cookie'
-export { useRequestHeaders, useRequestEvent, useRequestFetch, setResponseStatus } from './ssr'
+export { prerenderRoutes, useRequestHeaders, useRequestEvent, useRequestFetch, setResponseStatus } from './ssr'
export { onNuxtReady } from './ready'
export { abortNavigation, addRouteMiddleware, defineNuxtRouteMiddleware, onBeforeRouteLeave, onBeforeRouteUpdate, setPageLayout, navigateTo, useRoute, useRouter } from './router'
export type { AddRouteMiddlewareOptions, RouteMiddleware } from './router'
diff --git a/packages/nuxt/src/app/composables/ssr.ts b/packages/nuxt/src/app/composables/ssr.ts
index f81b0d8d5c..69fc78dd5a 100644
--- a/packages/nuxt/src/app/composables/ssr.ts
+++ b/packages/nuxt/src/app/composables/ssr.ts
@@ -1,5 +1,5 @@
import type { H3Event } from 'h3'
-import { setResponseStatus as _setResponseStatus, getRequestHeaders } from 'h3'
+import { setResponseStatus as _setResponseStatus, appendHeader, getRequestHeaders } from 'h3'
import type { NuxtApp } from '../nuxt'
import { useNuxtApp } from '../nuxt'
@@ -35,3 +35,10 @@ export function setResponseStatus (arg1: H3Event | number | undefined, arg2?: nu
}
return _setResponseStatus(useRequestEvent(), arg1, arg2 as string | undefined)
}
+
+export function prerenderRoutes (path: string | string[]) {
+ if (!process.server || !process.env.prerender) { return }
+
+ const paths = Array.isArray(path) ? path : [path]
+ appendHeader(useRequestEvent(), 'x-nitro-prerender', paths.map(p => encodeURIComponent(p)).join(', '))
+}
diff --git a/packages/nuxt/src/imports/presets.ts b/packages/nuxt/src/imports/presets.ts
index 8e3dab3bab..54b3eaedfe 100644
--- a/packages/nuxt/src/imports/presets.ts
+++ b/packages/nuxt/src/imports/presets.ts
@@ -37,6 +37,7 @@ const appPreset = defineUnimportPreset({
'useRequestURL',
'setResponseStatus',
'setPageLayout',
+ 'prerenderRoutes',
'onNuxtReady',
'useRouter',
'useRoute',
diff --git a/test/fixtures/basic/components/ServerOnlyComponent.server.vue b/test/fixtures/basic/components/ServerOnlyComponent.server.vue
index e0c5945c1e..a775c99524 100644
--- a/test/fixtures/basic/components/ServerOnlyComponent.server.vue
+++ b/test/fixtures/basic/components/ServerOnlyComponent.server.vue
@@ -1,7 +1,5 @@
diff --git a/test/nuxt/composables.test.ts b/test/nuxt/composables.test.ts
index 8d8ad83c4d..606a292138 100644
--- a/test/nuxt/composables.test.ts
+++ b/test/nuxt/composables.test.ts
@@ -47,6 +47,7 @@ describe('composables', () => {
'getRouteRules',
'onNuxtReady',
'setResponseStatus',
+ 'prerenderRoutes',
'useRequestEvent',
'useRequestFetch',
'isPrerendered',
@@ -200,6 +201,7 @@ describe('ssr composables', () => {
expect(useRequestEvent()).toBeUndefined()
expect(useRequestFetch()).toEqual($fetch)
expect(useRequestHeaders()).toEqual({})
+ expect(prerenderRoutes('/')).toBeUndefined()
})
})