How to use custom fonts in Vue or React projects

When developing a front-end project, it’s common to encounter a UI colleague who wants to use a cool font in the project. So how do you use custom fonts in your projects?

In fact, the implementation is not complex, you can borrow CSS3 @font-face to achieve.

This article focuses on how the WebPack project can properly package introduced custom fonts.

What does @font-face do

To sum up: with this rule, the user can give an imported font package a name, specify where to find it (specify where the font package is stored), and then use it as if it were a generic font.

Concrete implementation steps

For example, the current requirement is to use the Klavikamedium-italic font in a project.

The following three steps are required.

1. Place the font package in the project directory

Put this in the tool/fonts folder in the root directory.

2. Define it in the index. CSS file

@font-face {
  font-family: 'myFont';
  src: url(tool/fonts/KlavikaMedium-Italic.otf);
}
Copy the code

3. Use custom fonts

Create a new index.vue file and introduce styles:

Import './index.css' <template> <h1> Use custom fonts </h1> <style> h1 {font-family: 'myFont'} </style> </template>Copy the code

The effect is as follows:

How does webPack project properly package custom fonts

1. Packing is wrong

Now that I have implemented the effect in the local development environment, I use webpack to go live, but I find that webPack has an error during the packaging process:

2. Why is there an error when packing

We specify the path of the font package when we define our custom fonts using urls. Since WebPack cannot handle urls in CSS by default, we get an error here.

3. Resolve the error

3.1 know file – loader

Then you need to use loader to show their skills, to solve this problem need to use file-loader, it mainly does two things:

  • Modify the storage path of packaged pictures and font packages according to the configuration;
  • Then modify the path we reference according to the configuration so that it corresponds to import.

3.2 installation file – loader

yarn add file-loader
Copy the code

3.3 configuration file – loader

In webpack.config.js, configure file-loader:

module.exports = {
  module: {
    rules: [{// Hit the font package
        test: /\.(woff2? |eot|ttf|otf)(\? . *)? $/.// Only hits files in the specified directory to speed up Webpack search
        include: [paths.toolSrc],
        // Exclude files in node_modules
        exclude: /(node_modules)/,
        loader: 'file-loader',},]}}Copy the code

Execute the package command again without error.

4. Why don’t custom fonts work

Then I redeployed the packaged dist directory to the server and visited the page, but found that it did not take effect because I could not find the font:

As can be seen from the figure, the path of the HTTP request font package is:Root directory (packaging of static file index. The HTML directory) of CSS / 620 db1b997cd78cd373003282ee4453f otf.

4.1 Reasons why fonts do not take effect

Take a look at the dist directory structure generated by the package command:

├ ─ ─ 620 db1b997cd78cd373003282ee4453f otf ├ ─ ─ CSS │ ├ ─ ─ backend. 66 a35. CSS │ └ ─ ─ backend. 66 a35. CSS. The map ├ ─ ─ the favicon. Ico ├ ─ ─ Images │ ├── Data-basetexture. 6F50D.jpg │ ├─ data-heighttexture Index.html ├─ js ├─ back.66a35.jsCopy the code

It turns out that the font package is at the same level as index.html. So it’s clear why fonts don’t work:

  • Because the HTTP request font package path is the same as the actual store path, the result is 404;
  • The actual path to the font package could not be found, so the font used did not take effect.

4.2 Solution of ineffective fonts

You can solve this problem by changing the actual storage path of the font package. In webpack.config.js, you can use the options parameter to set more configuration items for file-loader:

module.exports = {
  module: {
    rules: [{// Hit the font package
        test: /\.(woff2? |eot|ttf|otf)(\? . *)? $/.// Only hits files in the specified directory to speed up Webpack search
        include: [paths.toolSrc],
        // Exclude files in node_modules
        exclude: /(node_modules)/,
        loader: 'file-loader'.// Added configuration parameters: file-loader configuration items
        options: {
          limit: 10000.// Define the path to the final exported file after the packaging is complete
          outputPath: 'css/fonts/'.// Final name of the file
          name: '[name].[hash:7].[ext]'}},]}}Copy the code

Packaged again, the resulting dist directory structure is as follows:

├ ─ ─ CSS │ ├ ─ ─ backend. 66 a35. CSS │ ├ ─ ─ backend. 66 a35. CSS. The map │ └ ─ ─ fonts │ └ ─ ─ KlavikaMedium - Italic. 620 db1b otf ├ ─ ─ Favicon.ico ├── images │ ├─ Data-basetexture. C2963.jpg │ ├─ data-heighttexture. 6F50D.jpg │ ├─ Data-heighttexture ├─ index.html ├─ js ├─ back.66a35.jsCopy the code

You can see that the font package is stored under the ** CSS /fonts ** directory as expected when configured.

Redeploy the project and look again:

This time, the HTTP request font package path is the same as the actual path, so the custom font takes effect.

You can see it more clearly through the following combing flow chart:

3. To summarize

Why do you see fonts when you’re developing locally, but not when you’re deployed to the server?

  • Since webpack projects use webpack-dev-server in local development, real-time compiled files are saved in memory, and font packages are referenced using absolute paths, so custom fonts used in local development can take effect.
  • In the dist directory packed with Webpack, the actual storage path of the font package is inconsistent with that of the HTTP request font package, so the font package cannot be found.
  • Use file-loader to solve the webpack error, by using the options parameter to set the font package after the actual storage path, so as to solve the problem.

Follow the wechat official account

Welcome to follow my wechat official account to read more original articles: