Read more

Using local fonts with Webpack / Webpacker

Jakob Scholz
March 22, 2019Software engineer at makandra GmbH

When we want to use our own (or bought) fonts in an application with Webpack(er), we have two options. We can

  • put the fonts directly into your Webpack's assets folder or
  • write an npm package with an own sass file that can be imported from the Webpack manifest.

Load fonts from your assets folder

Illustration UI/UX Design

UI/UX Design by makandra brand

We make sure that your target audience has the best possible experience with your digital product. You get:

  • Design tailored to your audience
  • Proven processes customized to your needs
  • An expert team of experienced designers
Read more Show archive.org snapshot

The first option turns out to be straightforward: Import the stylesheets in the index.js of the pack you're using:

// webpack_source_path/application/index.js

import './stylesheets/reset'
import './stylesheets/main' // loads the fonts in
let stylesheetsContext = require.context('./stylesheets/blocks', true, /\.sass$/)
for(let key of stylesheetsContext.keys()) { stylesheetsContext(key) }
// webpack_source_path/application/stylesheets/main.sass

@import 'font_faces'

html
  font-family: MyFont, Arial
// webpack_source_path/application/stylesheets/_font_faces.sass

@font-face
  font-family: 'MyFont'
  src: url('../fonts/my_font.ttf')

Webpack will replace ../fonts/my_font.ttf with the compiled filepath (something like media/application/fonts/my_font-f99f9d50a569dbcf72e3084ef1a43208.ttf) and you're good.

Load fonts as an npm package

The second option is handy when you're dealing with fonts that are not maintained by yourself but neither are available on npm. In our case, we purchased a font that had hashed filenames for each font version (normal, bold, ...). You don't want to mess around with assets you don't maintain, so renaming them is not a good option. Neither is inserting cryptic filenames to your code a good manner, it can affect readability in a terrible way.
The better option is to bundle your local font into an npm package and to add a dependency in your project's package.json file which loads this bundled font:

// ./package.json

{
  "name": "my_project",
  "private": true,
  "dependencies": {
    "@rails/webpacker": "^3.0.2",
    "bought-font": "file:vendor/asset-libs/bought-font"
  },
  "devDependencies": {
    "webpack-dev-server": "^2.9.5"
  }
}

Note the path's prefix file: in the dependency of 'bought-font', which tells Webpack to not search npm for a matching package, but to look for a local directory.
The directory you are pointing to should also contain a package.json file so Webpack can interpret the folder as an npm package.

// vendor/asset-libs/bought-font/package.json

{
  "name": "bought-font",
  "version": "1.0.0",
  "description": "",
  "main": "index.scss",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Salesman of trust",
  "license": "LICENSE",
  "private": true
}

Webpack will now handle the font as a package and you can import the shipped scss/sass/css file, which contains the font-faces, in your pack's manifest and just use the defined fonts in your application:

//webpack_source_path/application/index.js

import 'bought-font/index.scss'
Jakob Scholz
March 22, 2019Software engineer at makandra GmbH
Posted by Jakob Scholz to makandra dev (2019-03-22 11:52)