Adding Bootstrap from a CDN to your Rails application

In a previous post, I talked about manually adding Bootstrap 3 files to a new Rails 4 project. What about if we made upgrading easier by loading the files from a CND instead? Then we could choose between using the latest version of Bootstrap 3, an earlier release or even Bootstrap 2 by just changing a string in a helper. Sound good?

Let’s get started by creating a project:

rails new bootstrap-cdn

Next, created a new file called layout_helper.rb in app/helpers/ and populate it with the contents below. I’ve chosen to use the latest version of Bootstrap at the time of writing which was 3.0.3.

module LayoutHelper

  def bootstrap_version
    # Choose the Bootstrap version you would like to use from the CDN
    "3.0.3"
  end

end

Now let’s edit application.html.erb in app/views/layouts. In the head, we want to included the css and just before the closing body tag, we add the javascript.

<!DOCTYPE html>
<html>
<head>
  <title>Loading Bootstrap from a CDN</title>
  <link href="//netdna.bootstrapcdn.com/bootstrap/<%= bootstrap_version %>/css/bootstrap.min.css" rel="stylesheet">
  <%= stylesheet_link_tag    "application", media: "all", "data-turbolinks-track" => true %>
  <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
  <%= csrf_meta_tags %>
</head>
<body>
  <div class="container">
    <%= yield %>
  </div>
  <script src="//netdna.bootstrapcdn.com/bootstrap/<%= bootstrap_version %>/js/bootstrap.min.js"></script>
</body>
</html>

That’s all it takes to get up and running quickly without a gem. It also happens to be the simplest upgrade method that I can think of for down the road. For those of you looking to expand the application slightly for testing purposes, then read on.

Open your Gemfile and add high_voltage.

gem 'high_voltage', '~> 2.1.0'

Edit your routes.rb found in config/.

Rails.application.routes.draw do

  get 'pages/home' => 'high_voltage/pages#show', id: 'home'

end

For High Voltage to function correctly, we need to create an initializer called high_voltage.rb in the config/initializers/ directory and populate it with:

# config/initializers/high_voltage.rb
HighVoltage.configure do |config|
  config.home_page = 'home'
end

In your Terminal, create the home page and directory that we referenced above.

$ mkdir app/views/pages
$ touch app/views/pages/home.html.erb

Now let’s get to some fun testing. Open the file home.html.erb in app/views/pages. We’ll create a number of buttons to make sure the Glyphicons are loaded along with a Javascript tooltip. Here’s some code to get you started:

<h2>Some Glyphicons</h2>

<%= button_tag(type: 'button', class: 'btn btn-default btn-lg' ) do %>
  Star <%= content_tag(:span, '', class: 'glyphicon glyphicon-star') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-default' ) do %>
  Star <%= content_tag(:span, '', class: 'glyphicon glyphicon-star') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-default btn-sm' ) do %>
  Star <%= content_tag(:span, '', class: 'glyphicon glyphicon-star') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-default btn-xs' ) do %>
  Star <%= content_tag(:span, '', class: 'glyphicon glyphicon-star') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-primary btn-lg' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-user') %> User
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-primary' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-user') %> User
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-primary btn-sm' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-user') %> User
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-primary btn-xs' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-user') %> User
<% end %>

<br><br>

