If you are a newbie like me, I have two questions for you:
When you first learnt HTML, CSS and JavaScript:
- How did you use
Roboto
from Google fonts in your page? Probably via a<link>
tag inindex.html
, or an@import
statement in the CSS style sheet? - 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 inindex.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:
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
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 is no longer necessary.
To quote from create-react-app guide on "adding a style sheet":
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
in the following example.
You are probably familiar with the two choices from Google Font,
- via a
<link>
tag inindex.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.
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, 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 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 from Google Developers:
Google Fonts provides the option to load fonts via
<link>
tags or an@import
statement. The<link>
code snippet includes apreconnect
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.