feat(nuxt): add ssr route rule to enable SPA mode (#7938)

This commit is contained in:
Daniel Roe 2022-10-11 17:03:52 +01:00 committed by GitHub
parent ee41bb6d5d
commit 5f003a9738
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 0 deletions

View File

@ -227,3 +227,9 @@ async function resolveHandlers (nuxt: Nuxt) {
devHandlers devHandlers
} }
} }
declare module 'nitropack' {
interface NitroRouteOption {
ssr?: boolean
}
}

View File

@ -3,6 +3,7 @@ import type { RenderResponse } from 'nitropack'
import type { Manifest } from 'vite' import type { Manifest } from 'vite'
import { appendHeader, getQuery } from 'h3' import { appendHeader, getQuery } from 'h3'
import devalue from '@nuxt/devalue' import devalue from '@nuxt/devalue'
import { createRouter as createMatcher } from 'radix3'
import { joinURL } from 'ufo' import { joinURL } from 'ufo'
import { renderToString as _renderToString } from 'vue/server-renderer' import { renderToString as _renderToString } from 'vue/server-renderer'
import { useRuntimeConfig, useNitroApp, defineRenderHandler } from '#internal/nitro' import { useRuntimeConfig, useNitroApp, defineRenderHandler } from '#internal/nitro'
@ -106,6 +107,9 @@ const getSPARenderer = lazyCachedFunction(async () => {
} }
}) })
// Set up route rule matcher
const routerOptions = createMatcher({ routes: useRuntimeConfig().nitro.routes })
const PAYLOAD_CACHE = (process.env.NUXT_PAYLOAD_EXTRACTION && process.env.prerender) ? new Map() : null // TODO: Use LRU cache const PAYLOAD_CACHE = (process.env.NUXT_PAYLOAD_EXTRACTION && process.env.prerender) ? new Map() : null // TODO: Use LRU cache
const PAYLOAD_URL_RE = /\/_payload(\.[a-zA-Z0-9]+)?.js(\?.*)?$/ const PAYLOAD_URL_RE = /\/_payload(\.[a-zA-Z0-9]+)?.js(\?.*)?$/
@ -128,6 +132,9 @@ export default defineRenderHandler(async (event) => {
} }
} }
// TODO: share across endpoints on event context
const routeOptions = event.context.routeOptions || routerOptions.lookup(url) || {}
// Initialize ssr context // Initialize ssr context
const ssrContext: NuxtSSRContext = { const ssrContext: NuxtSSRContext = {
url, url,
@ -138,6 +145,7 @@ export default defineRenderHandler(async (event) => {
noSSR: noSSR:
!!(process.env.NUXT_NO_SSR) || !!(process.env.NUXT_NO_SSR) ||
!!(event.req.headers['x-nuxt-no-ssr']) || !!(event.req.headers['x-nuxt-no-ssr']) ||
routeOptions.ssr === false ||
(process.env.prerender ? PRERENDER_NO_SSR_ROUTES.has(url) : false), (process.env.prerender ? PRERENDER_NO_SSR_ROUTES.has(url) : false),
error: !!ssrError, error: !!ssrError,
nuxt: undefined!, /* NuxtApp */ nuxt: undefined!, /* NuxtApp */

View File

@ -29,6 +29,12 @@ describe('server api', () => {
}) })
}) })
describe('route rules', () => {
it('should enable spa mode', async () => {
expect(await $fetch('/route-rules/spa')).toContain('serverRendered:false')
})
})
describe('pages', () => { describe('pages', () => {
it('render index', async () => { it('render index', async () => {
const html = await $fetch('/') const html = await $fetch('/')

View File

@ -19,6 +19,9 @@ export default defineNuxtConfig({
'./extends/node_modules/foo' './extends/node_modules/foo'
], ],
nitro: { nitro: {
routes: {
'/route-rules/spa': { ssr: false }
},
output: { dir: process.env.NITRO_OUTPUT_DIR }, output: { dir: process.env.NITRO_OUTPUT_DIR },
prerender: { prerender: {
routes: [ routes: [

View File

@ -0,0 +1,5 @@
<template>
<div>
should not be rendered on ssr
</div>
</template>