How to include Roboto font in webpack build for Material UI?

WebpackWebfontsMaterial UiRoboto

Webpack Problem Overview


For a progressive web app based on Material UI (React) and built with Webpack, how do I properly include Roboto font(s) so that the app does not depend on Google servers and fonts also work offline ?

So, what is a good and simple solution to bundle the right Roboto files with my application?

Webpack Solutions


Solution 1 - Webpack

You can also do it like it is documented in this issue: https://github.com/callemall/material-ui/issues/6256

npm install typeface-roboto --save

Then, in your index.js:

import 'typeface-roboto'

Works with webpack/create-react-app.

Solution 2 - Webpack

This is how my team went about including the Roboto fonts in our Webpack project:

Download the Roboto fonts and make a CSS file in a font-specific folder

  • Create a folder (/fonts).
  • Download all of the Roboto fonts from Font Squirrel. Go to the Webfont Kit tab, then press the Download @font-face Kit button with default settings.
  • Move the fonts into /fonts.
  • Create the CSS file (/fonts/index.css). We got the contents for this file from this tutorial.

index.css:

* {
  font-family: Roboto, sans-serif;  
}

@font-face {
    font-family: 'Roboto';
    src: url('Roboto-Regular-webfont.eot');
    src: url('Roboto-Regular-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-Regular-webfont.woff') format('woff'),
         url('Roboto-Regular-webfont.ttf') format('truetype'),
         url('Roboto-Regular-webfont.svg#RobotoRegular') format('svg');
    font-weight: normal;
    font-style: normal;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-Italic-webfont.eot');
    src: url('Roboto-Italic-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-Italic-webfont.woff') format('woff'),
         url('Roboto-Italic-webfont.ttf') format('truetype'),
         url('Roboto-Italic-webfont.svg#RobotoItalic') format('svg');
    font-weight: normal;
    font-style: italic;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-Bold-webfont.eot');
    src: url('Roboto-Bold-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-Bold-webfont.woff') format('woff'),
         url('Roboto-Bold-webfont.ttf') format('truetype'),
         url('Roboto-Bold-webfont.svg#RobotoBold') format('svg');
    font-weight: bold;
    font-style: normal;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-BoldItalic-webfont.eot');
    src: url('Roboto-BoldItalic-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-BoldItalic-webfont.woff') format('woff'),
         url('Roboto-BoldItalic-webfont.ttf') format('truetype'),
         url('Roboto-BoldItalic-webfont.svg#RobotoBoldItalic') format('svg');
    font-weight: bold;
    font-style: italic;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-Thin-webfont.eot');
    src: url('Roboto-Thin-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-Thin-webfont.woff') format('woff'),
         url('Roboto-Thin-webfont.ttf') format('truetype'),
         url('Roboto-Thin-webfont.svg#RobotoThin') format('svg');
    font-weight: 200;
    font-style: normal;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-ThinItalic-webfont.eot');
    src: url('Roboto-ThinItalic-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-ThinItalic-webfont.woff') format('woff'),
         url('Roboto-ThinItalic-webfont.ttf') format('truetype'),
         url('Roboto-ThinItalic-webfont.svg#RobotoThinItalic') format('svg'); (under the Apache Software License). 
    font-weight: 200;
    font-style: italic;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-Light-webfont.eot');
    src: url('Roboto-Light-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-Light-webfont.woff') format('woff'),
         url('Roboto-Light-webfont.ttf') format('truetype'),
         url('Roboto-Light-webfont.svg#RobotoLight') format('svg');
    font-weight: 100;
    font-style: normal;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-LightItalic-webfont.eot');
    src: url('Roboto-LightItalic-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-LightItalic-webfont.woff') format('woff'),
         url('Roboto-LightItalic-webfont.ttf') format('truetype'),
         url('Roboto-LightItalic-webfont.svg#RobotoLightItalic') format('svg');
    font-weight: 100;
    font-style: italic;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-Medium-webfont.eot');
    src: url('Roboto-Medium-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-Medium-webfont.woff') format('woff'),
         url('Roboto-Medium-webfont.ttf') format('truetype'),
         url('Roboto-Medium-webfont.svg#RobotoMedium') format('svg');
    font-weight: 300;
    font-style: normal;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-MediumItalic-webfont.eot');
    src: url('Roboto-MediumItalic-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-MediumItalic-webfont.woff') format('woff'),
         url('Roboto-MediumItalic-webfont.ttf') format('truetype'),
         url('Roboto-MediumItalic-webfont.svg#RobotoMediumItalic') format('svg');
    font-weight: 300;
    font-style: italic;
}

