Background:
As mentioned in #915 , I am working on making i18n module work with i18n rewrites. Basically, this allows to serve user content from CDN in their language, without a redirect.
The functional part is resolved, but there is an issue with SEO, which doesn't do what is desired in URL rewrite case.
Currently, with prefix_and_default strategy and seo enabled, the rel=canonical tag will be added on default language routes. This means, that when default language is "en",
/ <- this one is canonical
/en <- this one will have link rel=canonical href="/"
This is great and exactly how it should work without rewrites. With rewrites, however, the desired behavior would be reversed: the canonical tag should point to language route, not the default:
/ <-default route never canonical, but have link rel=canonical href="/{{defaultLocale}}"
/en <- should have self-referencing link rel=canonical href="/en"
/fr <- should have self-referencing link rel=canonical href="/fr"
Additionally, the default route should have hreflang="x-default", signaling that no other language/region matches the user's browser setting.
With this setup, we can expect the crawler to scan all language routes, but not the default routes, because the content of default routes depends users' browser settings and should not be indexed.
What is the best way to introduce such change? Any guidance would be appreciated.
Here is what I am thinking regarding config changes:
Current behavior (marks default route as canonical)
i18n: {
seo: true
// or
seo: {
defaultCanonical: true
}
}
Desired behavior for i18n rewrites (marks language routes as canonical, plus sets hreflang="x-default" for default route)
i18n: {
seo: {
defaultCanonical: false
}
}
default route should have
hreflang="x-default"
Well, I think this is another feature request which is great if added.
I think you are right. Prefixed strategy with canonical links is what I need.
I think you are right. Prefixed strategy with canonical links is what I need.
Then this feature request _might be closed_.
Thanks!
x-default was added through https://github.com/nuxt-community/i18n-module/pull/922.
As for your case, it's a bit special since you are rewriting the URLs. That way of doing things feels like a hack to me, sorry. Due to that, I'm not really willing to dive into it and investigate if and how this should work.
It may be a special case because of the rewrite. Yet it would be nice if it was possible to choose, whether the default or the prefixed route is considered canonical. My understanding is that such a case is going to be covered in #912
Fixed for #912 are released in https://github.com/nuxt-community/i18n-module/releases/tag/v6.15.2 but not sure if it's not gonna fully help your case.
Hey @rchl and @divine. Thank you for your PRs! Huge improvement for SEO.
Forget my special case with URL rewrite for a minute. Here is what essentially I am trying to achieve:
<link rel="alternate" href="http://example.com/en" hreflang="en" />
<link rel="alternate" href="http://example.com/es" hreflang="es" />
<link rel="alternate" href="http://example.com/fr" hreflang="fr" />
<link rel="alternate" href="http://example.com/" hreflang="x-default" />
It's an example from Google Webmasters blog you have probably seen, except I am using es, en, and fr for language codes for simplicity.
It appears that there is no way to generate the above result.
With prefix_and_default strategy we get this:
<link rel="alternate" href="http://example.com/" hreflang="en" /> <!-- difference here -->
<link rel="alternate" href="http://example.com/es" hreflang="es" />
<link rel="alternate" href="http://example.com/fr" hreflang="fr" />
<link rel="alternate" href="http://example.com/" hreflang="x-default" />
With prefix strategy we get this (as expected):
<link rel="alternate" href="http://example.com/en" hreflang="en" />
<link rel="alternate" href="http://example.com/es" hreflang="es" />
<link rel="alternate" href="http://example.com/fr" hreflang="fr" />
<link rel="alternate" href="http://example.com/en" hreflang="x-default" />
And regarding to canonicals, I still can't make prefixed route canonical.
Here is what I would like to see:
<link rel="canonical" href="http://example.com/en" />
<link rel="canonical" href="http://example.com/en" />
@divine suggested that I need to use prefix strategy, which at first I thought was the right direction to go, but it turns out prefix strategy generates meaningless /index.html meant to redirect, which is not what I want.
It appears that there is no way to generate the above result.
Have you tried setting up defaultLocale: '' with prefixed strategy?
Here is what I would like to see:
- /index.html
<link rel="canonical" href="http://example.com/en" />
- /en/index.html
<link rel="canonical" href="http://example.com/en" />
Why? Doesn't make sense at all. You don't have content at root path and why it should be canonical?
I can't really understand what you're trying to achieve (do you have some weird errors in Google search console that your pages can't be indexed or any other SEO tool suggest to change that? Maybe some articles that suggest using root path as canonical?).
Let me remind, canonical used to mark page as unique, it doesn't do anything else. Making your root path canonical without content _wouldn't help you at all_.
Thanks!
Have you tried setting up defaultLocale: '' with prefixed strategy?
Just tried. It doesn't generate x-default link
Why? Doesn't make sense at all. You don't have content at root path and why it should be canonical?
Thanks for your response @divine. I think there is a bit of misunderstanding.
I am building a multi-language statically generated site, and I want to take advantage of i18n rewrites provided by Firebase Hosting. The rewrite allows me to host the website on CDN, yet provide content in user's language immediately without redirect.
Here is an example: when opening root of my website, a spanish-speaking visitor will get content from /es, whereas a russian-speaking visitor will get content from /ru. A visitor from unsupported locale will get content from /. (root path has content in default locale)
For SEO, I am trying to avoid marking default path as canonical, and instead make language routes /en, /es, /ru canonical, so that when the website is indexed, only the prefixed routes are respected.
Right now, with prefix_and_default strategy, the default route gets to be canonical. And with prefix strategy, root path doesn't get any content.
Just tried. It doesn't generate
x-defaultlink
Sorry, I forgot that you're using static generation, currently there is a bug https://github.com/nuxt-community/i18n-module/issues/911 that doesn't render anything which is solely used as redirection.
I am building a multi-language statically generated site, and I want to take advantage of i18n rewrites provided by Firebase Hosting. The rewrite allows me to host the website on CDN, yet provide content in user's language immediately without redirect.
Still doesn't make sense to me. What exactly does give i18n rewrites in terms of SEO? No redirection?
You're trying to make things more complicated. I've just read that documentation, giving content without redirection based on user IP-address. Basically I don't know what search engines bots might think about your site? 馃
This is why I am trying to avoid marking default path as canonical, and instead make language routes /en canonical, so that when the website is indexed, only the prefixed routes are respected.
You're looking for a prefixed strategy again which is currently has a bug. Even after it will be fixed I don't know it wouldn't help you since it will redirect.
Sorry, I'm out from this, too much complexity for doing some weird i18n-rewrites (weird because this library already does i18n and you're on top of it trying to do another layer of i18n logic.)
You should check for sites hosted with firebase and see how they perform with i18n-rewrites in terms of SEO.
What exactly does give i18n rewrites in terms of SEO? No redirection?
You are correct, the purpose of url rewrite is to avoid redirection. It complicates things in terms of SEO, but doesn't make it impossible.
1) I would like to stick to serving a static site on CDN an avoid adding back-end language detection and redirect
2) I client-based redirect is bad in terms of user experience: the browser first downloads the document, then parses and executes all JS (Nuxt+i18n+content is more than 350KB), then redirects and does the parsing and execution of JS again. To experience this, try the prefix strategy with redirect in slow 3G throttling mode.
The reason I am focused on making this right is because I know that the majority of visitors will be coming from locales other than default.
Yet, without the URL rewrite, the not-so-good case of client-based redirect is the only option (if you want to serve content in client's language).
This issue, however, can be closed, as my original request was to add self-referencing canonical to prefixed routes, which is now possible with prefix strategy.
To resolve my particular case, I generate website with defaultLocale: '', and then cp -a ./dist/en/. ./dist. Not perfect, and doesn't generate x-default, but it works.
To resolve my particular case, I generate website with
defaultLocale: '', and thencp -a ./dist/en/. ./dist. Not perfect, and doesn't generatex-default, but it works.
Wouldn't prefix strategy + defaultLocale: 'en' give you the x-default? Then you can use your copy hack with that.
Also, I wonder if you have some more complex options when it comes to rewrites. Maybe it allows you to set the cookie in which case you could use the no_prefix strategy and control the language with a cookie.