You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue 3 本地化(i18n@next)实现中的静态资源、URL路径翻译及路由链接问题解决方案咨询

Hey there! Let's tackle these three issues one by one with practical solutions tailored to your Vue 3 + i18n setup:

1. Fix Static Asset Loading with Language Prefixes

The problem happens because relative asset paths get resolved against the current route path (which includes the language prefix). To load assets from the root path every time, use one of these approaches:

Option 1: Use Absolute Paths

Replace relative asset paths with absolute paths starting with / (since your app's base URL is /):

<!-- Before -->
<img v-bind:src="assets/images/logo.png" alt="Logo">

<!-- After -->
<img src="/assets/images/logo.png" alt="Logo">

Option 2: Use process.env.BASE_URL

If your app might be deployed under a subpath later, use the built-in environment variable to ensure portability:

<img :src="`${process.env.BASE_URL}assets/images/logo.png`" alt="Logo">

Option 3: Configure publicPath in vue.config.js

If you need more control, set the public path explicitly (this ensures all assets are loaded from the root):

// vue.config.js
module.exports = {
  publicPath: process.env.NODE_ENV === 'production' ? '/' : '/'
}

2. Localize URL Slugs (e.g., /en/login → /it/accedi)

To translate route slugs alongside content, follow these steps:

Step 1: Add Slug Translations to Your i18n Files

Update your translation JSONs to include route slug mappings:

// lang/translations/en.json
{
  "selectLanguage": "Select Language",
  "routes": {
    "home": "",
    "login": "login",
    "register": "register"
  }
}

// lang/translations/it.json
{
  "selectLanguage": "Seleziona Lingua",
  "routes": {
    "home": "",
    "login": "accedi",
    "register": "registrati"
  }
}

Step 2: Update Route Configuration

Modify your routes to use dynamic slugs and link them to translation keys via meta:

// router/index.ts
const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'root',
    redirect: `/${process.env.VUE_APP_I18N_LOCALE}/${i18n.global.t('routes.home')}`
  },
  {
    path: '/:locale',
    component: App,
    beforeEnter: (to, from, next) => {
      const locale = to.params.locale.toString()
      const supportedLocales = process.env.VUE_APP_I18N_SUPPORTED_LOCALE.split(',')
      if (!supportedLocales.includes(locale)) return next(`/en/${i18n.global.t('routes.home', { locale: 'en' })}`)
      if (i18n.global.locale !== locale) {
        i18n.global.locale = locale
      }
      next()
    },
    children: [
      {
        path: ':slug',
        name: 'home',
        component: load('Home'),
        meta: { requiresAuth: false, slugKey: 'routes.home' }
      },
      {
        path: ':slug',
        name: 'login',
        component: load('Auth/Login'),
        meta: { requiresAuth: false, slugKey: 'routes.login' }
      },
      {
        path: ':slug',
        name: 'register',
        component: load('Auth/Register'),
        meta: { requiresAuth: false, slugKey: 'routes.register' }
      }
    ]
  }
]

Step 3: Add Route Guard to Match Slugs

Add a global guard to map incoming slugs to the correct route based on the current locale:

// router/index.ts
router.beforeEach((to, from, next) => {
  if (to.params.locale && to.params.slug) {
    const locale = to.params.locale.toString()
    const incomingSlug = to.params.slug.toString()

    // Find the route whose translated slug matches the incoming one
    const matchedRoute = routes[1].children?.find(route => {
      return i18n.global.t(route.meta.slugKey, { locale }) === incomingSlug
    })

    if (matchedRoute) {
      next({ name: matchedRoute.name, params: { locale } })
    } else {
      // Redirect to home if slug is invalid
      next(`/${locale}/${i18n.global.t('routes.home', { locale })}`)
    }
  } else {
    next()
  }

  // Keep your existing auth logic here
  const { authenticating, user } = useAuth()
})

Step 4: Update Language Switcher to Navigate to Localized Slugs

Modify the changeLanguage method to jump to the translated slug of the current route:

<!-- LanguageSwitcher.vue -->
<script>
export default defineComponent({
  // ... existing code
  methods: {
    changeLanguage(lang) {
      const currentRouteName = this.$route.name
      const translatedSlug = this.$t(`routes.${currentRouteName}`, { locale: lang })
      this.$i18n.locale = lang
      this.$router.replace(`/${lang}/${translatedSlug}`)
    }
  }
})
</script>

The issue occurs because you're using hardcoded absolute paths (like /login) instead of leveraging route names. Here's how to fix it:

Option 1: Use Route Names with Params

Always reference routes by their name and pass the current locale as a param:

<!-- Before -->
<router-link class="nav-link" to="/login">Login</router-link>

<!-- After -->
<router-link class="nav-link" :to="{ name: 'login', params: { locale: $i18n.locale } }">
  {{ $t('login') }}
</router-link>

For convenience, build a custom component that automatically injects the current locale:

<!-- components/LocalizedRouterLink.vue -->
<template>
  <router-link :to="getLocalizedRoute">
    <slot></slot>
  </router-link>
</template>

<script setup>
import { useI18n } from 'vue-i18n'
const { locale } = useI18n()

const props = defineProps({
  to: {
    type: [String, Object],
    required: true
  }
})

const getLocalizedRoute = () => {
  if (typeof props.to === 'string') {
    // Convert string paths (e.g., '/login') to locale-prefixed paths
    return `/${locale.value}${props.to}`
  } else {
    // Add locale to route object params
    return {
      ...props.to,
      params: {
        locale: locale.value,
        ...props.to.params
      }
    }
  }
}
</script>

Register it globally in main.ts:

// main.ts
import LocalizedRouterLink from '@/components/LocalizedRouterLink.vue'
createApp(App)
  // ... existing plugins
  .component('LocalizedRouterLink', LocalizedRouterLink)

Now use it anywhere in your app:

<localized-router-link to="/login">{{ $t('login') }}</localized-router-link>
<!-- Or with route name -->
<localized-router-link :to="{ name: 'login' }">{{ $t('login') }}</localized-router-link>

内容的提问来源于stack exchange,提问作者sfarzoso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 05:37:30