My Octopress Blog

A blogging framework for hackers.

Rails 3 - Removing or Adding Www in the Url

I don’t like having two separate domains that point to the same content for a number of reasons. Caching and SEO optimization are two them that make it worth dealing with for me. Here is how I deal with that in Rails 3.

Usually, I would handle this in my webserver config file but since I’ve started using Heroku I don’t have access to a config file so the Rails application needs to handle that for me.

One way to do the redirect is to have some code in your application_controller.rb file that checks for www. and then behaves accordingly. Like this:

before_filter :strip_www

def strip_www
  if request.env["HTTP_HOST"] == ""
    redirect_to ""

This functions just fine, however, there is no need to load the entire application stack just to do a redirection.

Fortunately, Rails runs on Rack which means you can run some pretty awesome middleware and a few of the guys over at pivotal labs have done just that.

Enter Refraction.

Refraction is a piece of middleware that gives you a router before the request reaches your main application stack, which means you can intercept the call and perform a redirect on it without loading a bunch of unnecessary code. You can read a lot more about it in the README file on GitHub.

All I’m going to show you here is how to ADD “www.” to a request that doesn’t have it. These instructions are fairly similar to the, with the exception of the refraction_rules and a small change to the production.rb call.

First, install the refraction gem. I recommend adding “gem ‘refraction’” to your Gemfile and running “bundle install” in your app. This will also install it on Heroku when you push.

Once you have done that, we are going to add the following call near the top of your config/environments/production.rb file:

config.middleware.insert_before(::Rack::Lock, ::Refraction)

and then create a new file inside the config/initializers/ folder called refraction_rules.rb that has the following content in it:

Refraction.configure do |req|
  req.permanent! :host => "" if !~ /^www./

Once that’s done, you should be good to go. I tested this on my dev box by setting my /etc/hosts file up to point and to which should work nicely for testing. :)

Good luck!