It is a confusing state of affairs, but here are some pointers:
Don't use the canonical tag in the way you were thinking. Content translated into several languages is not duplicate content. So you don't want to be pointing /fr/ --canonical--> /en/
at all. Use rel="alternate" hreflang="en"
instead. Use canonical within a given language to account for duplicates. Example:
www.example.com/en/page1.html
www.example.com/en/page1.html?somerandomparameter=4
www.example.com/fr/page1.html
www.example.com/fr/page1.html?somerandomparameter=4
You should use two canonical tags:
en/page1.html?somerandomparameter=4 --> en/page1.html
fr/page1.html?somerandomparameter=4 --> fr/page1.html
Note that the French page never points to a canonical English version. To deal with the language difference, we use reciprocal hreflang tags as well:
fr/page1.html <--> en/page1.html
Another important aspect to hreflang is that a page should refer not just to the other languages, but to itself as well. So, on the English-language page, you would have:
<link rel="alternate" hreflang="en" href="www.example.com/en/page1.html" />
<link rel="alternate" hreflang="fr" href="www.example.com/fr/page1.html" />
Putting it all together, here are the canonical and hreflang tags for my example. I've listed the page, and then indented are all the tags that should be in the source code of that page:
www.example.com/en/page1.html
<link rel="alternate" hreflang="en" href="www.example.com/en/page1.html" />
<link rel="alternate" hreflang="fr" href="www.example.com/fr/page1.html" />
www.example.com/en/page1.html?somerandomparameter=4
<link rel="canonical" href="www.example.com/en/page1.html" />
www.example.com/fr/page1.html
<link rel="alternate" hreflang="en" href="www.example.com/en/page1.html" />
<link rel="alternate" hreflang="fr" href="www.example.com/fr/page1.html" />
www.example.com/fr/page1.html?somerandomparameter=4
<link rel="canonical" href="www.example.com/fr/page1.html" />
Note that the parameterised pages don't need to hreflang each other: Google follows the canonical instruction in each case, and then realises that there are multiple versions of page1.html
across various languages.
Finally, it isn't ideal to 301-redirect visitors based on their browser language preference or location. Googlebot always crawls from the US, and doesn't express a preference for any language other than English. Forcing a 301-redirect can mean Googlebot spends most of its crawl budget on the English-language pages, and may never even see the other languages. Make sure that Google can at least reach those other language subfolders -- is your language selector crawlable?
Edit 1: I just realised I didn't answer the part of your question about x-default. In your case, given that you're redirecting users to the /en/
subfolder (i.e. nobody is really going to use the root folder), then your x-default should be www.example.com/en/
, not www.example.com
Edit 2: I do understand your concern there, but I'd still recommend using x-default
to point to the /en/
folder. The reason being that this actually describes the way your site works more accurately: your root folder doesn't really have a language at all -- it just serves as a redirect.
The behaviour of your site is such that English is truly functioning as the default language, and your hreflang should reflect that. After all, as you've said, when you can't find a better language for them you send the user to the /en/
folder.
Google shares your aim of serving language-specific content, and rely on your x-default as a signal. If your site had only French, English, and Spanish versions, and the user is a German speaker searching on Google.de
, it makes more sense for the /en/
page to show up in Google's results. That makes for a more straightforward user experience -- that's the default language, and the user gets sent straight to it -- rather than Google sending them to a page that only functions as a redirect to English content anyway. Also, the user doesn't have to wait for a redirect, which speeds things up and improves the experience.
Basically, you probably want to minimize direct traffic to the root folder. Configure your x-default to /en/
and let Google do the work of per-user language selection for you.