Robots.txt dinâmico no Rails

Ao usar o Amazon Cloudfront CDN com uma determinada configuração, todo o seu site fica disponível por meio do url do CDN. Nos resultados de pesquisa do Google, dois resultados diferentes começaram a aparecer, um com o url canônico e outro com o url Cloudfront.

Host canônico

Host Cloudfront

Existem várias estratégias para resolver esta situação, entre elas as duas listadas aqui :
* Urls canônicas
* Um robots.txt dinâmico

Lendo alguns conselhos para uma resposta semelhante no Stackoverflow, atualmente uso a seguinte solução para renderizar um robots.txt dinâmico com base no parâmetro de host da solicitação.

Encaminhamento

# config/routes.rb
#
# Dynamic robots.txt
get 'robots.:format' => 'robots#index'

Controlador

# app/controllers/robots_controller.rb
class RobotsController < ApplicationController
# No layout
layout
false

# Render a robots.txt file based on whether the request
# is performed against a canonical url or not
# Prevent robots from indexing content served via a CDN twice
def index
if canonical_host?
render
'allow'
else
render
'disallow'
end
end

private

def canonical_host?
request
.host =~ /plugingeek\.com/
end
end

Visualizações

Com base no request.host, renderizamos um dos dois .text.erbarquivos de visualização diferentes .

Permitindo robôs

# app/views/robots/allow.text.erb # Note the .text extension

# Allow robots to index the entire site except some specified routes
# rendered when site is visited with the default hostname
# http://www.robotstxt.org/

# ALLOW ROBOTS
User-agent: *
Disallow:

Banindo aranhas

# app/views/robots/disallow.text.erb # Note the .text extension

# Disallow robots to index any page on the site
# rendered when robot is visiting the site
# via the Cloudfront CDN URL
# to prevent duplicate indexing
# and search results referencing the Cloudfront URL

# DISALLOW ROBOTS
User-agent: *
Disallow: /

Especificações

Testar a configuração com RSpec e Capybara também pode ser feito facilmente.

# spec/features/robots_spec.rb
require 'spec_helper'

feature
"Robots" do
context
"canonical host" do
scenario
"allow robots to index the site" do
Capybara.app_host = 'http://www.plugingeek.com'
visit
'/robots.txt'
Capybara.app_host = nil

expect
(page).to have_content('# ALLOW ROBOTS')
expect
(page).to have_content('User-agent: *')
expect
(page).to have_content('Disallow:')
expect
(page).to have_no_content('Disallow: /')
end
end

context
"non-canonical host" do
scenario
"deny robots to index the site" do
visit
'/robots.txt'

expect
(page).to have_content('# DISALLOW ROBOTS')
expect
(page).to have_content('User-agent: *')
expect
(page).to have_content('Disallow: /')
end
end
end

# This would be the resulting docs
# Robots
# canonical host
# allow robots to index the site
# non-canonical host
# deny robots to index the site

Como última etapa, pode ser necessário remover a estática public/robots.txtda pasta pública se ela ainda estiver presente.

Espero que você ache isso útil. Fique à vontade para comentar, ajudando a aprimorar ainda mais essa técnica.