Use the file-loader webpack module to load in the font files so webpack can recognize them

webpack.conf.js:

loaders: [
  ..., {
    test: /\.(woff|woff2|eot|ttf|svg)$/,
    loader: 'file-loader',
    options: { name: '[name].[ext]', outputPath: 'fonts/', }
  },
  ...
]

Import the font css file in the main entry of the app

App.js:

import './fonts/index.css';

And that's it. Your application's default font should now be Roboto.

EDIT: Which Roboto Fonts does Material-UI actually use?

Part of this question is determining the right Roboto fonts to include in the project since the entirety of the Roboto fonts is almost 5MB.

In the README, the instructions for including Roboto point to: fonts.google.com/?selection.family=Roboto:300,400,500. Here, 300 = Roboto-Light, 400 = Roboto-Regular, and 500 = Roboto-Medium. These correspond to the font weights defined in the typography.js file. While these three font weights account for usage in almost the entirety of the library, there is one reference to Regular-Bold in DateDisplay.js. If you are not using the DatePicker, you should probably be safe to omit that. Italics font styling is not used anywhere in the project aside from the GitHub markdown styling.

This information is accurate at the time of this writing, but it may change in the future.

Solution 3 - Webpack

I tried installing typeface-roboto with npm but it didn't work. Also, using CDN from material ui didn't work. But, installing webfontloader with npm worked. Here is the solution, First,

npm install webfontloader --save

Then, import WebFont from webfontloader in your entry.js file for example App.js or index.js

import WebFont from "webfontloader";
WebFont.load({google: {families: ["Roboto:300,400,500"]}});

Solution 4 - Webpack

If you do use Angular, where import 'typeface-roboto' is not ideal and easy, you may do it a little different than suggested here.

First, install this nice npm package as described by others:

npm install typeface-roboto --save

Then just add this to your angular.json:

"styles": [
  "node_modules/typeface-roboto/index.css",
  [...],
  "src/styles.css"
],

Solution 5 - Webpack

In case the application was started with create-react-app, it doesn't have a [visible] webpack configfile. In this case you can do the following:

  1. create /fonts directory in /public

  2. create /public/fonts/fonts.css, that defines the @font-faces

    @font-face { font-family: 'inglobal'; font-weight: normal; font-style: normal; src: url('./OperatorMono.ttf'); }

  3. Copy font files

  4. add <link rel="stylesheet" href="%PUBLIC_URL%/fonts/fonts.css"> to /public/index.html's

  5. Hurray!

5/b. If, for any reason, it still doesn't work, change the fonts' extensions to .css (also at src: url('./OperatorMono.css') )

Solution 6 - Webpack

For a no-frills Material-UI / Create React App PWA, there is no need for all the variants - all you need is:

yarn add @fontsource/roboto

index.js

import "@fontsource/roboto/latin-400.css";
import "@fontsource/roboto/latin-500.css";

theme.js (optional but makes it looks sharp and clean)

overrides: {
  MuiCssBaseline: {
   html: {
    "-webkit-font-smoothing": "antialiased",
    "-moz-osx-font-smoothing": "grayscale",
    height: "100%",
    width: "100%"
  }
 }
}

Your fonts will be bundled and available online/offline instantly

Demo

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionUdo GView Question on Stackoverflow
Solution 1 - WebpackkimomatView Answer on Stackoverflow
Solution 2 - WebpackDaniel BankView Answer on Stackoverflow
Solution 3 - Webpacksumod badchhapeView Answer on Stackoverflow
Solution 4 - WebpackrugkView Answer on Stackoverflow
Solution 5 - WebpacksandorvasasView Answer on Stackoverflow
Solution 6 - WebpackBrad StewartView Answer on Stackoverflow