Skip to content

Commit

Permalink
fix: cannot navigate on toppage (#2240)
Browse files Browse the repository at this point in the history
  • Loading branch information
kazupon authored Jul 18, 2023
1 parent eb55bc3 commit 53161c6
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 17 deletions.
30 changes: 30 additions & 0 deletions specs/fixtures/issues/1889/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script lang="ts" setup>
const localePath = useLocalePath()
</script>
<template>
<div>
<button
v-for="locale in $i18n.locales"
:id="locale.code"
:key="locale.code"
@click="$i18n.setLocale(locale.code)"
>
{{ locale.name }}
</button>
</div>

<nuxt-page />

<p>
Test:
<nuxt-link id="disabled-route" :to="localePath('/disabled-localized-route')">
Page with disabled localized route
</nuxt-link>
</p>
</template>

<style lang="css" scoped>
button {
margin-right: 16px;
}
</style>
3 changes: 3 additions & 0 deletions specs/fixtures/issues/1889/locales/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"hello": "Hello!"
}
3 changes: 3 additions & 0 deletions specs/fixtures/issues/1889/locales/fr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"hello": "Bonjour!"
}
3 changes: 3 additions & 0 deletions specs/fixtures/issues/1889/locales/pl.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"hello": "Witaj!"
}
33 changes: 33 additions & 0 deletions specs/fixtures/issues/1889/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
modules: ['@nuxtjs/i18n'],
i18n: {
locales: [
{
code: 'en',
flag: 'us',
iso: 'en-US',
file: 'en.json',
name: 'English'
},
{ code: 'pl', flag: 'pl', iso: 'pl-PL', file: 'pl.json', name: 'Polski' },
{
code: 'fr',
flag: 'fr',
iso: 'fr-FR',
file: 'fr.json',
name: 'Français'
}
],
defaultLocale: 'en',
strategy: 'prefix',
langDir: 'locales',
detectBrowserLanguage: {
useCookie: true,
// cookieKey: 'locale',
// fallbackLocale: 'en',
alwaysRedirect: false,
redirectOn: 'root'
}
}
})
14 changes: 14 additions & 0 deletions specs/fixtures/issues/1889/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "nuxt3-test-issues-1889",
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview"
},
"devDependencies": {
"@nuxtjs/i18n": "latest",
"nuxt": "latest"
}
}
10 changes: 10 additions & 0 deletions specs/fixtures/issues/1889/pages/disabled-localized-route.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<template>
<div>
<h1 id="disable-route-text">Page with disabled localized route</h1>
<nuxt-link id="goto-home" :to="localePath('/')"> Goto Home </nuxt-link>
</div>
</template>

<script lang="ts" setup>
defineI18nRoute(false)
</script>
3 changes: 3 additions & 0 deletions specs/fixtures/issues/1889/pages/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<h1 id="hello-text">{{ $t('hello') }}</h1>
</template>
28 changes: 28 additions & 0 deletions specs/issues/1889.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { test, expect, describe } from 'vitest'
import { fileURLToPath } from 'node:url'
import { setup, createPage, url } from '../utils'
import { getText } from '../helper'

