Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I define localized dynamic slug routes #3331

Open
Jones-S opened this issue Jan 29, 2025 · 8 comments
Open

How can I define localized dynamic slug routes #3331

Jones-S opened this issue Jan 29, 2025 · 8 comments

Comments

@Jones-S
Copy link

Jones-S commented Jan 29, 2025

I know there is some documentation out there but I think they are unclear with the following issue:

I want to define some localized slugs somewhere. I tried for example to set them in my nuxt config:

i18n: {
    strategy: 'prefix_except_default',
    detectBrowserLanguage: false,
    defaultLocale: 'de',
    baseUrl: process.env.NUXT_PUBLIC_SITE_URL,
    locales: [
      {
        name: 'Deutsch',
        code: 'de',
        language: 'de-CH',
      },
      {
        name: 'English',
        code: 'en',
        language: 'en-US',
      },
    ],
    customRoutes: 'config',
    pages: {
      yesterday: {
        en: '/yesterday',
        de: '/gestern',
      },
      dataprivacy: {
        en: '/dataprivacy',
        de: '/datenschutz',
      },
      imprint: {
        en: '/imprint',
        de: '/impressum',
      },
    },
  },

I do have a page template yesterday.vue and there everything works great. But for imprint and dataprivacy I want to use either [...slug].vue or [slug].vue.

For my lang switch I need to somehow have a function where I can pass in the wanted locale and the identifier.
I expected that this would work:

const localePath = useLocalePath()
console.log('route: ', localePath('dataprivacy', 'de'))
// expected output: '/datenschutz'

I also tried with localeRoute

const localeRoute = useLocaleRoute()

console.log('route: ', localeRoute('dataprivacy', 'de'))
// or
console.log('route: ', localeRoute({ params: { slug: 'dataprivacy' } }))

But none of this will get me back the correct paths.
I tried to also do something like:

// [slug].vue
setI18nParams({
  en: { slug: 'imprint' },
  de: { slug: 'impressum' },
})

But also that approach was not successful.

I do see this entry:
https://i18n.nuxtjs.org/docs/guide/custom-paths#dynamic-route-parameters
But somehow I just can't translate this to my case.

In the end I only want to have an access to my localized page name map.
But I also am not able to log out the vue app.i18n or something alike to get access to the raw config...

I would really be interested to get to know how I can achieve this.
Thanks a lot.

Copy link

Would you be able to provide a reproduction? 🙏

More info

Why do I need to provide a reproduction?

Reproductions make it possible for us to triage and fix issues quickly with a relatively small team. It helps us discover the source of the problem, and also can reveal assumptions you or we might be making.

What will happen?

If you've provided a reproduction, we'll remove the label and try to reproduce the issue. If we can, we'll mark it as a bug and prioritise it based on its severity and how many people we think it might affect.

If needs reproduction labeled issues don't receive any substantial activity (e.g., new comments featuring a reproduction link), we'll close them. That's not because we don't care! At any point, feel free to comment with a reproduction and we'll reopen it.

How can I create a reproduction?

We have a couple of templates for starting with a minimal reproduction:

👉 Reproduction starter (v8)
👉 Reproduction starter (v9 and higher)
👉 Reproduction starter (edge)

A public GitHub repository is also perfect. 👌

Please ensure that the reproduction is as minimal as possible. See more details in our guide.

You might also find these other articles interesting and/or helpful:

@Jones-S
Copy link
Author

Jones-S commented Jan 29, 2025

Ok here we go:
https://github.com/Jones-S/nuxt-i18n-demo
(instead of the starter I kind of need to have all the nuxt content stuff in there, so I slimmed down my current project).

You can see that the navigation between yesterday, today and tomorrow works as expected (incl. langswitch)
but with the imprint / data privacy in the footer I am currently not able to get the correct paths for the links and for the langswitch.

Thank you for looking into it.

@Jones-S
Copy link
Author

Jones-S commented Jan 31, 2025

Oh and I believe there is a problem with v9.
While the basic langswitch for the defined pages works (yesterday, today etc.)
the messages don't.

