In a classic multilingual rails 4 website I want to avoid the duplicate content problem.
I used friendly-id and globalize3 to make the website multilingual.
Here is my configuration:
classic page model:
extend FriendlyId
friendly_id :title, use: [:slugged, :history]
translates :title, :content, :slug
first routes configuration:
scope ":locale", /#{I18n.available_locales.join("|")}/ do
my_routes
end
#rails cast solution
match '*path', to: redirect("/#{I18n.default_locale}/%{path}"), constraints: lambda { |req| !req.path.starts_with? "/#{I18n.default_locale}/" }, via: :all
match '', to: redirect("/#{I18n.default_locale}"), via: :all
first application application-controller configuration:
before_action :set_locale
def default_url_options(options = {})
{locale: I18n.locale}
end
private
def set_locale
I18n.locale = params[:locale] if params[:locale].present?
end
As I want users to access the site without /the-default-locale at the end of the URL I change configuration as follow:
Routes configuration:
#Here I'm trying to avoid /en/content and /content to avoid duplication
match "/#{I18n.default_locale}/*path", to: redirect("/%{path}"), via: :all
scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
my_routes
end
#removed the rails cast fallback to default locale
Application controller configuration:
before_action :set_locale
def default_url_options(options = {})
{ :locale => ((I18n.locale == I18n.default_locale) ? nil : I18n.locale) }
end
private
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
the links to switch between languages:
#here the French language is the default locale
<%= link_to_unless_current t("English"), locale: "en" %>
<%= link_to_unless_current t("French"), locale: nil %>
Questions:
1- With the friendly ids and the translated slug you can go to mywebsite.com/mon_contenu and mywebsite/en/my_content. But if you already are on mywebsite.com/mon_contenu and you click on the english switch you will be on mywebsite.com/en/mon_contenu with the english content but the url doesn't switch to the english slug.
Is this considerated as duplicate content? And if yes how can I avoid it?
2- With globalize if a content isn't translated it will display the default locale content. So mywebsite.com/mon_contenu and mywebsite.com/en/my_content can display the same content in the same language if the translation is not done.
Again is this considerated as duplication?
Options considered
Using robot.txt to disable some routes for instance to allow just the default locale to be indexed?
Using the canonical tag but I don't know how to easily setup it in the layout
How do you manage this kind of situations?
Any help/idea/comment/advice is always welcome!
As always thanks for your help.
Few months later, I'm still trying to figure out the best options.
Here is the solution I use for the question 1:
I set this in the controllers (solution from railscasts about friendly_id)
def show
if request.path != page_path(@page)
redirect_to @page, status: :moved_permanently
end
end
With this in place there are no reasons for multiple urls pointing to the same content. Instead the user will be redirected properly to the right URL. And the slug history is still useful.
I'll update this post if I figured out something for the second point! Actually I'm thinking of something to check if translation exist and if not redirect to default locale with a flash notice.