Ognjen Regoje bio photo

Ognjen Regoje

I make things that run on the web (mostly).
More /ABOUT me.

me@ognjen.io Twitter LinkedIn Github

Building human readable link building in Rails

A while ago I needed to improve the canonical links for some of our pages, specifically because we added more search parameters etc. so I made use of routes file to create some of these.

I started out with an extremely simple usecase: something like /restaurants-with-:feature and then progressively tagged on more parameters.

So, I rolled a new app to test this out. I started out with:

get "/restaurants-with-:feature/", to: "restaurants#index", as: :built_restaurant

Next, I planned out what attributes I wanted to have. Feature makes no sense for a restaurant. I decided on three:

  • Location: I just used a dropdown for my purposes but it’d be easy enough to replace it with address, parse coordinates and use geofencing
  • Cuisine: Japanese, Korean, Fusion, etc
  • Tag: a descriptive attribute of the restaurant such as cheap, fancy, romantic, etc.

Then, I went through a few iterations of the link:

# Omitting the ', to: "restaurants#index, as: built_restaurant` for sake of brevity

get "/restaurants(-in-:location)"
# I'm using slugs for all three attributes above so the :location parameter would end up being 'new-york' for example
# Example end result: /restaurants-in-new-york

Next the cuisine:

get "/(:cuisine-)restaurants(-in-:location)"
# Example end result: /chinese-restaurants-in-new-york

Next the tag:

get "/(list-of-:tag-)(:cuisine-)restaurants(-in-:location)"
# Example end result: /list-of-romantic-chinese-restaurants-in-new-york

A couple of notes and pr0 tips:

  • The brackets indicate that a parameter is optional and the link would work without that parameter being passed as well. This lets you use built_restaurant_path anywhere with any combination of parameters.
  • Each of the segments also needs a delimiter of some sort otherwise it would all drop down into the next parameter. That’s why I couldn’t do just (:tag-)(:cuisine-) because when :tag was absent all cuisines would be parsed as tags.
  • My specific usecase was SEO link building since I didn’t want to have long queries in the URL show up in search engines.
  • The most difficult part turned out to be planning the order so that the end result makes sense no matter which parameters are present – especially if some are missing – which is to say it was cake and the end result does look good.
  • There is funkiness if you are to use / instead of - as separators between categories that would end up with // between terms, the helper would not generate leading or trailing slashes, etc. I didn’t have enough time to test all of these out but reader beware.

#link building #rails #seo #technical