How to force default locale in the URL when clicking a link in Next.js
Asked Answered
U

3

8

For the SEO purposes I need to set up English as default language -> mynextapp.com/ when user enters the website, he/she can choose between ENGLISH or FRENCH, if English is selected the url will change to mynextapp.com/en, if the French will be chosen -> mynextapp.com/fr

Currently I am using the build in option in Next - i18n:

i18n: {
    locales: ['en', 'fr'],
    defaultLocale: 'en',
},

But this allows me to have English only as a default path = mynextapp.com/

Language Switcher:

    <Link
        href="/"
        locale={router.locale === 'en' ? 'fr' : 'en'}
    >
        <a>Switch</a>
    </Link>

Is there a way how to handle the same language under different urls? So that when you click on "en" in language switcher, the url path should be myapp.com/en.

Upswell answered 13/3, 2021 at 16:26 Comment(4)
I'm not sure I understand what the issue is? Your default language, english in this case, will be available under / and /en routes.Determinism
@Determinism yes, it is available when you manually add it to url, but when you click on Link, where I want to switch between Languages (en/fr) I get the new url path only for french language myapp.com/fr, but when I click on English the url is just myapp.com/Upswell
Ah, so you want to force the english (default) locale to have /en in the URL when clicking that link.Determinism
Exactly. When you enter the website url should be myapp.com/ and it should be in English (as it is now) by default. But when you click on "en" in language switcher, the url path should be myapp.com/en (still in English)Upswell
D
6

To force the default language to add the locale to the URL you could pass it to the href directly, and opt-out of automatically handling the locale prefixing by setting locale to false.

<Link href={`/${router.locale === 'en' ? 'fr' : 'en'}`} locale={false}>
    <a>Switch</a>
</Link>

If you want all your Links to behave this way, and also force the default locale on the URL, the same logic would need to be applied.

Assuming you have a link to the /about page, it would look like the following.

<Link href={`/${router.locale}/about`} locale={false}>
    <a>About Page</a>
</Link>

If using next/router to do the routing, the same logic can also be applied.

router.push(`/${router.locale}/about`, undefined, { locale: false });
Determinism answered 13/3, 2021 at 17:52 Comment(6)
Thank you for post, this could be correct, although when I click on English Flag and yes, it does set up url to myapp.com/en, but when I click on other link - let's say about us page, the url does not stay with /en, as it should. When I am on /fr path, the path is staying the same even when I click on other pages links.Upswell
You'll need to apply this to all the Link's you have, so they all follow this same logic. You can create a wrapper around Link for reusability.Determinism
But that would just keep switching languages on every link, or am I missing something ?Upswell
I got it now! Makes perfect sense. Thanks!Upswell
If I could ask one more question, I am using Prismic as my "backend" CMS so I am fetching the links in my navbar from there based on it's id, so I can not specify each link as explained above (can be done only on buttons on pages". Do you have any experience with that ?Upswell
That may require some clarifications from you, so I would suggest you create a new question for it here on StackOverflow with the detailed issue you're having.Determinism
P
0

For future reference, I managed to get my code working by routing to the other language (2 locales, one of them default) and have the default prefix always in the URL by using the following redirecting logic in my language switcher:

i18n.changeLanguage(i18n.language === Locales.EN ? Locales.NL : Locales.EN);
router.push(
  `/${i18n.language}${router.pathname}`,
  `/${i18n.language}${router.asPath}`,
  {
    locale: false
  }
);
Phalangeal answered 26/8, 2022 at 11:11 Comment(0)
F
0

How to use?

import { useLocale } from "next-intl";

...

  console.log(useLocale()); // en

Fiann answered 25/5, 2024 at 20:14 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.