From f2868f8c72320009e4502f97456b13f77c6b0322 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 20 Jun 2024 20:26:46 +0100 Subject: [PATCH] fix(nuxt): resolve routes when `navigateTo` called with `open` (#27742) --- packages/nuxt/src/app/components/nuxt-link.ts | 8 ++------ packages/nuxt/src/app/composables/router.ts | 11 +++++++++-- packages/nuxt/test/nuxt-link.test.ts | 6 +++++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/nuxt/src/app/components/nuxt-link.ts b/packages/nuxt/src/app/components/nuxt-link.ts index e4fa62d8a4..a126078b8a 100644 --- a/packages/nuxt/src/app/components/nuxt-link.ts +++ b/packages/nuxt/src/app/components/nuxt-link.ts @@ -8,10 +8,10 @@ import type { } from 'vue' import { computed, defineComponent, h, inject, onBeforeUnmount, onMounted, provide, ref, resolveComponent } from 'vue' import type { RouteLocation, RouteLocationRaw, Router, RouterLink, RouterLinkProps, useLink } from '#vue-router' -import { hasProtocol, joinURL, parseQuery, withQuery, withTrailingSlash, withoutTrailingSlash } from 'ufo' +import { hasProtocol, joinURL, parseQuery, withTrailingSlash, withoutTrailingSlash } from 'ufo' import { preloadRouteComponents } from '../composables/preload' import { onNuxtReady } from '../composables/ready' -import { navigateTo, useRouter } from '../composables/router' +import { navigateTo, resolveRouteObject, useRouter } from '../composables/router' import { useNuxtApp, useRuntimeConfig } from '../nuxt' import { cancelIdleCallback, requestIdleCallback } from '../compat/idle-callback' @@ -495,7 +495,3 @@ function isSlowConnection () { if (cn && (cn.saveData || /2g/.test(cn.effectiveType))) { return true } return false } - -function resolveRouteObject (to: Exclude) { - return withQuery(to.path || '', to.query || {}) + (to.hash ? '#' + to.hash : '') -} diff --git a/packages/nuxt/src/app/composables/router.ts b/packages/nuxt/src/app/composables/router.ts index d6395e5832..fad568a885 100644 --- a/packages/nuxt/src/app/composables/router.ts +++ b/packages/nuxt/src/app/composables/router.ts @@ -1,6 +1,6 @@ import { getCurrentInstance, hasInjectionContext, inject, onScopeDispose } from 'vue' import type { Ref } from 'vue' -import type { NavigationFailure, NavigationGuard, RouteLocationNormalized, RouteLocationPathRaw, RouteLocationRaw, Router, useRoute as _useRoute, useRouter as _useRouter } from '#vue-router' +import type { NavigationFailure, NavigationGuard, RouteLocationNormalized, RouteLocationRaw, Router, useRoute as _useRoute, useRouter as _useRouter } from '#vue-router' import { sanitizeStatusCode } from 'h3' import { hasProtocol, isScriptProtocol, joinURL, withQuery } from 'ufo' @@ -120,7 +120,7 @@ export const navigateTo = (to: RouteLocationRaw | undefined | null, options?: Na to = '/' } - const toPath = typeof to === 'string' ? to : (withQuery((to as RouteLocationPathRaw).path || '/', to.query || {}) + (to.hash || '')) + const toPath = typeof to === 'string' ? to : 'path' in to ? resolveRouteObject(to) : useRouter().resolve(to).href // Early open handler if (import.meta.client && options?.open) { @@ -252,3 +252,10 @@ export const setPageLayout = (layout: unknown extends PageMeta['layout'] ? strin useRoute().meta.layout = layout as Exclude } } + +/** + * @internal + */ +export function resolveRouteObject (to: Exclude) { + return withQuery(to.path || '', to.query || {}) + (to.hash || '') +} diff --git a/packages/nuxt/test/nuxt-link.test.ts b/packages/nuxt/test/nuxt-link.test.ts index a712d0f267..40e714045d 100644 --- a/packages/nuxt/test/nuxt-link.test.ts +++ b/packages/nuxt/test/nuxt-link.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it, vi } from 'vitest' -import type { RouteLocation } from 'vue-router' +import type { RouteLocation, RouteLocationRaw } from 'vue-router' +import { withQuery } from 'ufo' import type { NuxtLinkOptions, NuxtLinkProps } from '../src/app/components/nuxt-link' import { defineNuxtLink } from '../src/app/components/nuxt-link' import { useRuntimeConfig } from '../src/app/nuxt' @@ -25,6 +26,9 @@ vi.mock('vue', async () => { // Mocks Nuxt `useRouter()` vi.mock('../src/app/composables/router', () => ({ + resolveRouteObject (to: Exclude) { + return withQuery(to.path || '', to.query || {}) + (to.hash || '') + }, useRouter: () => ({ resolve: (route: string | RouteLocation & { to?: string }): Partial & { href?: string } => { if (typeof route === 'string') {