Skip to content
Menu
Railshero
  • Blog
  • About Me
  • Contact Me
  • Privacy Policy
Railshero
SEO friendly URLs with friendly_id

SEO friendly URLs with friendly_id

Posted on October 16, 2021 by Rails Hero

What is a SEO friendly URL ?

So, normally rails’ routes looks like these: ‘/posts/122’, ‘/photos/45531, ‘blog/posts/54222’ and so on. This is because rails finds the resource’s records by looking at the record id. This is alright for private applications like research apps, academic apps, management apps, etc. But, if you were to build a public application like a blogging app, forum app, CMS app, photo gallery app, etc; you would want the search engines to index your pages as efficiently as possible and also you’d want users/searchers to find your website/page quickly and easily. In other words, you’d want to rank better in search engine results and get more visitors to your website/application.

SEO friendly URLs are short, keyword rich and much easier to read, in other words; it’s ‘human friendly’. A SEO friendly looks something like these: ‘/photos/my-new-photo-gallery’ or ‘/photos/new-blog-post’, etc instead of; ‘/posts/122’, ‘/photos/45531, ‘blog/posts/54222’.

Clean URL Wiki: https://en.wikipedia.org/wiki/Clean_URL

SEO Wiki: https://en.wikipedia.org/wiki/Search_engine_optimization

What is a Permalink ?

So, now we know what is a SEO friendly URL, but what is a permalink ?. Permalinks (permanent links) are hyperlinks that don’t get changed over time, even if the contents on the link (i.e; webpage) are changed. The most common examples of permalinks can be seen in popular blogs like gizmodo, mashable, techcrunch, etc and even wikipedia. The permalinks of their website’s pages, look like these:

  • techcrunch.com/2021/10/16/what-to-expect-from-apple-google-and-samsungs-big-events
  • mashable.com/entertainment/25316/netflix-finally-shared-how-many-people-have-watched-squid-game-and-yep-its-a-record
  • en.wikipedia.org/wiki/Ruby_on_Rails

As you can see in the above examples, these permalinks are SEO optimized and will remain unchanged as long as the post exists. They could change the permalinks in future, but then it’ll not be a permalink anymore and will effect their SEO rankings as well.

Permalink Wiki: https://en.wikipedia.org/wiki/Permalink

Friendly_id Gem

The Friendly ID gem is the gem that you’d want to use if you want to implement SEO friendly URLs to your web applications. They call it the “Swiss Army bulldozer” of slugging and permalink plugins for Active Record. This gem was originally created by Norman Clarke and Adrian Mugnolo. Friendly ID is straight-forward, easy to use and most of the methods are self explanatory. Also, this gem has many advanced features, but for this tutorial we’ll just stick to the basic of using friendly id.

Github Link: https://github.com/norman/friendly_id

Friendly ID rubygems.org: https://rubygems.org/gems/friendly_id

Friendly ID rubygems
Friendly ID rubygems.org

 

Installing Friendly_id

To install Friendly ID, add friendly_id to your Gemfile and run bundler. Please note: v5.4.0 is the most recent & stable version as of now, but in future this is most likely to be changed, so please check friendly_id docs to get info about the latest releases of friendly_id.

#File: Gemfile
gem 'friendly_id', '~> 5.4.0'
bundle install

Demo Blog Post App

To show you the demo of friendly ID; I have created a demo blogging app, with just a title and a description to keep things minimal. So this is what the scaffold looks like; the model name is post and it has input fields of a title and a description with string and text data respectively.

rails g scaffold post title:string description:text

After that, i created a new migration to add a slug column to the posts table, this is where the slugs for friendly id will be stored. This column has to be unique; because every URL of my posts, should be unique. After that i ran the new migrations.

rails g migration add_slug_to_posts slug:uniq
rails db:migrate

After the migrations were done; i had to allow the :slug parameter in the trusted parameters list, of my posts controller.

#File: app/controllers/posts_controller.rb
class PostsController < ApplicationController
#...Other Methods...

private
   def set_post
      @post = Post.find(params[:id])
   end

#..Add :slug to the trusted parameters list...
   def post_params
      params.require(:post).permit(:title, :description, :slug)
   end
end

Also to add new slugs to my posts or edit existing slugs, i added the slug field in my posts’ form

#File: app/views/posts/_form.html.erb
<!---Other form elements--->

<div class="field">
<%= form.label :slug %>
<%= form.text_field :slug %>
</div>

<!---Other form elements--->

Using Friendly_id

To use friendly id, i had to run the generator that comes with friendly id, which generated a few more migrations. So, after running the generator, i ran the new migrations.

rails g friendly_id
rails db:migrate

So, after this was done, i had to add friendly id to my model as well.

#File: app/models/post.rb
class Post < ApplicationRecord
   extend FriendlyId
   friendly_id :slug, use: :slugged
end

