aralroca / next-translate

Next.js plugin + i18n API for Next.js 🌍 - Load page translations and use them in an easy way!
MIT License
2.64k stars 206 forks source link

Localized routes #154

Closed pix2D closed 3 years ago

pix2D commented 4 years ago

Hello, first of all thank you for the great library. I have everything working perfectly across locales, so /en/blah and /de/blah work great. However I need to localize quite a few routes into different locales. So I want to load [lang]/blah on de/bleh, fr/bluh etc.

I tried to get this working with the experimental rewrites from Next, but every combination I try results in a 404. If I set the destination to a static route it rewrites fine so I know the rewrites themselves are working, and the source is formatted properly.

For the destination I tried:

/:lang/blah /:lang/blah?lang=:lang /[lang]/blah /[lang]/blah?lang=:lang

And various other combinations but nothing worked. Maybe I just don't follow how Next handles this internally. 🙈

I could make bleh and just import blah but that has the negative side effect of also enabling /en/bleh and just in general it's cumbersome to maintain with many routes.

I would appreciate any suggestions.

In case it matters I am using the example from here as a base (so without the build step): https://github.com/vinissimus/next-translate/tree/master/examples/with-dynamic-routes

aralroca commented 4 years ago

I'm going to investigate how to do it without the build step, but I can tell you how I resolved this using the build step (however it's like cumbersome and should be improved).

Using the build step:

First, we need to use dynamic route on the page. [slug].js.

Then, on getStaticPaths we can just add the lang path. (Because on the build step is adding the lang param):

import useTranslation from "next-translate/useTranslation"

const pageTranslations = {
  'es': 'blah',
  'en': 'bleh',
  'ca': 'blih',
}

export default function BlahPage() {
  const { t } = useTranslation()

  return <div>{t`common:example`}</div>
}

export const getStaticPaths = ({ lang }) => ({
  paths: [{ params: { slug: pageTranslations[lang] }}],
  fallback: false 
})

export const getStaticProps = () => ({ props: {} })

However, you need to take care the on Link and Route to add the slug correctly.


<Link lang={lang} href={`/[slug]?slug=${pageTranslations[lang]}`} as={`/${pageTranslations[lang]}`} />
pix2D commented 4 years ago

Thank you for the instructions. I am going to use this as a fallback, but I'd love to get it working without the build step. I got it semi-working with getInitialProps but of course then there's only SSR. I'll keep trying as well.

aralroca commented 4 years ago

@pix2D maybe you can fix this using rewrites https://github.com/vercel/next.js/discussions/9081#discussion-5567

sven-ra commented 3 years ago

I tried this using the build step instructions you provided but since you can't add multiple dynamic routes on the same level this is not an option for me.

I also tried it with the rewrites config but this also does not work since the you can't get the correct lang parameter inside getStaticProps.

aralroca commented 3 years ago

@sven-ra Using the build step the lang is added as prop to the getStaticProps.

sven-ra commented 3 years ago

@aralroca Yes but I can not have multiple dynamic routes on the same level.

[lang][blog]
[lang][people]

I can't translate the routes for both blog and people.

aralroca commented 3 years ago

Using the build step the lang is not a dynamic route, it's generated at build time as /es/[blog], /en/[blog], etc. Anyway, now next.js is advancing in i18n and soon there will be better support. Perhaps it would be good to move the discussion on this issue:

The "build step" is a workaround as long as there is no better support, but soon things will probably be simpler and in version 1.0.0 of next-translate no build-step will be needed.

So I think it's best to close this issue and address this implementation in the Next.js RFC