Serving custom fonts with cssbundling-rails
Tags: rails, tailwindcss
Published: 2022-07-10 10:25:26

_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.

```erb
@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 special font file to the asset manifest. This ensures that the assets will be served both in development and production.


```js
// ./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 just add `Open Sans` to them sans fonts.


```js
// ./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"'
      ]
    }
  }
}
```

## Precompiling opensans.css.erb

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

```ruby
# ./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`.

```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>
```