Using Google Fonts locally (in hjs-webpack and React)

Note: in this tutorial I am using hjs-webpack and React. The concepts here can be easily adapted to full blown webpack by copying hjs-webpack's base config.

Moving on!

Why @font-face is an exception to the convention of inline styles

Often in React apps, we shy away from global styles. We favor components either styling themselves or allowing parent components to pass in styles via props as to maximize reusability.

Google Fonts use CSS's @font-face via a link tag or an @import statement in order to bring fonts in from the web.

Using @font-face in CSS is an exception as it cannot be inlined. Thus, we must make an exception and use a global stylesheet for this case.

When using Webpack, we no longer rely on a CDN for our resources. Instead we use local resources. So how do we use Google Fonts locally and define global styles in our React app?

Getting started

Step 1: Install loaders

In order to load fonts, we're going to need some webpack loaders. These loaders will look for the fonts we need on the filesystem. You're probably used to using a CDN when you use Google fonts. Google's CDN automatically provides the right font type based on the file extension you provide. Webpack can do the same kind of things when using the correct loaders.

hjs-webpack is already configured to lazily use the following loaders but it is up to you to actually opt-in to using them.

To opt in, we use npm install. Remember that loaders should always be installed with --save-dev and not --save since they are not distributable code.

1
npm install --save-dev css-loader file-loader postcss-loader style-loader url-loader

Create folder structure

I'll assume your source code lives in a src directory in the root of your project. I'll also assume your main React app component is in src/App.jsx. In your src directory create a directory called assets. Inside of that directory, create two directories, one called fonts, the other called styles.

Your initial structure will look something like this:

1
2
3
4
5
6
7
8
9
/
public/
src/
assets/
fonts/
styles/
App.jsx
package.json
webpack.config.js

Download and extract font files

To find and download Google Fonts files you can use this fantastic tool which will let you download preview and download the fonts in a variety of font formats (all of which are needed to support older browsers):

https://google-webfonts-helper.herokuapp.com

For this example I've downloaded Open Sans. Once you have downloaded the zip file, extract the font files to src/assets/fonts. If you want more than one font in your application, just put them in src/assets/fonts as well.

Create and import the global styles

Now that we have some loaders installed, and our file structure created we can use the loaders to import global styles. Remember that this is an exception to the convention of using inline styles. Certainly you could put tons of CSS in the following file, but generally I'd try to keep it as lean as possible.

In src/assets/styles, create a file called global.css and place the following code in it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: url('../fonts/open-sans-v13-latin-regular.eot'); /* IE9 Compat Modes */
src: local('Open Sans'), local('OpenSans'),
url('../fonts/open-sans-v13-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/open-sans-v13-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/open-sans-v13-latin-regular.woff') format('woff'), /* Modern Browsers */
url('../fonts/open-sans-v13-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/open-sans-v13-latin-regular.svg#OpenSans') format('svg'); /* Legacy iOS */
}
body {
font-family: 'Open Sans';
}

The code above defines a new font and applies that font to the body tag of our application. You should omit body { font-family: 'Open Sans';} if you do not want to apply your font to the body tag.

Next edit src/App.jsx to import the global.css file using the following:

1
import globalStyles from '../assets/global.css';

Node: you only need to import this file once in your App.jsx. You do not need to import it in every component, even if that component uses a font listed in global.css. This is still CSS so the styles from global will cascade down into your components.

If you want to use more than one Google Font (for example Lato), just put the additional @font-face CSS from the Google Webfont Helper into global.css. You can then use the additional font in a component's render method using <p style={{fontFamily: 'Lato'}}>Lorem ipsum</p>.

Share Comments

Getting Started with Angular 2 and TypeScript

The following is a presentation that I gave at several conferences and it covers some of the basic concepts in Angular 2 and TypeScript. At the time of this recording Angular 2 was still in alpha so some of the code may be outdated. Nevertheless, the concepts should continue to be useful as you learn about Angular 2 or any component based framework that encourages uni directional data flow.

Check out the slides and follow along.

I've also included a recorded version of the talk.

I hope it is helpful as you learn about Angular 2!

Banner image courtesy of Tuncay Yilmaz. Public domain.

Share Comments