fix(nuxt): respect baseurl when redirecting (and universal router) (#4933)

* fix(nuxt): respect baseurl when redirecting (and universal router)

* test: add test case for redirect
This commit is contained in:
Daniel Roe 2022-05-11 19:33:29 +02:00 committed by GitHub
parent 7e89fe8f6c
commit cad4edd5a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 18 additions and 10 deletions

View File

@ -1,6 +1,7 @@
import type { Router, RouteLocationNormalizedLoaded, NavigationGuard, RouteLocationNormalized, RouteLocationRaw, NavigationFailure } from 'vue-router' import type { Router, RouteLocationNormalizedLoaded, NavigationGuard, RouteLocationNormalized, RouteLocationRaw, NavigationFailure } from 'vue-router'
import { sendRedirect } from 'h3' import { sendRedirect } from 'h3'
import { useNuxtApp } from '#app' import { joinURL } from 'ufo'
import { useNuxtApp, useRuntimeConfig } from '#app'
export const useRouter = () => { export const useRouter = () => {
return useNuxtApp()?.$router as Router return useNuxtApp()?.$router as Router
@ -66,7 +67,7 @@ export const navigateTo = (to: RouteLocationRaw, options: NavigateToOptions = {}
if (process.server) { if (process.server) {
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
if (nuxtApp.ssrContext && nuxtApp.ssrContext.event) { if (nuxtApp.ssrContext && nuxtApp.ssrContext.event) {
const redirectLocation = router.resolve(to).fullPath || '/' const redirectLocation = joinURL(useRuntimeConfig().app.baseURL, router.resolve(to).fullPath || '/')
return nuxtApp.callHook('app:redirected').then(() => sendRedirect(nuxtApp.ssrContext.event, redirectLocation, options.redirectCode || 301)) return nuxtApp.callHook('app:redirected').then(() => sendRedirect(nuxtApp.ssrContext.event, redirectLocation, options.redirectCode || 301))
} }
} }

View File

@ -1,5 +1,5 @@
import { reactive, h } from 'vue' import { reactive, h } from 'vue'
import { parseURL, parseQuery, withoutBase, isEqual } from 'ufo' import { parseURL, parseQuery, withoutBase, isEqual, joinURL } from 'ufo'
import { createError } from 'h3' import { createError } from 'h3'
import { defineNuxtPlugin } from '..' import { defineNuxtPlugin } from '..'
import { callWithNuxt } from '../nuxt' import { callWithNuxt } from '../nuxt'
@ -102,6 +102,7 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>((nuxtApp) => {
hooks[hook].push(guard) hooks[hook].push(guard)
return () => hooks[hook].splice(hooks[hook].indexOf(guard), 1) return () => hooks[hook].splice(hooks[hook].indexOf(guard), 1)
} }
const baseURL = useRuntimeConfig().app.baseURL
const route: Route = reactive(getRouteFromPath(initialURL)) const route: Route = reactive(getRouteFromPath(initialURL))
async function handleNavigation (url: string, replace?: boolean): Promise<void> { async function handleNavigation (url: string, replace?: boolean): Promise<void> {
@ -124,7 +125,7 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>((nuxtApp) => {
// Perform navigation // Perform navigation
Object.assign(route, to) Object.assign(route, to)
if (process.client) { if (process.client) {
window.history[replace ? 'replaceState' : 'pushState']({}, '', url) window.history[replace ? 'replaceState' : 'pushState']({}, '', joinURL(baseURL, url))
if (!nuxtApp.isHydrating) { if (!nuxtApp.isHydrating) {
// Clear any existing errors // Clear any existing errors
await callWithNuxt(nuxtApp, clearError) await callWithNuxt(nuxtApp, clearError)

View File

@ -148,12 +148,9 @@ describe('head tags', () => {
describe('navigate', () => { describe('navigate', () => {
it('should redirect to index with navigateTo', async () => { it('should redirect to index with navigateTo', async () => {
const html = await $fetch('/navigate-to/') const { headers } = await fetch('/navigate-to/', { redirect: 'manual' })
// Snapshot expect(headers.get('location')).toEqual('/')
// expect(html).toMatchInlineSnapshot()
expect(html).toContain('Hello Nuxt 3!')
}) })
}) })
@ -368,6 +365,15 @@ describe('dynamic paths', () => {
} }
}) })
it('should use baseURL when redirecting', async () => {
process.env.NUXT_APP_BUILD_ASSETS_DIR = '/_other/'
process.env.NUXT_APP_BASE_URL = '/foo/'
await startServer()
const { headers } = await fetch('/foo/navigate-to/', { redirect: 'manual' })
expect(headers.get('location')).toEqual('/foo/')
})
it('should allow setting CDN URL', async () => { it('should allow setting CDN URL', async () => {
process.env.NUXT_APP_BASE_URL = '/foo/' process.env.NUXT_APP_BASE_URL = '/foo/'
process.env.NUXT_APP_CDN_URL = 'https://example.com/' process.env.NUXT_APP_CDN_URL = 'https://example.com/'

View File

@ -3,5 +3,5 @@
</template> </template>
<script setup> <script setup>
navigateTo('/', { replace: true }) await navigateTo('/', { replace: true })
</script> </script>