Last Updated: September 09, 2019
·
28.78K
· blackfalcon

Web fonts and Rails' Asset Pipeline

Web fonts are pretty much all the rage. Using a CDN for font libraries, like TypeKit or Google Fonts, will be a great solution for many projects. For others, this is not an option. Especially when you are creating a custom icon library for your project.

Rails and the asset pipeline are great tools, but Rails has yet to get caught up in the custom web font craze.

As with all things Rails, there is more then one way to skin this cat. There is the recommended way, and then there are the other ways.

The recommended way

Here I will show how to update your Rails project so that you can use the asset pipeline appropriately and resource your files using the common Rails convention.

The default asset pipeline

When looking in your project's assets directory, you would see the following:

|-app/
|---assets/
|-----images/
|-----javascripts/
|-----stylesheets/

What we need to do is add the fonts directory within the assets directory so that we can resource these files in our CSS or Sass files using proper rails conventions and the asset pipeline.

The problem is, simply adding a fonts directory isn't picked up by the pipeline. For now, let's just add that in there and then fix the Rails issue next.

|-app/
|---assets/
|-----fonts/
|-----images/
|-----javascripts/
|-----stylesheets/

Updating the asset pipeline

The fix is pretty simple. Open your project's config file, located at config/application.rb and add the following line within your Application class:

config.assets.paths << Rails.root.join("app", "assets", "fonts")

BOOM! Now Rails is smart enough to know what to do with assets within the fonts directory.

Fonts path in your Sass

Default CSS that you will get from sites like icomoon.io will typically look something like this:

@font-face {
    font-family: 'icofonts';
    src:url('fonts/icofonts.eot');
    src:url('fonts/icofonts.eot?#iefix') format('embedded-opentype'),
        url('fonts/icofonts.ttf') format('truetype'),
        url('fonts/icofonts.woff') format('woff'),
        url('fonts/icofonts.svg#icofonts') format('svg');
    font-weight: normal;
    font-style: normal;
}   

That seems right, unless you are using the asset pipeline. So to make the path correct we need to make a slight update and replace src:url() with src:font-url(). Our Sass file would look like:

@font-face {
  font-family:'icofonts';
  src:font-url('icofonts.eot');
  src:font-url('icofonts.eot?#iefix') format('embedded-opentype'),

  ...
} 

When the Sass is rendered into CSS, you should see something like the following:

@font-face {
  font-family: 'icofonts';
  src: url(/assets/icofonts.eot);
  src: url(/assets/icofonts.eot?#iefix) format("embedded-opentype"), 
    url(/assets/icofonts.ttf) format("truetype"), 
    url(/assets/icofonts.woff) format("woff"), 
    url(/assets/icofonts.svg#icofonts) format("svg");
  font-weight: normal;
  font-style: normal;
}

Perfect. Our fonts are in the assets directory where it feels best. Our code is clean and follows all the common Rails conventions. YAY!