In my posts controller, i had to do a slight change to my set_post method, i just had to change from ‘Post.find’ to ‘Post.friendly.find’.

#File: app/controllers/posts_controller.rb
class PostsController < ApplicationController
#...Other Methods...#
private
#...Change from Post.find to Post.friendly.find.... 
   def set_post
      @post = Post.friendly.find(params[:id])
   end

   def post_params
      params.require(:post).permit(:title, :description, :slug)
   end
end

After populating a few records with some dummy text and dummy slugs, that is how the slug column look like; in my posts table.

Table Of Slugs
Table Of Slugs

 

Validation Of Slugs

Validations are necessary, so that the slugs are properly added & Permalinks don’t break; which is bad for SEO. For instance, if any user enters any random string of characters like “%$@!~=+[]\\” or something similar; sometimes it might work properly, but sometimes it might not and will crash your app, also this will be bad for SEO. So that’s why validations are a must for slugs, this way any random user cannot enter any random string of characters and break your app and also your web app/site will rank higher in search results.

As you can see below, i have added a few validations. Firstly, for presence; i.e the slug cannot be empty/blank. Second validation is for uniqueness; i.e every slug must be unique, because every permalink is unique. Third validation is for the length of the slug, a minimum of 2 characters and a maximum of 2000 characters. And the last validation is for the format of the slug; i.e only alphanumeric characters from A-Z or a-z and 0-9 with dashes(-) and underscores(_) are allowed to be entered. This is done so that any random user can’t enter any random string of characters that can break your app or harm your SEO.

Active Record Validations Guide: https://guides.rubyonrails.org/active_record_validations.html

#File: app/models/post.rb
class Post < ApplicationRecord
   extend FriendlyId
   friendly_id :slug, use: :slugged

##...Validations for slug...##
   validates :slug, presence: true # Validates Presence i.e Slug can't be blank.
   validates :slug, uniqueness: true # Validates uniqueness i.e every slug must be unique.
   validates :slug, length: { in: 2..2000 } # Validates length i.e min & max length of the slug. 
   validates :slug, format: { with: /\A[a-zA-Z0-9-_]+\z/,
   message: ":only letters(A-Z or a-z), numbers(0-9), dashes(-) and underscores(_) are allowed" } # Validates format of the slug.

end

Get The Demo App

You can get my Friendly ID demo app that i created, from my Github Repo here: https://github.com/railshero/friendly-id-demo

Friendly ID Demo App
Friendly ID Demo App

This demo app will help you get started with friendly id. With this demo app, you can create demo posts, view existing posts, add new slugs or edit existing slugs or even test the validation of slugs that i mentioned above.

Final Thoughts

Friendly ID isn’t the only way to add SEO friendly slugs to your app, you could even do it from scratch. But this gem makes everything a lot easier, so why not use a tool that already exists instead of creating a new tool?. There are many advanced features of friendly id that i haven’t discussed about, in the post. But, if you wish to dig deeper; please check them out by reading their documentation. That’s all for now and have a nice day.

Friendly Id Guide: https://norman.github.io/friendly_id/file.Guide.html

Friendly Id Docs: https://www.rubydoc.info/github/norman/friendly_id/FriendlyId/Base

2 thoughts on “SEO friendly URLs with friendly_id”

  1. robert sneed says:
    April 5, 2022 at 10:40 am

    any other gems that do this ?

    Reply
    1. Rails Hero says:
      April 6, 2022 at 8:05 am

      here’s a few of them: https://www.ruby-toolbox.com/categories/rails_permalinks___slugs

      Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Tags

active record active storage assets assign to many associations attachment attachments authentication authorization avatar bootstrap cdn config database deploy deployments devise DRY environment variables file uploads Gemfile gems has_many helpers heroku index indexing initializer javascript pagination parameters postgres production public routes.rb ruby gem ruby gems search sendgrid server smtp stylesheets variants views voting

Recent Posts

  • Understanding the DRY Principle in Rails
  • Building Multi-tenant Applications with Rails
  • Rails Basics: Templating Engines
  • Deploying With Capistrano
  • Automated Testing in Rails

Archives

  • July 2023
  • June 2023
  • October 2021
  • September 2021
  • August 2021
  • July 2021

Categories

  • Active Record
  • Activity Logging
  • Apps
  • Assets
  • Attachments
  • Audio
  • Authentication
  • Authorization
  • Deployments
  • Error Pages
  • File Uploads
  • General
  • Heroku
  • Heroku
  • Pagination
  • Rails Basics
  • RubyGems
  • Search Engine Optimization
  • Search/Indexing
  • Testing
  • User Interface
  • Video
  • Views & Templating
  • Voting
  • Web Security
©2025 Railshero | Theme: Wordly by SuperbThemes
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent.
Cookie SettingsAccept All
Manage consent

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Non-necessary
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.
SAVE & ACCEPT