How to use web fonts and SCSS stylesheet after LEVEL UP to React?
Tags: react, scss, webdev, newbie
Published: 2021-08-10 08:19:57

If you are a newbie like me, I have two questions for you:

When you first learnt HTML, CSS and JavaScript:
1. How did you use `Roboto` from Google fonts in your page? Probably via a `<link>` tag in `index.html`, or an `@import` statement in the CSS style sheet? 
2. What do you do if you want to use SCSS instead of CSS? Probably you need some compiler to turn your SCSS into CSS, then include the compiled CSS file with a `<link>` tag in `index.html`?

I was taught to do things as I described above. When I "level up" to React, I kept doing the same thing. Turn out these "classic" ways of loading web fonts and importing SCSS stylesheet are NOT the best practice with React. 

---
## How to add SCSS stylesheet in create-react-app project? 

According to the [create-react-app documentation](https://create-react-app.dev/docs/adding-a-sass-stylesheet):
1. First you need to install `node-sass` in your command line, either via npm or yarn.
  ```
  # example from create-react-app documentation

  $ npm install node-sass --save
  $ # or
  $ yarn add node-sass
  ```
2. Then you can import the SCSS file from JS directly via `@import` statement, like so:
  ```
  // app.js

  import "./app.scss"
  ``` 

So that means, unlike the "classic" approach (as mentioned at the beginning), a compiler like [Live Sass Compiler](https://marketplace.visualstudio.com/items?itemName=ritwickdey.live-sass) is no longer necessary. 

To quote from [create-react-app guide on "adding a style sheet"](https://create-react-app.dev/docs/adding-a-stylesheet):
> This project setup uses Webpack for handling all assets. 

This means Webpack handles the compilation, we don't have to do it ourselves with a compiler.

---
## How to load web fonts in create-react-app project?

We will use [Google Fonts `Roboto`](https://fonts.google.com/specimen/Roboto) in the following example.

You are probably familiar with the two choices from Google Font, 
- via a `<link>` tag in `index.html`, which is the choice on the left radio button in the following picture.
- copy the `@import` content and paste it into SCSS or CSS file, which is the choice on the right radio button in the following picture.   

![google-fonts-import.PNG](https://cdn.hashnode.com/res/hashnode/image/upload/v1628581741960/HIUysc7rR.png)

So which one should you choose, and which one is a better way? Let's discuss one by one:

### 1. `@import` statement in SCSS/ CSS file

If you use an `@import` statement in SCSS/ CSS file, you have to import that SCSS/ CSS file into your JavaScript file (don't forget to install `node-sass` first for SCSS), like so:

```
// app.scss or app.css

@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap');
```

  ```
  // app.js

  import "./app.scss"   // if you are using SCSS
  import "./app.css"    // if you are using CSS
  ``` 

According to [this StackOverflow  answer](https://stackoverflow.com/questions/41676054/how-to-add-fonts-to-create-react-app-based-projects), importing web font via `@import` statement to an SCSS/CSS file "ensures your fonts go through the build pipeline", which means to say Webpack will "verify that the (font) file actually exists" when compiling, and therefore it is a recommended practice according to this answer.

### 2. A `<link>` tag in `index.html` inside the `public` folder

According to the same [StackOverflow answer](https://stackoverflow.com/questions/41676054/how-to-add-fonts-to-create-react-app-based-projects) above. You can also do it the "classic" way BUT it is not recommended since the font loaded this way "does not go through the build pipeline". 

So it should be clear now. Always use `@import`, right? Not so quick to jump to the conclusion yet. Turn out there's a speed advantage of using a `<link>` tag:

According to [this article](https://web.dev/font-best-practices/#preconnect-to-critical-third-party-origins) from Google Developers: 
> Google Fonts provides the option to load fonts via `<link>` tags or an `@import` statement. The `<link>` code snippet includes a `preconnect` resource hint and therefore will likely result in faster stylesheet delivery than using `@import` version.  

So which one should we follow?

### My conclusion for now

I am not yet "level up" enough to think about optimization at this point. So I am taking the advice from both links and use `@import` in my SCSS for now.

### Other ways to load web fonts
The two methods described above are by no means exhaustive. There are other ways to load web fonts that I did not include, such as: 

- `@font-face`
- `Webfont` package which can be installed via either npm or yarn.

I am sure there are other (better) ways of doing things that I am unaware of. If you do know better, kindly leave a suggestion below. 

### Fonts is a BROAD topic 
When I research for this article I found that fonts is a broad topic. Sometimes the answers/ articles  conflict with one another so I can't be 100% sure of what I wrote is correct. So if you find anything inaccurate please feel free to point it out. 

### Resources and further readings
- [How to add fonts to create-react-app based projects?](https://stackoverflow.com/questions/41676054/how-to-add-fonts-to-create-react-app-based-projects)
- [3 quick ways to add fonts to your React app](https://blog.greenroots.info/3-quick-ways-to-add-fonts-to-your-react-app)
- [Difference between @font-face and @import url?](https://stackoverflow.com/questions/56141957/difference-between-font-face-and-import-url/56142023)
- [Using @font-face](https://css-tricks.com/snippets/css/using-font-face/)
- [Best way to add a custom font to my site?](https://webmasters.stackexchange.com/questions/108916/best-way-to-add-a-custom-font-to-my-site)
- [Best practices for fonts](https://web.dev/font-best-practices/)