feat(nuxt): add prerenderRoutes ssr composable (#22863)

This commit is contained in:
Daniel Roe 2023-09-28 11:54:22 +01:00 committed by GitHub
parent 4b5e6ff195
commit a06d5247ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 37 additions and 9 deletions

View File

@ -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.
::

View File

@ -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

View File

@ -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]

View File

@ -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)

View File

@ -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'

View File

@ -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(', '))
}

View File

@ -37,6 +37,7 @@ const appPreset = defineUnimportPreset({
'useRequestURL',
'setResponseStatus',
'setPageLayout',
'prerenderRoutes',
'onNuxtReady',
'useRouter',
'useRoute',

View File

@ -1,7 +1,5 @@
<script setup>
import { appendResponseHeader } from 'h3'
appendResponseHeader(useRequestEvent(), 'x-nitro-prerender', '/some/url/from/server-only/component')
prerenderRoutes(['/some/url/from/server-only/component'])
</script>
<template>

View File

@ -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()
})
})