Better Search Engine Friendly URL’s with Ruby on Rails
In my last post about SEO and RoR I gave really BAD advice on how to accomplish clean URL’s that are search engine friendly. Our first RoR project consists of pages that are nearly 100% unspiderable by the search engine bots because its an app that requires login to do anything so I hadn’t really sat down and worked out the proper way to do URLs.
Obie Fernandez posted a great comment and reply on his blog showing how he taps into the power of to_param to easily generate clean URL’s. But the problem with both my approach and his is that it doesn’t guarantee a permanant link. From an SEO perspective its very important that your URL’s remain the same for eternity once they are generated.
For example:
You created a new company in your app a few months ago that resulted in the URL:
/companies/apple-computer
At Macworld Steve Jobs announces that Apple Computer is changing its name to Apple, Inc. A staff member updates your CMS to reflect the new name and now your URL is:
/companies/apple-inc
BAD. What if you were really good with your copy on that page and were forunate to get lots of links to /companies/apple-computer? Now that page returns 404 and you lose all that link juice.
Solution
You need to store the slug in a field so that your URL remains the same forever just as its done in most blog systems like Wordpress. The plugin permalink_fu solves the problem by generating a slug that is automatically stored in the DB. Hat tip to Eadz who goes into more detail on how to implement:
http://www.seoonrails.com/even-better-looking-urls-with-permalink_fu
One More Solution for URL Slugs
I haven’t tried this one either but the Acts as Sluggable plugin sounds like it might do the trick.
If you have used either of these solutions please leave a comment!
Hey Tony, thanks for the acknowledgement, and here’s one quick point that I should have emphasized — because the significant part of the URL is the numerical id (and the textual part of the slug is ignored when pulling up a resource), then even if the name was changed in the future, the original URL would still work perfectly with old links.
Hey Obie,
That would still be a bad thing for SEO as it would result in multiple, indexable pages with exactly duplicate content.
@tony: I took yours and Obie advice/idea into account and stoped the multiple page issue…. hope you find it useful
http://www.chrisfarms.com/2007/2/11/seo-friendly-urls-in-rails
Chrisfarms solution is better than permalink_fu cause it allows to change url.
After renaming “Apple Computer” to “Apple Inc.”
/companies/7-apple-computer would change to /companies/7-apple-inc
/companies/7-apple-computer would return a 301 (permanent) redirect to /companies/7-apple-inc and that is the way it should be.
Without a doubt chrisfarm’s is the perfect solution and so easy! Well done mate. I just installed the plugin and was up and running in seconds.
How about http://chrisfarms.googlecode.com/svn/rails/plugins/acts_as_friendly_param/README
Known as Acts_As_Friendly_Param
I feel like the id-words-words is a bit of an ugly solution. I get that its easy and will satisfy most.
However if you are representing clients names then the user should not have to remember the ID. I.E. if you were talking to someone and said “go to mydomain.com and type /apple” as opposed to “go to mydomain.com and type /1233-apple”
I’ve found the map.something_custom in the routes.rb file to be a much nicer solution:
map.client ‘client/:permalink’, :controller => ‘test’, :action => ’show’, :permalink => ”
Then in the controller: @client = Client.find_by_permalink(params[:permalink])
And in the view: link_to @client.name, show_client(:permalink => @client.permalink)
This way you have full customization over the url paths, and still retain permalink functionality. Write a little AJAX on the input form and you can generate/and validate URLs. This is really nice because you don’t always need the whole title of your post in the URL.
Sorry made a typo:
And in the view: link_to @client.name, client_url(:permalink => @client.permalink)