describe('#1889', async () => {
await setup({
rootDir: fileURLToPath(new URL(`../fixtures/issues/1889`, import.meta.url))
})

test('navigate work on `defineI18nRoute(false)`', async () => {
const home = url('/')
const page = await createPage()
await page.goto(home)

// switch 'pl' locale
await page.locator('#pl').click()
expect(await getText(page, '#hello-text')).toEqual('Witaj!')

// navigate to disabled route
await page.locator('#disabled-route').click()
expect(await getText(page, '#disable-route-text')).toEqual('Page with disabled localized route')

// back to home
await page.locator('#goto-home').click()
expect(await getText(page, '#hello-text')).toEqual('Witaj!')
})
})
4 changes: 2 additions & 2 deletions src/runtime/plugins/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ export default defineNuxtPlugin(async nuxt => {
notInitialSetup = false
}

const redirectPath = detectRedirect(route, nuxtContext, locale, getLocaleFromRoute, nuxtI18nOptions)
const redirectPath = detectRedirect({ to: route }, nuxtContext, locale, getLocaleFromRoute, nuxtI18nOptions)
__DEBUG__ && console.log('redirectPath on setLocale', redirectPath)

await navigate(
Expand Down Expand Up @@ -446,7 +446,7 @@ export default defineNuxtPlugin(async nuxt => {
notInitialSetup = false
}

const redirectPath = detectRedirect(to, nuxtContext, locale, getLocaleFromRoute, nuxtI18nOptions)
const redirectPath = detectRedirect({ to, from }, nuxtContext, locale, getLocaleFromRoute, nuxtI18nOptions)
__DEBUG__ && console.log('redirectPath on locale-changing middleware', redirectPath)

return navigate(
Expand Down
32 changes: 17 additions & 15 deletions src/runtime/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
proxyNuxt,
DefaultDetectBrowserLanguageFromResult
} from '#build/i18n.internal.mjs'
import { joinURL } from 'ufo'
import { joinURL, isEqual } from 'ufo'

import type {
Route,
Expand Down Expand Up @@ -281,7 +281,10 @@ export function detectLocale<Context extends NuxtApp = NuxtApp>(
}

export function detectRedirect<Context extends NuxtApp = NuxtApp>(
route: Route | RouteLocationNormalized | RouteLocationNormalizedLoaded,
route: {
to: Route | RouteLocationNormalized | RouteLocationNormalizedLoaded
from?: Route | RouteLocationNormalized | RouteLocationNormalizedLoaded
},
context: Context,
targetLocale: Locale,
routeLocaleGetter: ReturnType<typeof createLocaleFromRouteGetter>,
Expand All @@ -301,21 +304,20 @@ export function detectRedirect<Context extends NuxtApp = NuxtApp>(
strategy !== 'no_prefix' &&
// skip if already on the new locale unless the strategy is "prefix_and_default" and this is the default
// locale, in which case we might still redirect as we prefer unprefixed route in this case.
(routeLocaleGetter(route) !== targetLocale || (strategy === 'prefix_and_default' && targetLocale === defaultLocale))
(routeLocaleGetter(route.to) !== targetLocale ||
(strategy === 'prefix_and_default' && targetLocale === defaultLocale))
) {
const { fullPath } = route
const decodedRoute = decodeURI(fullPath)
const { fullPath } = route.to
// the current route could be 404 in which case attempt to find matching route using the full path
const routePath = context.$localePath(fullPath, targetLocale)
const routePath = context.$switchLocalePath(targetLocale) || context.$localePath(fullPath, targetLocale)
__DEBUG__ && console.log('detectRedirect: calculate routePath -> ', routePath, fullPath)
if (
isString(routePath) &&
routePath &&
routePath !== fullPath &&
routePath !== decodedRoute &&
!routePath.startsWith('//')
) {
redirectPath = routePath
if (isString(routePath) && routePath && !isEqual(routePath, fullPath) && !routePath.startsWith('//')) {
/**
* NOTE: for #1889, #2226
* If it's the same as the previous route path, respect the current route without redirecting.
* (If an empty string is set, the current route is respected. after this function return, it's pass navigate function)
*/
redirectPath = !(route.from && route.from.fullPath === routePath) ? routePath : ''
}
}

Expand All @@ -330,7 +332,7 @@ export function detectRedirect<Context extends NuxtApp = NuxtApp>(
*/
const switchLocalePath = useSwitchLocalePath({
i18n: getComposer(context.$i18n),
route,
route: route.to,
router: context.$router
})
const routePath = switchLocalePath(targetLocale)
Expand Down

0 comments on commit 53161c6

Please sign in to comment.