Serving fonts with Propshaft and Tailwind
Recently I've been using tailwindcss more and more to style web applications, with propshaft as my preferred asset pipeline since Rails 7. Often, custom fonts are needed when designing and building web applications. This post will focus on how to use both tools in a Rails application to serve custom fonts.
#Custom fonts with Tailwind
You can configure a custom font using a service like Google Fonts by adding links to the head of your layout and defining the font in your Tailwind config.
<!-- app/views/layouts/application.html.erb -->
<head>
<!-- ... -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
<!-- ... -->
</head>
// config/tailwind.config.js
module.exports = {
// ...
theme: {
extend: {
// ...
fontFamily: {
poppins: ['Poppins', 'sans-serif'],
},
},
}
}
The custom font can then be applied using the font-poppins
class.
This approach works well, is easy to configure, and is likely to be served to the client from a Content Delivery Network (CDN) —which can mean fast, cached responses.
However, there are times when you might need to serve fonts directly from your application.
#Serving custom fonts with Propshaft
Propshaft is a new asset pipeline for Rails 7, designed to be a simpler and faster solution compared to previous options (e.g. Sprockets).
By default, Propshaft will make all assets in directories in app/assets
available to be served and will copy them all to public/assets
when
precompiling.
This means you can add a downloaded font to app/assets/fonts
and it will "just
work".
In this example, I've downloaded the Chivo Mono font and saved it as
app/assets/fonts/chivo-mono.ttf
.
Then we can configure Tailwind to use the font. We need to define the font in the config, and define a font-face rule in our CSS.
// config/tailwind.config.js
module.exports = {
// ...
theme: {
extend: {
// ...
fontFamily: {
chivo: ['Chivo Mono', 'sans-serif'],
},
},
}
}
/* app/assets/stylesheets/application.tailwind.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
@font-face {
font-family: 'Chivo Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('chivo-mono.ttf');
}
}
Again, the font-chivo
class can be used to apply the font to elements in your
HTML.
It's important to note that Propshaft copies all assets to public/assets
in a
flat structure, irrespective of the directory it is placed in app/assets
.
This means we only need to reference chivo-mono.ttf
, rather than
fonts/chivo-mono.ttf
.
This gotcha might seem obvious, but it tripped me up for long enough to write this post!