DEV Community

Cover image for Serving custom fonts with cssbundling-rails
Mikael Henriksson
Mikael Henriksson

Posted on • Updated on

Serving custom fonts with cssbundling-rails

originally posted at https://mhenrixon.com/posts/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 of all, 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;
}
Enter fullscreen mode Exit fullscreen mode

Adding opensans.css to manifest.js

Then we have to add the special font file to the asset manifest. This ensures that the assets will be 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
Enter fullscreen mode Exit fullscreen mode

Configure TailwindCSS

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

// ./tailwind.config.js

module.exports = {
  content: [
    "./app/**/*.html.erb",
    "./app/helpers/**/*.rb",
    "./app/javascript/**/*.js",
    "./app/assets/stylesheets/**/*.js",
    "./app/components/**/*.js",
    "./app/components/**/*.css"
  ],
  theme: {
    fontFamily: {
      sans: [
        "Open Sans",
        "ui-sans-serif",
        "system-ui",
        "-apple-system",
        "BlinkMacSystemFont",
        '"Segoe UI"',
        "Roboto",
        '"Helvetica Neue"',
        "Arial",
        '"Noto Sans"',
        "sans-serif",
        '"Apple Color Emoji"',
        '"Segoe UI Emoji"',
        '"Segoe UI Symbol"',
        '"Noto Color Emoji"'
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Precompiling opensans.css.erb

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

# ./config/initializers/assets.rb

Rails.application.config.assets.precompile += %w[opensans.css.erb]
Enter fullscreen mode Exit fullscreen mode

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">
  <head>
    <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 %>
  </head>
</html>
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
rodreegez profile image
Adam Rogers

Thank you - this dug me out of a hole.

One potential correction: I think the initializer lives at ./config/initializers/assets.rb rather than ./app/config/initializers/assets.rb

Thanks again.

Collapse
 
mhenrixon profile image
Mikael Henriksson

Thanks, I'll correct that!