How to embed fonts with React and styled-components
Tags: react, styledcomponents, javascript, fonts
Published: 2022-11-16 12:15:47

In this post I will show you how to embed fonts into your React App using styled components. It is not unusual that you need to use a specific font in a project you are working with React. The reason why it can be a good practice to embed a font with your app is that different browses and devices use different rendering engines so the font you are using while developing may not be the same your client is seeing. Okay, but how can we embed a font within our React app?

## Getting the font extensions

First of all, you need to choose the font you want to use. For the purpose of this tutorial, I will choose the font 'Montserrat' from [Google Fonts](https://fonts.google.com/), but you can choose any other font. After choosing your font from Google Fonts, you will see something like this.

![Google Fonts page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9pnevkzl1q73iq2xlhed.png)

Now, just click in the button **Download family** in the top right side of the page to download the font. After unzipping the file you will see a folder with all the styles available for the font you selected, like this

![Font styles](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ity6urzpn5cwtmt0sq7v.png)

**Remark 1:** it is important to notice that not all the fonts have the same weights and styles as this one. Some fonts have just specific weights or even don't have the italic or bold styles.

As you noticed, the fonts shown in your folder have the extension ttf which stands for true type font. Actually, in order to meet the best cross-browser standards you will need 5 font file extensions: eot, ttf, woff, woff2 and svg. In this tutorial I will show you how to get all these extensions, but you can use only ttf if you want. It is just that you don't have guarantee that it will fit perfectly to all browsers. 

If you don't have all the extensions above I suggest the use of the [Transfonter](https://transfonter.org/) site. It provides you the other fonts extensions. You just have to drag and drop or upload the fonts you want in your project. Here, I will use the regular, italic, bold and bold italic of Montserrat. So, after uploading the ttf fonts from Montserrat to **Transfonter**, do not forget to check the formats you want (in this example, I will check them all) and once it's done, click the button **Convert**.

![how to use the transfonter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/neo07vzxydkt0dh62y22.png)

After that, it will process and you can download all the other extensions by clicking the download link as shown in the image below.

![Transfonter output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5egdyc35fdgw4g6r8d6b.png)

Unziping the file, you can see the all the extensions you have chosen. In my case I will have 20 font files (5 for each ttf I selected) and two more files: a demo.html and a stylesheet.css.

![Transfonter output unzipped](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxhdxpqp5a9l15pnundt.png)

## Creating your project

Now that we have our fonts, let's code! First of all, I will create a React project using [create react app](https://create-react-app.dev/docs/getting-started/) standard boilerplate. So go to the folder you want in your terminal and type
```javascript
npx create-react-app react-fonts
```
or, using yarn (that's my choice).
```javascript
yarn create react-app react-fonts
```
Once it install everything, go to the code editor of your preference (I'm using Visual Studio Code) and open the folder. You will see the create react app boilerplate.

![Create react app boilerplate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/87brzvxk5p5q31v8m6wo.png)

Go to your terminal and type

```javascript
npm start
```
or (if using yarn)
```javascript
yarn start
```
and you will see the following in your browser.

![React initial page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mpo934m1d1eg3hbrcasu.png)

Great! Everything is working perfectly so far. Since we will use the styled-components in this tutorial, you can add it to your dependencies. So, again, go back to your terminal and type

```javascript
npm install --save styled-components
```
or (if using yarn)
```javascript
yarn add styled-components
```
and this will install the styled-components.

## Including the fonts to your project

Well, the first thing that comes to mind is: where do I include the fonts?

There is no right answer to that, but here I will create a folder named **fonts** inside the src folder as shown in the image below.

![fonts folder](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dacyabwfnfyt5h68nbg0.png)

Now, I will select all my font files and copy them inside the **fonts** folder.

![Font extensions copied](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d74paf8sjak8wdbkjpgw.png)

## Creating Global Styles using styled-components

Now we already add the fonts to the project but we can't use them yet. Before, we will use styled-components to create a global styles. In order to do that, I will create a new file named `styles.js` inside the src folder.

![adding styles.js file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cr7103chwvhitms7azri.png)

and, inside this file we type the following code

```javascript
import { createGlobalStyle } from 'styled-components';

import MontserratRegularEot from './fonts/Montserrat-Regular.eot';
import MontserratRegularSvg from './fonts/Montserrat-Regular.svg';
import MontserratRegularTtf from './fonts/Montserrat-Regular.ttf';
import MontserratRegularWoff from './fonts/Montserrat-Regular.woff';
import MontserratRegularWoff2 from './fonts/Montserrat-Regular.woff2';
import MontserratItalicEot from './fonts/Montserrat-Italic.eot';
import MontserratItalicSvg from './fonts/Montserrat-Italic.svg';
import MontserratItalicTtf from './fonts/Montserrat-Italic.ttf';
import MontserratItalicWoff from './fonts/Montserrat-Italic.woff';
import MontserratItalicWoff2 from './fonts/Montserrat-Italic.woff2';
import MontserratBoldEot from './fonts/Montserrat-Bold.eot';
import MontserratBoldSvg from './fonts/Montserrat-Bold.svg';
import MontserratBoldTtf from './fonts/Montserrat-Bold.ttf';
import MontserratBoldWoff from './fonts/Montserrat-Bold.woff';
import MontserratBoldWoff2 from './fonts/Montserrat-Bold.woff2';
import MontserratBoldItalicEot from './fonts/Montserrat-BoldItalic.eot';
import MontserratBoldItalicSvg from './fonts/Montserrat-BoldItalic.svg';
import MontserratBoldItalicTtf from './fonts/Montserrat-BoldItalic.ttf';
import MontserratBoldItalicWoff from './fonts/Montserrat-BoldItalic.woff';
import MontserratBoldItalicWoff2 from './fonts/Montserrat-BoldItalic.woff2';

export default createGlobalStyle`

@font-face {
  font-family: 'Montserrat';
  font-weight: normal;
  font-style: normal;
  font-display: swap;
  src: url(${MontserratRegularEot});
  src: url(${MontserratRegularEot}) format('embedded-opentype'),
    url(${MontserratRegularWoff2}) format('woff2'),
    url(${MontserratRegularWoff}) format('woff'),
    url(${MontserratRegularTtf}) format('truetype'),
    url(${MontserratRegularSvg}) format('svg');
  }

  @font-face {
    font-family: 'Montserrat';
    font-weight: normal;
    font-style: italic;
    font-display: swap;
    src: url(${MontserratItalicEot});
    src: url(${MontserratItalicEot}) format('embedded-opentype'),
      url(${MontserratItalicWoff2}) format('woff2'),
      url(${MontserratItalicWoff}) format('woff'),
      url(${MontserratItalicTtf}) format('truetype'),
      url(${MontserratItalicSvg}) format('svg');
  }

  @font-face {
    font-family: 'Montserrat';
    font-weight: bold;
    font-style: normal;
    font-display: swap;
    src: url(${MontserratBoldEot});
    src: url(${MontserratBoldEot}) format('embedded-opentype'),
      url(${MontserratBoldWoff2}) format('woff2'),
      url(${MontserratBoldWoff}) format('woff'),
      url(${MontserratBoldTtf}) format('truetype'),
      url(${MontserratBoldSvg}) format('svg');
  }

  @font-face {
    font-family: 'Montserrat';
    font-weight: bold;
    font-style: italic;
    font-display: swap;
    src: url(${MontserratBoldItalicEot});
    src: url(${MontserratBoldItalicEot}) format('embedded-opentype'),
      url(${MontserratBoldItalicWoff2}) format('woff2'),
      url(${MontserratBoldItalicWoff}) format('woff'),
      url(${MontserratBoldItalicTtf}) format('truetype'),
      url(${MontserratBoldItalicSvg}) format('svg');
  }

`;
```
With the code above we just create a global component (in this case with just font styles) with whom we will just wrap the entire App inside this global component, so we can use the Montserrat font wherever we need. After that we import every font with an alias and create them using the CSS `@font-face` declaration. In this point you just have to create one `@font-face`declaration to every font style you selected. Notice that each have the respective `font-family`, `font-weight` and `font-style` to the font. It is also a good idea to include the descriptor `font-display`, and here I will be using the value **swap** which means it shows the font fallback option when the custom font is loading, i.e, there will always be a font shown to the user while rendering the selected font in your app, it won't be empty, which can be a little annoying.

Okay, but if you look to your browser nothing happened yet. And that is why we didn't include these global styles and, of course, we didn't call the Montserrat font at any component.

## Including the global styles

Now it's time to include the global styles. That is really easy. Just go to the `index.js` file and import the styles with any name you want (I will be using GlobalFonts at this step) and call the global component before calling the App component

```javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import GlobalFonts from './styles';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <GlobalFonts />
    <App />
  </React.StrictMode>
);
reportWebVitals();
```
Now, you can use everything you create inside your global styles at any component of your project. In this tutorial, of course, I'm just using font styles, but you can use other styles to any html tag or any CSS class you want.

## Using the custom font in your component

The last part of this tutorial is how you can use the font. If you did everything so far, it is really easy this last part. First, we create a new file called **App.styled.js** at src folder.

![App.styled.js file created](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uvs9jwmeong7w27znjmr.png)

Inside of it we create the following code.

```javascript
import styled from 'styled-components';

const CustomFont = styled.h1`
  font-family: 'Montserrat';
  font-weight: normal;
  font-size: 30px;
`;

export { CustomFont };
```

Well, this is very straight forward. Here we are just importing `styled` from styled-components and creating a `CustomFont` component, which will be a `h1` tag styled with the Montserrat regular font with 30px size.

Then, we move to the **App.js***, import this CustomFont component and change the code to shown all the Montserrat styles as shown in the code below.

```javascript
import logo from './logo.svg';
import './App.css';
import { CustomFont } from './App.styled';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <CustomFont>Montserrat regular</CustomFont>
        <CustomFont style={{ fontStyle: 'italic' }}>Montserrat italic</CustomFont>
        <CustomFont style={{ fontWeight: 'bold' }}>Montserrat bold</CustomFont>
        <CustomFont style={{ fontWeight: 'bold', fontStyle: 'italic' }}>Montserrat bold italic</CustomFont>
      </header>
    </div>
  );
}

export default App;
```

And now, if you look into your browser, you will see the following.

![App final output with custom font](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y6xh90mqhkrifns4ych5.png)

As you can see, the Montserrat is now being used in your App.

## Conclusion

As we can see in this simple tutorial, it is not difficult to embed custom fonts in your React project using styled-components and the CSS `@font-face`. Also, I really recommend you to embed the fonts into your project since, otherwise you can't guarantee it can be rendered properly at most of web browsers.

Well, I hope you all like this tutorial. If you're reading so far, thank you so much and if you have some questions, just let me know!