Serving custom fonts with cssbundling-rails

Choosing a font

My font of choice is Open Sans; I downloaded it and added the various font files to the `app/assets/fonts/OpenSans` directory.

Using .css.erb

First, to make the `asset_url` helpers work, we need to use a `.css.erb` file to direct the fonts through the asset pipeline. Using paths directly won't be possible in production when the assets have had a digest added to them.

@font-face {
  font-family: "Open Sans";
  src: url("<%= font_path('OpenSans/Bold/OpenSans-Bold.woff2') %>") format("woff2"),
       url("<%= font_path('OpenSans/Bold/OpenSans-Bold.woff') %>") format("woff"),
       url("<%= font_path('OpenSans/Bold/OpenSans-Bold.ttf') %>") format("truetype");
  font-weight: bold;
  font-style: normal;

@font-face {
  font-family: "Open Sans";
  src: url("<%= font_path('OpenSans/BoldItalic/OpenSans-BoldItalic.woff2') %>") format("woff2"),
       url("<%= font_path('OpenSans/BoldItalic/OpenSans-BoldItalic.woff') %>") format("woff"),
       url("<%= font_path('OpenSans/BoldItalic/OpenSans-BoldItalic.ttf') %>") format("truetype");
  font-weight: bold;
  font-style: italic;

@font-face {
  font-family: "Open Sans";
  src: url("<%= font_path('OpenSans/ExtraBold/OpenSans-ExtraBold.woff2') %>") format("woff2"),
       url("<%= font_path('OpenSans/ExtraBold/OpenSans-ExtraBold.woff') %>") format("woff"),
       url("<%= font_path('OpenSans/ExtraBold/OpenSans-ExtraBold.ttf') %>") format("truetype");
  font-weight: 800;
  font-style: normal;

@font-face {
  font-family: "Open Sans";
  src: url("<%= font_path('OpenSans/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff2') %>") format("woff2"),
       url("<%= font_path('OpenSans/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff') %>") format("woff"),
       url("<%= font_path('OpenSans/ExtraBoldItalic/OpenSans-ExtraBoldItalic.ttf') %>") format("truetype");
  font-weight: 800;
  font-style: italic;

Adding opensans.css to manifest.js

Then we have to add the particular font file to the asset manifest. This step ensures that the assets are served both in development and production.


// ./app/assets/config/manifest.js

//= link_tree ../fonts
//= link_tree ../images
//= link_tree ../builds
//= link opensans.css
//= link_tree ../../javascript .js

Configure TailwindCSS

To use our custom font as default in TailwindCSS, we need to add `Open Sans` to them sans fonts.


// ./tailwind.config.js

module.exports = {
  content: [
  theme: {
    fontFamily: {
      sans: [
        "Open Sans",
        '"Segoe UI"',
        '"Helvetica Neue"',
        '"Noto Sans"',
        '"Apple Color Emoji"',
        '"Segoe UI Emoji"',
        '"Segoe UI Symbol"',
        '"Noto Color Emoji"'

Precompiling opensans.css.erb

Precompile the erb asset to make use of it in the assets pipeline:


# ./app/config/initializers/assets.rb

Rails.application.config.assets.precompile += %w[opensans.css.erb]

Loading opensans

The last step is to load the font file in the application.html.erb.


<!-- app/views/layouts/application.html.erb -->
<!DOCTYPE html>
<html class="min-h-screen">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <%= stylesheet_link_tag "opensans", "data-turbo-track": "reload", defer: true %>
    <%= stylesheet_link_tag "application", "data-turbo-track": "reload", defer: true %>
    <%= javascript_importmap_tags %>

Mikael Henriksson

6 min read