There are multiple ways to add custom web fonts to SPFx projects. The best options are to load fonts from a CDN, your own, a commercial provider or via fonts.google.com.
Sometimes this is not enough cause our customer has their custom fonts or my want to use a custom font for a single web part only. Let me show the steps to get this accomplished in the SharePoint Framework.
Prepare the solution
For this demo webpart, I downloaded the font ‘Permanent Marker‘ from the Google Fonts. The right location for this font file is at first somewhere in the src folder. I chose to create a fonts folder directly in the root of src. This way, the font could be consumed by multiple web part in the solution.
Two-stage build chain
The SharePoint Framework build chain happens in three steps. First, the code and assets in the ‘src’ folder will be transpiled to the ‘lib’ folder. From there webpack pick up the transpiled code and assets and bundle it with webpack.
Move font from ‘src’ to ‘lib’
When the font files only exist in the ‘src’ folder, we cannot make use in our web part of it. The first step is that those files also need to exist in the ‘lib’ folder.
One option is to copy the files manually. Other developers run into issues that cause the ‘lib’ folder is just an intermediate folder that won’t get checked in to your code repository.
A best and only stable approach is to let SPFx copy the files over to the ‘lib’ directory for us. Fonts files are real static assets in the overall solution. For static files, we need to create a ‘copy-static-assets.json’ in the config folder with the following content.
{
"includeExtensions": [
"ttf",
"woff",
"eot",
"woff2"
// optional use , "svg"
]
}
In the ‘includedExtension’ section contains all file extension for know font files. SPFx detects such a file and will copy it to the ‘lib’ folder automatically.
Preparing Webpack
The next step is to make webpack aware of our custom font files because it cannot handle files other than JavaScript by default. For custom font files, we need a simple file loader is enough. To install the webpack file loader add the following dependency.
npm install file-loader --save-dev
The next step is to make the SPFx build chain aware that we want to use and additional loader. For this edit the gulp file in the root of your project.
'use strict';
const build = require('@microsoft/sp-build-web');
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
// Font loader configuration for webfonts
const fontLoaderConfig = {
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}]
};
// Merge custom loader to web pack configuration
build.configureWebpack.mergeConfig({
additionalConfiguration: (generatedConfiguration) => {
generatedConfiguration.module.rules.push(fontLoaderConfig);
return generatedConfiguration;
}
});
build.initialize(require('gulp'));
The fontLoaderConfig-variable define which files extensions we like to handle with the file-loader. In our case, only font files. In the ‘build.configureWebpart’ the section we merge then the configuration to the already SPFx predefined webpack configuration. We finished now the core setup to handle custom web fonts.
Make use of web fonts in the webpart
To use the fonts I placed already the font files in the src folder directly but now if we reference it directly from our web part we run into an error. All data in the ‘src’ folder that do not contain any code get ignored by the build chain.
To change that I created an additional folder named styles. This folder contains all global style definitions for all web parts in the solution.
In this folder then I created a file name ‘_fonts.scss’. Files in SASS with an underscore up front are also known as partial files. Partial files only get compiled when referenced by another SASS file without the underscore prefix.
@font-face {
font-family: 'Permanent Marker';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local('Permanent Marker Regular'),
local('PermanentMarker-Regular'),
url(../fonts/PermanetMarker-Regular.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
In this file, we add the @font-face definition for our web font. The critical part here is the ‘src’ section and more specific the ‘url’. The URL needs to point to our font file in the fonts folder. Your @font-face definition might look different depending on the font you use.
Add @font-face to web part
Now up to the webpart code. In the style sheet of the webpart, the use of this font definition, we need to ‘@import’ the partial file from ‘src/styles’.
@import '~office-ui-fabric-react/dist/sass/References.scss';
// imports @font-face definiton
@import '../../../styles/font';
.permanentMarker {
// Make use of our custom font
font-family: 'Permanent Marker';
font-size: 2em;
}
The CSS of this demo webpart is just text with a single surrounding style sheet class, and we can assign the name of the web font to the font-family property.
That is all to get any custom font running.
The build and file location
Finally, let’s take a look at the file cycle of our font file.
First, we placed it in the ‘src’ folder.
Via the ‘copy-static-assets.json’ file it will automatically move to the ‘lib’ folder.
The webpack file-loader pick up the font file and transfer it to the ‘dist’ folder.
Now when we bundle and package the solution, this font file also is part of our ‘.sppkg’ file.
Now we are ready to load any custom web font on any SharePoint page.
Personally, I think the best way still is to host web fonts from a CDN, a public or private one, but sometimes you have a specific need to add just a single font to your design. This way you can accomplish this without a problem.
Hey, I liked your post, but following step by step i still got a error.
When I bundle my solution this message is shown:
Error – [webpack] ‘dist’:
./lib/webparts/customFontUsage/components/CustomFontUsage.module.css (./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src??postcss!./lib/webparts/customFontUsage/components/CustomFontUsage.module.css)
Module not found: Error: Can’t resolve ‘../fonts/sansr.woff’ in ‘C:/Repos/spfx/SpfxDemos/custom-font-usage/lib/webparts/customFontUsage/components’
resolve ‘../fonts/sansr.woff’ in ‘C:/Repos/spfx/SpfxDemos/custom-font-usage/lib/webparts/customFontUsage/components’ using description file: C:/Repos/spfx/SpfxDemos/custom-font-usage/package.json (relative path: ./lib/webparts/customFontUsage/components)
Field ‘browser’ doesn’t contain a valid alias configuration using description file: C:/Repos/spfx/SpfxDemos/custom-font-usage/package.json (relative path: ./lib/webparts/customFontUsage/fonts/sansr.woff)no extension
And when I manually put the font file in the folder:
Error – [copy-assets] Webpack-produced asset “fonts/ctgsansr.woff” does not appear to have a checksum in its filename, meaning that it
is not safe to deploy to the CDN.
I followed this working fine on workbranch but when trying gulp bundle –ship has error like below
Error – [copy-assets] Webpack-produced asset “fonts/Apercu-Regular.eot” does not appear to have a checksum in its filename, meaning that it is not safe to
deploy to the CDN.
please help what i have to do?