{{ t('imprint') }} for example is not found in messages.

If I downgrade to v8:
package.json
"@nuxtjs/i18n": "^8",

Both Langswitch AND messages work. (The translations in the footer are now displayed correctly).

I did not see how I missed some things I would have to do differently in v9 docs, so I believe this is a bug.
You can try this out in the same repo. (I can also open a new ticket, if wanted)

My initial question remains though.

Thank you

@BobbieGoede
Copy link
Collaborator

I did not see how I missed some things I would have to do differently in v9 docs, so I believe this is a bug. You can try this out in the same repo. (I can also open a new ticket, if wanted)

Please make sure to check out the migration docs to see the breaking changes introduced in v9. It sounds like the translations are not loaded as you haven't updated or configured the new directory structure.

My initial question remains though.

I tried running your reproduction in stackblitz but it exits when trying to start a dev server 🤔 https://stackblitz.com/edit/jones-s-nuxt-i18n-demo-q1cjubg8?file=package.json. Could you take a look if you experience the same thing, otherwise I'll try and run it locally when I have more time.

@Jones-S
Copy link
Author

Jones-S commented Jan 31, 2025

Thanks a lot for looking into it. 🙏
I have to remove husky. Forgot to remove that, we have that as a part of our stack. Then stackblitz should work.
I will also check the migration guide. I might have accidentally skipped some stuff. Sorry for that. My initial question probably remains valid though.

I'll post here again, when I've updated the repo.

@Jones-S
Copy link
Author

Jones-S commented Jan 31, 2025

Ok I pushed the removal of husky.
But I think I don't have any things messed up with the migration.
Except for the structure, which I am not sure if that is a must:

The migration guide says:

app/
server/
i18n/
  locales/
    en.json
    ja.json
  i18n.config.ts
  localeDetector.ts
nuxt.config.ts

but I dont have any json files. I have the locales directly in my nuxt config and my i18n.config.ts is defining the messages. Should work too, right?

Then my problems remain:

  • The translated messages don't work with v9
  • I don't know how I can access my localized dynamic paths

PS: I tried to run direclty on blitzstack. Now I don't see an error but it seems not to be able to connect to localhost port 3000.
I don't know how that normally works on stackblitz...

@BobbieGoede
Copy link
Collaborator

but I dont have any json files. I have the locales directly in my nuxt config and my i18n.config.ts is defining the messages. Should work too, right?

The module now looks for the i18n.config.ts file inside/relative to the i18n directory, so either move that file into an i18n directory or disable this structure temporarily to aid with migration by setting restructureDir: false. Not doing so will prevent the translations from being loaded when using v9.

You should update to v9.1.4 as it fixes a regression related to locale detection and loading on the server side.

I'm not sure how other projects use nuxt content combined with nuxt i18n, specifically the routing aspect of it, custom routes are mapped based on pages/routes, for dynamic parameters the page itself should set the translated versions of the current page using setI18nParams, this way you can switch between these using useSwitchLocalePath on that page.

Perhaps this helps you a bit further, I'm not sure when I have more time to check out how i18n routing can be fully utilized in this setup.

@Jones-S
Copy link
Author

Jones-S commented Jan 31, 2025

Oh alright, I did not get the restructuring of the directory. Sorry.

Just to summarize. I can now define the slugs with setI18nParams, and I managed to get a lang switch.

but If I have a navigation, how can I set the correct link depending on the set locale?

Assuming I have a link like

<NuxtLink
            :to="localePath('/dataprivacy')"
            class="cursor-pointer hover:underline"
            >{{ t('dataprivacy') }}</NuxtLink
          >

The text is now switching depending on the language, but the path is not.
I tried to get it via localePath('/dataprivacy', 'de') or localePath('dataprivacy', 'de').

I do see other possibilities, but I wonder how this could be done:
I have predefined slugs and localization but I only want to use the one slug.vue file.
Of course I could create yesterday.vue/today.vue etc. and then just import another file.

But I wondered if I could do this differently.

Thanks for clarification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants