Reputation: 11061
I am using Next.js i18n-routing to setup multi-language website. This works perfectly. If I create a file in /pages/about.js
this will create URLs based on my locale settings, for example:
/about
/de/about
/es/about
That is all fine.
What if I want to have a translated URL routes for each language? I am stuck on how to set this up...
/about
/de/uber-uns
/es/nosotros
?
Upvotes: 27
Views: 18665
Reputation: 71
For anyone looking for a solution like the one @juliomalves gave, and one that doesn't involve the use of middleware on every request, you can:
const nextConfig = {
...
async rewrites() {
return [
// Handle all paths that don't start with a locale
// and point them to the default locale static param: (en)
{
source: '/:path((?!(?:de|fr|es|it|el|pl|nl|en)(?:/|$)).*)',
destination: '/en/:path*',
},
];
},
};
Upvotes: 0
Reputation: 76
For a more scalable solution check this package: https://www.npmjs.com/package/next-translate-routes
With this you can keep one json file for your main urls and translations and also has a component for making i18n links easier
Upvotes: 2
Reputation: 50438
You can achieve translated URL routes by leveraging rewrites
in your next.config.js
file.
module.exports = {
i18n: {
locales: ['en', 'de', 'es'],
defaultLocale: 'en'
},
async rewrites() {
return [
{
source: '/de/uber-uns',
destination: '/de/about',
locale: false // Use `locale: false` so that the prefix matches the desired locale correctly
},
{
source: '/es/nosotros',
destination: '/es/about',
locale: false
}
]
}
}
Furthermore, if you want a consistent routing behaviour during client-side navigations, you can create a wrapper around the next/link
component to ensure the translated URLs are displayed.
import { useRouter } from 'next/router'
import Link from 'next/link'
const pathTranslations = {
de: {
'/about': '/uber-uns'
},
es: {
'/about': '/sobrenos'
}
}
const TranslatedLink = ({ href, children }) => {
const { locale } = useRouter()
// Get translated route for non-default locales
const translatedPath = pathTranslations[locale]?.[href]
// Set `as` prop to change displayed URL in browser
const as = translatedPath ? `/${locale}${translatedPath}` : undefined
return (
<Link href={href} as={as}>
{children}
</Link>
)
}
export default TranslatedLink
Then use TranslatedLink
instead of next/link
in your code.
<TranslatedLink href='/about'>
<a>Go to About page</a>
</TranslatedLink>
Note that you could reuse the pathTranslations
object to dynamically generate the rewrites
array in the next.config.js
and have a single source of truth for the translated URLs.
Upvotes: 36