Use Case for loading fonts using SharePoint Brand Center API
In my last blog post, I showed how it would be possible to use any font that you have uploaded to the brand center. Although the API is unofficial, I’ll show you how to make practical use of it in a web part.
You could apply the same methods used for styling with a custom CDN, but for this let’s leverage the built-in SharePoint CDN and Brand Centers capabilities.
For that, we need to go back to the year 2019. I demoed during the PnP Summer camp, how to make beautiful quotes for SharePoint. In this demo, I used custom fonts and background images to fill the test instead of just using a color for the text.
When I saw Microsoft’s demos, I was immediately reminded of a blog post from 2019.

While the text ended up there, it was because it was exported from Figma or a similar tool in this manner. It was a great opportunity to use it as a showcase to load a custom font from the brand center. Not that the stage is set, let’s get right into it.
Basic Setup
To achieve this effect, we need to load a bolder font that is likely not included in the base SharePoint setup. The font was uploaded via the Brand Center to the font library and replicated to the CDN.
The first thing I did in the web part was to create some variables.
// Font Base URL to Brand Center
private _fontBaseUrl: string | null = null;
// Font Base URL to Brand Centers CDN endpoint
private _fontBaseUrlCdn: string | null = null;
// Name of the file to load
static readonly FONTFILENAME: string = 'Gotham-Ultra.otf';
These properties should contain all the information to load my fonts. The static FONTFILENAME includes the actual file we need to load; there is always the slight chance that it does not exist, but that won’t be a deal breaker, which I explain later.
To prevent the result from being spoiled, the web part will load fine, even if something unforeseen happens to the Microsoft Brand Center in the future.
For performance optimisation, I created this small method that allows me to use local storage for the endpoints to my font files.
private async _fetchCdnFontBaseUrl(): Promise<string> {
const response = await fetch(`${this.context.pageContext.web.absoluteUrl}/_api/SP.BrandCenter/Configuration?src=ResponsiveTypographyWebPart`, {
headers: {
'Accept': 'application/json;odata=nometadata'
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.debug('Brand Center Configuration:', data);
// CDN Base Endpoint
const cdnBaseUrl = this.context.pageContext.legacyPageContext.publicCdnBaseUrl;
// brandCenterConfig is the retrieved brand center config
const fontBasePath = data.BrandFontLibraryUrl.DecodedUrl.replace(
`${window.location.protocol}//`, ''
);
const fontCDNUrl = `${cdnBaseUrl}/${fontBasePath}`;
console.debug('Font URL:', fontCDNUrl);
console.debug('Font URL:', data.BrandFontLibraryUrl.DecodedUrl);
// Set local Storage for base URL
localStorage.setItem('n8dFontBaseUrl', data.BrandFontLibraryUrl.DecodedUrl);
// Set local Storage for the CDN URL
localStorage.setItem('n8dFontBaseUrlCDN', fontCDNUrl);
return cdnBaseUrl;
}
It directly returns the cdnBaseUrl as an indicator of the retrieval’s success.
Local storage makes sure that I only have to evaluate the settings once per tenant.
The next step is to update the init function of the web part.
protected async onInit(): Promise<void> {
// Evaluate local storage
this._fontBaseUrl = localStorage.getItem('n8dFontBaseUrl') || null;
this._fontBaseUrlCdn = localStorage.getItem('n8dFontBaseUrlCDN') || null;
// retrieve base urls if not present
if (!this._fontBaseUrlCdn && !this._fontBaseUrl) {
console.debug('CDN Base URL from localStorage:', this._fontBaseUrlCdn);
this._fontBaseUrlCdn = await this._fetchCdnFontBaseUrl();
console.debug('CDN Base URL after fetch:', this._fontBaseUrlCdn);
} else {
console.debug('CDN Base URL from localStorage:', this._fontBaseUrlCdn);
console.debug('DOM Element:', this.domElement);
}
return super.onInit();
}
During the initialization of the web part, we check if the local storage entry for both the CDN and the Brand Center endpoint exists.
If those exist, register CSS customer properties with the font file URL in the web part, so that we can use them in the web part’s CSS. This concludes the base setup from a code perspective for our web part; we can now examine the CSS setup.
CSS to load fonts
Now that we have retrieved the endpoint for the fonts to load, we can examine the CSS required for this.
The first thing we need is the @font-face definition, as shown below.
@font-face {
font-family: 'Gotham';
src: url(<url-to-CDN/>) format("opentype"),
url(<url to brandcenter/>) format("opentype");
font-weight: 950;
font-style: normal;
font-display: swap;
}
The font-family defines the name of the font. We could even name this “A really Bold Font” when we use the same name later in the CSS. The font I chose is Gotham.
src defines the source from which the browser should download the font. We need to add the URLs that we have evaluated to our web part.
When the first URL succeeds, it will be loaded directly from the CDN. If the font is not present on the CDN, try loading it from the SharePoint Brand Center instead.
Loading it from the Brand Center will give you the correct font, but it will be slower because it needs to download the font from the SharePoint database.
font-weight defines the weight of the ULTRA font, which is associated with 950. The font-style is normal and not italic.
Finally, the font-swap gives a hint to the browser. Please don’t wait until the font is downloaded; instead, swap it to the correct font once it has been downloaded. This is crucial because it prevents layout shifts, and the loading of the font will make the experience smoother. You might see the swap only on the first load anyway.
Add Font CSS to the web Part
Since we cannot use CSS custom properties for those URLs, we need to create the @font-face definition directly in our web part code.
private _renderFontDefinition(): void {
const styleBlock = `
<style>
@font-face {
font-family: Gotham;
src: url(${this._fontBaseUrlCdn + '/' + ResponsiveTypographyWebPart.FONTFILENAME}) format("opentype"),
url(${this._fontBaseUrl + '/' + ResponsiveTypographyWebPart.FONTFILENAME}) format("opentype");
font-weight: 950;
font-style: normal;
font-display: swap;
}
</style>
`;
this.domElement.innerHTML += styleBlock;
}
We have now referenced the correct URLs for our web part. The content of this CSS is small; even though you might have it multiple times on the page, the font will be downloaded only once, nevertheless.
Styling the font and clipping it.
I don’t delve too deeply into the details of this, but I will highlight the key aspects.
.responsiveTypography {
background-clip: text;
background-image: url("https://<url to background-image></url>/sites/Demo/SiteAssets/forest.jpg");
color: white;
color: transparent;
font-family: Gotham, sans-serif;
font-weight: 950;
font-size: 10rem;
font-size: clamp(2rem, 10vw, 10rem);
font-weight: 950;
text-align: left;
white-space: nowrap;
line-height: 0.75;
padding: 1rem;
padding-block: clamp(1rem, 5vw, 5rem);
}
First thing I define a background for the container. Background-clip with the value of ‘text’ determines that the background should be only applied to the text and not the background of the container.
The color is set to transparent, allowing you to see both the background and the font. Similar to a clipping mask.
The font-family is set to Gotham and falls back to the sans-serif font. Any serif font will also be used during the loading of the web part. If this is not set, you may initially see the text in “Times New Roman”—the default font of SharePoint and the web browser.
The result should now look like this:

Similar to what I showed in the first picture from the Microsoft marketing materials, but it is not an image; you can make it editable text.
What if the font doesn’t load
Let’s assume something changes in the future, and the font cannot be loaded. There could be multiple reasons for that. The font will still be displayed correctly.

The font will be rendered now as Segoe UI instead of our custom one. The content will still be visible, and nothing will break.
In addition, you could add the CSS custom property for --fontFamilyBase to the font family definition.
.responsiveTypography {
// ...
font-family: Gotham, var(--fontFamilyBase);
font-weight: 950;
// ...
}
It may even revert to fonts that are installed on your client’s system.
Fazit
As mentioned in the first blog post, the brand center API is still unofficial, although I hope that it will be added to the official documentation.
It is a great example of the crucial role that typography plays in modern intranet design, and it can lead to great effects and eye-catching solutions.
There are also accessibility considerations, and this way is better than simply placing an image as the header in SharePoint.