<%= button_tag(type: 'button', class: 'btn btn-default btn-lg' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-align-justify') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-default' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-align-justify') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-default btn-sm' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-align-justify') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-default btn-xs' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-align-justify') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-primary btn-lg' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-align-justify') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-primary' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-align-justify') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-primary btn-sm' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-align-justify') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-primary btn-xs' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-align-justify') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-warning btn-lg' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-align-justify') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-warning' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-align-justify') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-warning btn-sm' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-align-justify') %>
<% end %>

<%= button_tag(type: 'button', class: 'btn btn-warning btn-xs' ) do %>
  <%= content_tag(:span, '', class: 'glyphicon glyphicon-align-justify') %>
<% end %>

<h2>A Javascript Tooltip</h2>

<%= button_tag('Tooltip on the right', type: 'button', class: 'btn btn-default', id: 'tooltip', data: {toggle: 'tooltip', placement: 'right'}, :'data-original-title' => 'Tooltip on the right' )%>

One last to do, be sure to edit application.js in app/assets/javascripts so that our tooltip works.

$(document).ready(function(){
    $("#tooltip").tooltip();
});

That’s it and don’t forget to run bundle install at the Terminal. We added a gem to the Gemfile. Enjoy!

A copy of this application is on Github and you can download it here.

If you have any suggestions or feedback, please let me know in the comments, via email or on Twitter.

Adding a Bootstrap 3 layout to a Rails 4 project

In this article, we are going to build on the project that we started in Using Bootstrap 3 with Rails 4.

Outcome

Our goal at the end of this article is to have implemented a Bootstrap 3 layout for our Rails 4 project similar to the image below.

Outcome

As you can see, we want to create a layout with a navigation bar at the top and a footer at the bottom. The content in between these two page elements will be dynamic from page to page. On the root url, or home page, of our application we want to have the option to include a Bootstrap jumbotron. The jumbotron is the section of the page in the image above that has a grey background and a heading of Hello, world! and it is not something we want to display on any of the other pages.

Creating some static pages

To build the layout, we are going to need to create 5 static pages which are listed in the table below.

Name URL Route
About Us /about about_path
Contact Us /contact contact_path
Home / root_path
Privacy Policy /privacy privacy_path
Terms /terms terms_path

To create these pages, we are going to use a gem from the folks at thoughtbot called High Voltage. It is one of my favorite gems that allows you to quickly and easily create static pages plus it has an MIT License. As an aside, start checking the licenses of your gems before deciding to include them in your projects if you are not already doing so. Let’s get started.

Open the Gemfile file in the root of your project and add the following line:

gem 'high_voltage'

Next run bundle install to add the gem to your project:

bundle install

We are going to follow the directions found in the High Voltage README to create the following directory structure:

app/views/pages
            ├── about.html.erb
            ├── contact.html.erb
            ├── home.html.erb
            ├── privacy.html.erb
            └── terms.html.erb

We’ll do that by typing the following commands:

mkdir app/views/pages
touch app/views/pages/about.html.erb
touch app/views/pages/contact.html.erb
touch app/views/pages/home.html.erb
touch app/views/pages/privacy.html.erb
touch app/views/pages/terms.html.erb

Take a few minutes to edit each of those 5 files so they contain some content.

Edit the file about.html.erb in app/views/pages/ to contain:

<h1>About Us</h1>
<p>Find me in app/views/pages/about.html.erb</p>

Edit the file contact.html.erb in app/views/pages/ to contain:

<h1>Contact Us</h1>
<p>Find me in app/views/pages/contact.html.erb</p>

Edit the file home.html.erb in app/views/pages/ to contain:

<h1>Home Page</h1>
<p>Find me in app/views/pages/home.html.erb</p>

Edit the file privacy.html.erb in app/views/pages/ to contain:

<h1>Privacy Policy</h1>
<p>Find me in app/views/pages/privacy.html.erb</p>

Edit the file terms.html.erb in app/views/pages/ to contain:

<h1>Terms of Service</h1>
<p>Find me in app/views/pages/terms.html.erb</p>

Application Routing

Next, we’ll setup routing. As mentioned in the previous section, we are going to make home.html.erb the root url for our project. We need to include a redirect for any root url page otherwise High Voltage will serve the same content up twice, at http://example.com/ and http://example.com/home, and that can effect the page rank in search engines. In a previous section, we discussed the need to setup a number of routes, like about_path, contact_path, etc., we’ll do that now. After edits, below are the contents of my routes.rb file:

Bootstrap::Application.routes.draw do

  get '/about'    => 'high_voltage/pages#show', id: 'about'
  get '/contact'  => 'high_voltage/pages#show', id: 'contact'
  get '/privacy'  => 'high_voltage/pages#show', id: 'privacy'
  get '/terms'    => 'high_voltage/pages#show', id: 'terms'

  get '/home', to: redirect('/')

  root :to => 'high_voltage/pages#show', id: 'home'

end

You might have noticed a discrepancy at this point. By default, High Voltage will serve our static pages at http://www.example.com/pages/about. That isn’t what we want so we’ll need to tell the gem to serve up these pages from the root of the domain path. That is very easy to do. In the config/initializers/ directory create a new file called high_voltage.rb. It’s content should be:

# config/initializers/high_voltage.rb
HighVoltage.route_drawer = HighVoltage::RouteDrawers::Root

I just wanted to mentioned that, with the initializer change is made, High Voltage is smart enought to route requests for /about to the correct page even if someone were to forget to create a get '/about' => 'high_voltage/pages#show', id: 'about' entry in their routes.rb file. However without that line, we would not be able to use about_path because Rails would not know how to route our request.

At this point, let’s pause for a moment. Start up a development server using rails s and test the 5 pages. If you already have one running, please restart it. If you use WEBrick on the default port, those paths would be:

http://localhost:3000/
http://localhost:3000/about
http://localhost:3000/contact
http://localhost:3000/privacy
http://localhost:3000/terms
http://localhost:3000/home

Make sure that last URL automatically takes you to http://localhost:3000/. Worked for me so I’m hopeful I did not miss a step while typing this up.

A few helpers

Next, we need a way to customize an HTML title element so that it changes as users navigate from one page to the next. I’ll be using a modified version of Michael Hartl’s full_title helper that you will find in his excellent Ruby on Rails Tutorial. We are also going to setup a number of methods so that it is easier to customize the application later. These additional methods are site_name, site_url, meta_author, meta_description and meta_keywords.

Open your application_helper.rb file in app/helpers and let’s add some content.

module ApplicationHelper

  def site_name
    # Change the value below between the quotes.
    "Project Name"
  end

  def site_url
    if Rails.env.production?
      # Place your production URL in the quotes below
      "http://http://www.example.com/"
    else
      # Our dev & test URL
      "http://localhost:3000"
    end
  end

  def meta_author
    # Change the value below between the quotes.
    "Website Author"
  end

  def meta_description
    # Change the value below between the quotes.
    "Add your website description here"
  end

  def meta_keywords
    # Change the value below between the quotes.
    "Add your keywords here"
  end

  # Returns the full title on a per-page basis.
  # No need to change any of this we set page_title and site_name elsewhere.
  def full_title(page_title)
    if page_title.empty?
      site_name
    else
      "#{page_title} | #{site_name}"
    end
  end

end

Please make sure to change the site_name, site_url, meta_author, meta_description and meta_keywords to suit your needs. I found it useful to review this article about How to Use HTML Meta Tags. Also, if you are building a larger application, it might be useful to put all of these methods in a new file in app/helpers called layout_helper.rb it might improve the readability of your application.

There are a number of other ways to solve this problem. Some might advocate using metamagic, meta-tags, storing this data in yml files or any number of other solutions. I might tackle one in a future article so let me know about your favorite. Right now, let’s get the static layout finished.

Now, let’s go back to all the pages and add the following code on Line 1:

<% provide(:title, 'Page Name Here') %>

Be sure to change the text Page Name Here to the title you would like to see. If you would prefer that the home page of your project only display the site_name, you have two choices. First you can choose to not include the code above at all or, secondly which is my preference, you could use leave the value blank like I have below:

<% provide(:title, '') %>

Now that we’ve finished setting up these methods, let’s turn to the layout.

It’s layout time

We want to implement a layout similar to the Jumbotron Template for Bootstrap with a few changes minor changes. Navigate to your app/views/layouts directory and open the application.html.erb file. If you just want to grab the file rather than read what I’ve done, you can skip ahead to Final contents of application.html.erb

I’m only going to spend time talking about the Rails related tweaks we are making to the Bootstrap 3 layout.

The <Head>

We’ll start with the HTML head. Earlier in this article, we created a number of methods in the application_helper.rb file and now we are going to use them. Here’s the content of my HTML Head:

<head>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="<%= meta_description %>">
  <meta name="author" content="<%= meta_author %>">
  <meta name="Keywords" content="<%= meta_keywords %>">

  <title><%= full_title(yield(:title)) %></title>

  <%= stylesheet_link_tag    "application", media: "all", "data-turbolinks-track" => true %>
  <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
  <%= csrf_meta_tags %>

  <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
  <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
  <![endif]-->
  <a href="#Top"></a>
</head>

You’ll see that we are populating the meta_description, meta_author and meta_keywords from the application_helper.rb file. That is done with these three lines:

<meta name="description" content="<%= meta_description %>">
<meta name="author" content="<%= meta_author %>">
<meta name="Keywords" content="<%= meta_keywords %>">

The title method we defined is also being used here:

<title><%= full_title(yield(:title)) %></title>

The Nav bar

Now we will turn our attention to the HTML body. At the top of our page, we wanted to have a navigation bar. On the left of this bar, we have our site_title that will respond to a click by taking you to our site_url. The most Rails like way to write this code is:

<%= link_to site_name, site_url, :class => "navbar-brand" %>

On the right side of our navigation bar, we want to show three buttons that direct you to their respective pages and have the list class of the button change if you are on its respective page.

<li class="<%= 'active' if current_page?(root_path) %>">
<li class="<%= 'active' if current_page?(about_path) %>">
<li class="<%= 'active' if current_page?(contact_path) %>">

If you find it redundant to have two links in the Nav bar pointing to the root url, just delete the entire home list item.

<li class="<%= 'active' if current_page?(root_path) %>"><%= link_to "Home", root_path %></li>

Then the only link to the root url with be the site_name on the left side of the Nav bar.

The Jumbotron

Support for the jumbotron necessitates code in the application.html.erb file because we need the jumbotron class to precend the container class. The latter is something I wanted in one place rather than having to remember to add it to each view later. So, we are going to check the current page and only display the jumbotron code when we are on the root url. That is done with the following:

<% if current_page?(root_path) %>
  <% if content_for?(:jumbotron) %>
    <div class="jumbotron">
      <div class="container">
        <%= yield :jumbotron %>
      </div>
    </div>
  <% end %>
<% else %>
  <div class="container">
<% end %>

We are also going to need to make modification the the home.html.erb file now to populate the jumbotron content. We’ll do that after we look at the application.html.erb footer.

The Footer

One of the things I wanted to include in this article was a Glyphicon. So in the bottom right corner of the footer, you will find the following code:

<%= link_to '<span class="glyphicon-class glyphicon glyphicon-chevron-up"></span> Back to top'.html_safe, '#Top' %>

Using html_safe is the prettiest way that I could think of to create the HTML required for Glyphicons. It produces the following HTML output:

<a href="#Top"><span class="glyphicon-class glyphicon glyphicon-chevron-up"></span> Back to top</a>

On the left side of the footer, we have a copyright line along with links to our Privacy and Terms pages.

&copy; <%= Time.now.year %> <%= site_name %>

<%= link_to "Privacy", privacy_path %></li>
<%= link_to "Terms", terms_path %></li>

If you would prefer to have range of years in your copyright line similar to:

© 2010 - 2012 Project Name

Then take a look at How to Automate Copyright Notice Updates in Ruby on Rails.

Revisiting home.html.erb

Let’s open the home.html.erb file in app/views/pages/. We need to add some content for our jumbotron. Before we do, just remember that if you would prefer not to have a jumbotron then just leave the value blank like this:

<% provide(:jumbotron, ''>

For thepurposes of this tutorial, I’m just going to add some default text. Please customize it to suit your needs.

<% provide(:jumbotron, '
    <h1>Hello, world!</h1>
    <p>This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.</p>
    <p><a class="btn btn-primary btn-lg" role="button">Learn more &raquo;</a></p>
'.html_safe)%>

The final contents of the home.html.erb file are at the end of this article.

Some improvements to the original CSS

If you followed my original article prior to a few updates, I used to include some overrides directly in the application.css file. Since then, I’ve made a few changes. My appication.css file, found in app/assets/stylesheets now contains:

/*
 *= require bootstrap_and_overrides
 *= require_self
 *= require_tree .
 */

In the same location app/assets/stylesheets, I have created a new file called bootstrap_and_overrides.css.scss and it contains:

@import "bootstrap.min";
@import "bootstrap-theme.min";

/* Move down content because we have a fixed navbar that is 50px tall */
body {
  padding-top: 50px;
  padding-bottom: 20px;
}

/* Override Rail's default error calls with Bootstrap 3 */
.field_with_errors {
  @extend .has-error;
}

/* Override Bootstrap 3 font location */
@font-face {
  font-family: 'Glyphicons Halflings';
  src: url('../assets/glyphicons-halflings-regular.eot');
  src: url('../assets/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), 
       url('../assets/glyphicons-halflings-regular.woff') format('woff'), 
       url('../assets/glyphicons-halflings-regular.ttf') format('truetype'), 
       url('../assets/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}

The .field_with_errors tweak came from Chris Oliver’s Trying Out Bootstrap 3.0.

Final contents of application.html.erb

<!DOCTYPE html>
<html>
<head>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="<%= meta_description %>">
  <meta name="author" content="<%= meta_author %>">
  <meta name="Keywords" content="<%= meta_keywords %>">

  <title><%= full_title(yield(:title)) %></title>

  <%= stylesheet_link_tag    "application", media: "all", "data-turbolinks-track" => true %>
  <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
  <%= csrf_meta_tags %>

  <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
  <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
  <![endif]-->
  <a href="#Top"></a>
</head>
<body>
  <div class="navbar navbar-fixed-top navbar-inverse" role="navigation">
    <div class="container">
      <div class="navbar-header">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <%= link_to site_name, site_url, :class => "navbar-brand" %>
      </div>
      <div class="collapse navbar-collapse">
        <ul class="nav navbar-nav pull-right">
          <li class="<%= 'active' if current_page?(root_path) %>"><%= link_to "Home", root_path %></li>
          <li class="<%= 'active' if current_page?(about_path) %>"><%= link_to "About", about_path %></li>
          <li class="<%= 'active' if current_page?(contact_path) %>"><%= link_to "Contact", contact_path %></li>
        </ul>
      </div><!-- /.nav-collapse -->
    </div><!-- /.container -->
  </div><!-- /.navbar -->

  <% if current_page?(root_path) %>
    <% if content_for?(:jumbotron) %>
      <div class="jumbotron">
        <div class="container">
          <%= yield :jumbotron %>
        </div>
      </div>
    <% end %>
  <% else %>
    <div class="container">
  <% end %>
  <%= yield %>
  <footer>
    <hr>
      <p class="pull-right">
        <%= link_to '<span class="glyphicon-class glyphicon glyphicon-chevron-up"></span> Back to top'.html_safe, '#Top' %>
      </p>
      <p>
        &copy; <%= Time.now.year %> <%= site_name %> 
        &bull;
        <%= link_to "Privacy", privacy_path %></li>
        &bull;
        <%= link_to "Terms", terms_path %></li>
      </p>
    </footer>
  </div> <!-- /container -->
</body>
</html>

Final contents of home.html.erb

<% provide(:title, '') %>

<% provide(:jumbotron, '
      <h1>Hello, world!</h1>
      <p>This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.</p>
      <p><a class="btn btn-primary btn-lg" role="button">Learn more &raquo;</a></p>
  '.html_safe)%>

  <div class="container">
    <!-- Example row of columns -->
    <div class="row">
      <div class="col-md-4">
        <h2>Heading</h2>
        <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
        <p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
      </div>
      <div class="col-md-4">
        <h2>Heading</h2>
        <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p>
        <p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
     </div>
      <div class="col-md-4">
        <h2>Heading</h2>
        <p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
        <p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
      </div>
    </div>

A sample application is now available on Github. Download it here.

If you have any suggestions or feedback about this article, please let me know in the comments, via email or on Twitter.

Using Bootstrap 3 with Rails 4

If you are looking to use Bootstrap 3 with Rails, then this article is for you. It provides a guide to adding Bootstrap 3, aka Twitter Bootstrap 3, to a new Rails 4 project. I found this article from Eric Minkel, however I’ve deviated slightly from his implementation and I decided to document it.

Let’s start by creating a new project:

rails new bootstrap

Next, we need Bootstrap 3 and you can download the latest version here. At the time this article was written, the latest Bootstrap release was v3.0.2.

I’m only interested in using the minimized Bootstrap files. We need to copy a number of files into our project from the Bootstrap download:

  1. Copy bootstrap.min.css to the /vendor/assets/stylesheets directory
  2. Copy bootstrap.min.js to the /vendor/assets/javascripts directory
  3. Copy the fonts directory and its contents to /vendor/assets/

Now that the files have been added to your project. We need to tell the application to use them.

Edit app/assets/stylesheets/application.css and add *= require bootstrap.min along with some @font-face overrides which change the path to the glyphicons. We’ll do that here to avoid changing the bootstrap files.

 *= require bootstrap.min
 *= require_self
 *= require_tree .
 */

@font-face {
  font-family: 'Glyphicons Halflings';
  src: url('../assets/glyphicons-halflings-regular.eot');
  src: url('../assets/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), 
       url('../assets/glyphicons-halflings-regular.woff') format('woff'), 
       url('../assets/glyphicons-halflings-regular.ttf') format('truetype'), 
       url('../assets/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}

Next, we need to edit app/assets/javascripts/application.js and add //= require bootstrap.min. Here’s a look at mine:

//= require jquery
//= require jquery_ujs
//= require bootstrap.min
//= require turbolinks
//= require_tree .

That is all it takes to add Bootstrap 3 to your rails application without a gem. There is also a sample application on Github, you can download it here.

I also recently published a new article that builds on this project. In it, I show you how to build the Bootstrap jumbotron in Rails. Check it out here.

If you have any suggestions or feedback, please let me know in the comments, via email or on Twitter.