How to do www to non-www 301 redirect on your Heroku Rails app | BlueDiapente - Lilibeth De La Cruz

BlueDiapente

How to do www to non-www 301 redirect on your Heroku Rails app

Content on your site should only be accessible from a single URL. You don't want search engines penalizing you for having duplicate content or to have issues with the domains for which cookies are set. It might seem to the outside that http://yoursite.com and http://www.yoursite.com are different websites.

Pick either one, but not both. Requests from one should be redirected to your chosen one using an SEO friendly 301 (Moved Permanently) redirect.

While at the momment it seems to be more a matter of style, I choose the non-www version. I prefer the look of shorter urls and www is not really necessary (though non technical folks might expect it).

Most people do this using their web server's configuration files. Go ahead and do that if you are lucky enough to have access to those.

But, what if you are using Heroku?

There are a few options available. You could do it using routes, redirect in the application controller or redirect at the Rack Middleware level.

The ideal thing is for this to happen at the lowest possible level (as close to the web server as possible) to avoid using any of your apps resources unnecessarily at make the whole thing less error prone.

I wouldn't recommend the controller level since aside from the application load issue (while it might be a small step, it is an additional check to handle on every request) and it wouldn't work for requests that don't even go through the controller, like when you are using file caching.

Since at Heroku you don't have access to the Nginx configuration, what I do is implement the 301 redirect in Rack Middleware. This has the benefit of depeding only on Rack instead of on Rails.

I decided to use the rack-rewrite gem to handle this since it looks like it's usage is pretty wide spread (and by that I mean tested), and the last commit was a few monts ago, so it doesn't look like it is abandoned. This was instead of choosing a gem to solve this in specific, since there are plenty of other uses for rack-rewrite.

First, include rack-rewrite on your Gemfile (You are using one right?).

Then, go to the config.ru file and add the redirect code before the command to run the application. This is based on a post in Scott Watermasysk's site. I changed some stuff including making it work on production. This is to make testing easier on your local development machine changing just some variables and not the core, before you upload the changes to your production site. To test locally you would need to have both the www and the non-www url pointing to your local server.

require "rack-rewrite"

ENV['RACK_ENV'] ||= 'development'

if ENV['RACK_ENV'] == 'development'
  ENV['SITE_URL'] = 'yoursite.local:3000'
  else
  ENV['SITE_URL'] = 'yoursite.com'
end

use Rack::Rewrite do
  r301 %r{.*}, "http://#{ENV['SITE_URL']}$&", :if => Proc.new { |rack_env|
  rack_env['SERVER_NAME'].start_with?('www')}

  r301 %r{^(.+)/$}, '$1'
end

When deploying to production make sure both, www and non-www, urls are being directed to your application by your DNS provider, so that the requests can be captured and handled.

That is pretty much it!