Closed jeromeheissler closed 2 years ago
I would like to know too ! It's so important for SEO and i can't manage to make it work with this..
Very important feature.
I managed to get it working using import { translatePath } from 'next-translate-routes/translateUrl'
But it doesn't work with page names with the "-" symbol in it (maybe even with other symbols).
Maybe this should be a separate issue?
Very important feature.
I managed to get it working using
import { translatePath } from 'next-translate-routes/translateUrl'
But it doesn't work with page names with the "-" symbol in it (maybe even with other symbols).
Maybe this should be a separate issue?
Finally I changed package to make it work correctly.. You can check next-multilingual, they have all of this incorporated. (translations, translated routes, auto rel=alternate and rel=canonical,...) And for the creator of next-translate-routes, next-multilingual could be a good inspiration to focus more on SEO.
I hope we will find the ultimate package for translations including everything we need in one place.
I am doing the following to get alternative urls.
src/utils/localize-helpers.ts:
import type { NextRouter } from 'next/router';
import { translateUrl } from 'next-translate-routes';
export const formatSlug = (slug: string, locale?: string, defaultLocale?: string) => {
return locale === defaultLocale ? `/${cleanSlug(slug)}` : `/${locale}/${cleanSlug(slug)}`.replace(/\/+$/, '');
}
export const cleanSlug = (slug: string) => slug.replace(/^\/|\/$/g, '');
/**
* Translate our path, and return a complete translated URL.
* Todo: 'next-translate-routes' doesn't provide a way to fetch the translated URL with locale prefixed?
* @param router NextRouter
* @param translateLocale The locale that we want to translate to.
* @param format Decide if you want to add slashes and locale for a complete path.
*/
export const translatePath = (router: NextRouter, translateLocale?: string, format: boolean = true) => {
const locale = translateLocale || router.locale;
const slug = translateUrl(router, locale).pathname || '';
return format
? formatSlug(slug, locale, router.defaultLocale)
: cleanSlug(slug);
};
/**
* Return an array of objects containing all translations of a route.
* @param router NextRouter
*/
export const getLocalizedPaths = (router: NextRouter) => {
return router.locales?.map((locale: string) => ({
locale,
path: `${translatePath(router, locale)}`,
})) || [];
};
export const getLocalizedSlugs = (router: NextRouter) => {
return router.locales?.map((locale: string) => ({
locale,
slug: `${translatePath(router, locale, false)}`,
})) || [];
};
src/pages/_app.tsx:
...
import { useRouter } from 'next/router';
import { DefaultSeo } from 'next-seo';
import withTranslateRoutes, { translateUrl } from 'next-translate-routes';
import { getLocalizedPaths, translatePath } from '../utils/localize-helpers';
...
function MyApp() {
const router = useRouter();
const url = `${process.env.PROJECT_URL?.replace(/\/+$/, '')}`;
const languageAlternatives = getLocalizedPaths(router).map((path) => ({
hrefLang: path.locale,
href: `${url}${path.path}`,
}));
languageAlternatives.push({ hrefLang: 'x-default', href: `${url}${translatePath(router)}` });
return (
<DefaultSeo
{...SEO}
canonical={`${url}${translatePath(router)}`}
languageAlternates={languageAlternatives.map((locale) => ({
hrefLang: locale.hrefLang,
href: locale.href,
}))}
/>
)
}
v1.9.0 is out, with two new helpers, fileUrlToUrl and urlToFileUrl. The docs now suggests a piece of code, quite similar to the above, to add alternate links. It seemed better to me to leave it like this, to avoid stepping out of next-transate-routes scope, and so that everyone can tweak it the way he want, using or not a dedicated package like next-seo. Feel free to reopen this issue if it is not satisfying.
Can we use this plugin to automatically add this on each page based on _route.json :
Maybe we can make a hook that takes the current page, search all rewrite for each language and return the Head tag with all alternate pages inside