Tired of being limited to requesting fonts over a CDN? Look no further.
You might be required to import a font for a number of reasons - ranging from buying corporate licenses for certain fonts, to availability concerns or even because your favourite font isn't available through a CDN (Content Delivery Network).
Since I've started working as a developer, I've learned how to import a web font directly rather than linking to a CDN where the font might be hosted. Since I didn't really know where to start, I thought I'd write up this quick tutorial to show you how you can accomplish this in a React setting using styled components version 4 - my favourite way of writing CSS in React apps.
Let's get down to business
First of all, you need select the font you want to import and download it in woff and woff2 format. Woff (and later Woff2) stands for Web Open Font Format and is the recommended font format by the World Wide Web Consortium (W3C). Its format specific compression ensures its performance in all browsers and furthermore reduces web font latency as opposed to requesting fonts from a CDN.
There are a few sites where you can download these, for example:
Pick anything you like!
I'd advise you to import at least those two font formats, woff and woff2, since they have been recommended by the W3C and are widely supported on all browsers.
In your React project, create a folder in your src folder and name it 'fonts'. In this folder create a file which you call fonts.js - this will contain the imports for your fonts and will later make them available to the rest of your app.
In the same folder, now place the two font files you have just downloaded. This will make them accessible for your app to import them correctly. After doing this, your file structure should look similar to this:
src
|__fonts
|__fonts.js
|__nameOfYourFont.woff2
|__nameOfYourFont.woff
Now, let's actually write some code into the fonts.js file so 'styled components' can import them as a Global Font.
In your fonts.js file import the { createGlobalStyle } from 'styled-components'. This is a handy little helper that handles global css styles in your app. If you want to to dive in, visit createGlobalStyle on the styled components documentation. After doing that, you have to import the fonts into your file and declare them in a font-face declaration.
import { createGlobalStyle } from 'styled-components';
import NameOfYourFontWoff from './nameOfYourFont.woff';
import NameOfYourFontWoff2 from './nameOfYourFont.woff2';
export default createGlobalStyle`
@font-face {
font-family: 'Font Name';
src: local('Font Name'), local('FontName'),
url(${NameOfYourFontWoff2}) format('woff2'),
url(${NameOfYourFontWoff}) format('woff');
font-weight: 300;
font-style: normal;
}
`;
This will import your chosen font in both woff and woff2 formats and make it accessible through the fonts file.
But that's only half of the battle done.
While we have imported the specific fonts, we haven't actually imported these in our App yet.
At the top of the App.js file, after importing React, write
import GlobalFonts from './fonts/fonts';
// assuming you places fonts in your src folder as described above.
Somewhere in the App.js file, preferably just below a normal styled component that would typically contain site layout or similar and doesn't need any font styles, place the GlobalFonts component in your return of the render:
render() {
return (
<Wrapper>
<GlobalFonts />
// ...
</Wrapper>
);
}
After doing this, you are free to use your font anywhere in your styles as you choose. In any styled-components file, just declare (for example):
const AwesomeHeadline = styled.h1`
font-family: 'Font Name';
`;
export default AwesomeHeadline;
Et voila, you just imported your web font and used it in a Headline!
I hope this helps you to import fonts in the future, be it for work or that awesome personal project with that personal touch!
Top comments (18)
Thank yooouuuuu!!!! ♥♥♥
And for those using TypeScript, create a
fonts.d.ts
file in /src folder and include the font extensions you want to import, like below ↓↓↓:declare module '*.woff';
declare module '*.ttf';
Don't write formats like
format('ttf')
orformat('otf')
, because it is not gonna work.If you are using TTF or OTF fonts, in the format options of
@font-face
, you should write as:format('truetype');
format('opentype');
Don't use spaces when naming your font files
Wrong:
My Awesome Font.ttf
Right:
MyAwesomeFont.ttf
That's it! Now your project's Typescript understands fonts.
I created an account on this website just to like this and say thank you. Been tearing out my hair trying to figure out why this darned font wouldn't load-- it was because of the spaces. Thank you for this.
Do you by change know how to handle the font delivery when using this approach in a component library?
I setup my library to be bundled with rollupjs and the
@rollup/plugin-url
, however when running the implementing react application, the fonts are requested directly via http./[hasedname].woff
which results in a 404.Did you find any solutions for this?
great article. If I want all my components to use this font without specifying the font again and again for every component, how would I do that?
edit: in the global styles file do
* {
font-family:...
}
Great post! What if I were to import a whole family of fonts?
Followed step by step (except for downloading two font formats) and downloaded my fonts from the site provided but just get an error
Thank you very much. Very informative. For people like me who are using Typescript you might want to declare your your font file types described here:
designcise.com/web/tutorial/how-to...
You can also to this:
Interesing approach! Thanks for share it.
It works on React Native ?
Thank you ❤️, you saved my life!