Im working on a website that I have made using NextJs 14.2.3. I have localization support using react-i18next.
I am having some issues in regards to getting the correct canonical url generated by latest NextJs metadata conventions, while using react-i18next for localization in my project.
When testing out on localhost i get the intended behaviour where the canonical link for e.g. my main page on my website points to ‘https://mywebsite.dk’ while switching to english points to ‘https://mywebsite.dk/en’.
But when I test this on a Vercel deployment the same main page in danish default language points to ‘https://mywebsite.dk/da’, while the english version points correctly to ‘https://mywebsite.dk/en’
I know the react-router-i18n is used behind the hood of react-i18next, and that the defaultLocale is used to remove the language prefix in the url if the default locale is selected as language. Thus I assume that the best approach would be to make the non language prefixed danish url the canonical one for danish language selection.
I am so confused at the issue where canonical link points to ‘/da’ is only happening in production and not development on localhost.
Can anybody help me?
i18nConfig.js:
const i18nConfig = {
locales: [
'da',
'en',
// 'de'
],
defaultLocale: 'da'
}
module.exports = i18nConfig;
i18n.js (might not be relevant):
import { createInstance } from 'i18next';
import { initReactI18next } from 'react-i18next/initReactI18next';
import resourcesToBackend from 'i18next-resources-to-backend';
import i18nConfig from '@/i18nConfig';
export default async function initTranslations(
locale,
namespaces,
i18nInstance,
resources
) {
i18nInstance = i18nInstance || createInstance();
i18nInstance.use(initReactI18next);
if (!resources) {
i18nInstance.use(
resourcesToBackend(
(language, namespace) =>
import(`@/locales/${language}/${namespace}.json`)
)
);
}
await i18nInstance.init({
lng: locale,
resources,
fallbackLng: i18nConfig.defaultLocale,
supportedLngs: i18nConfig.locales,
defaultNS: namespaces[0],
fallbackNS: namespaces[0],
ns: namespaces,
preload: resources ? [] : i18nConfig.locales
});
return {
i18n: i18nInstance,
resources: i18nInstance.services.resourceStore.data,
t: i18nInstance.t
};
}
middleware.js (might not be relevant):
import { i18nRouter } from 'next-i18n-router';
import i18nConfig from './i18nConfig';
export function middleware(request) {
return i18nRouter(request, i18nConfig);
}
// applies this middleware only to files in the app directory
export const config = {
matcher: '/((?!api|static|.*\..*|_next).*)'
};
main page.jsx (but all other pages have same setup for canonical urls):
export const metadata = {
metadataBase: new URL("https://mywebsite.dk"),
alternates: {
canonical: './',
},
}
If you need further details i will happily provide. Hope someone might be able to help me!
Kind regards
Morten