> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/web/get-started/faq/self-serve-substitute-fonts.md).

# Self-Serve Substitute Fonts in WebViewer

World's #1 PDF SDK Library for Web, Mobile, Server, Desktop

WebViewer will automatically use substitute fonts hosted on a web server when a font is not embedded in the document. The fallback fonts are hosted by Apryse by default but if this is a concern, you can host the fonts on your own servers. You can also customize the font package to better suit your needs.

To get started, please download the [self serve font package](https://pdftron.s3.amazonaws.com/downloads/SelfServeWebFontsV2.zip).

## Serving the default font package from your server

Simply expand the webfont archive into a location that is accessible via URL, and set the custom font URL within your WebViewer config file using

{% tabs %}
{% tab title="JavaScript (SDK v8.0+)" %}
{% code lineNumbers="true" %}

```js
Core.setCustomFontURL("https://www.somealternateurl.com/chosensubpath/");
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript (SDK v6.0+)" %}
{% code lineNumbers="true" %}

```js
CoreControls.setCustomFontURL("https://www.somealternateurl.com/chosensubpath/");
```

{% endcode %}
{% endtab %}
{% endtabs %}

See [this guide](/web/advanced/config-files.md) for more details about config files.

WebViewer will first download `fonts.json` (which serves as a catalogue of available fonts and matching rules), then it will choose the approriate fonts to download as needed.

## Customizing the font set

It is possible to add new fonts to the webfont backend, and it's possible to customize the matching behaviour. However it is very important that `fonts.json` closely matches the actual list of available fonts -- if the character set coverage in `fonts.json` is incorrect, or if it points to font files that do not exist, the stability of WebViewer could be compromised. For this reason, we've made a command-line tool that can be used to safely modify the font set.

Please download the webfont creation tool for [Linux](https://pdftron.s3.amazonaws.com/downloads/linux/WebFontCreator), [Mac](https://pdftron.s3.amazonaws.com/downloads/mac/WebFontCreator), or [Windows](https://pdftron.s3.amazonaws.com/downloads/win/WebFontCreator.exe) (only 64 bit versions of these tools are available at this time).

### Example: add Lato and Raleway to the list of supported fonts

First, download some variants of the fonts "Lato" and "Raleway", available [self serve font package](https://pdftron.s3.amazonaws.com/downloads/LatoAndRaleway.zip). Expand this archive into `WebFontSource/` alongside the already expanded webfont archive.

Then run the WebFontCreator CLI tool on your gathered files using the command line `./WebFontCreator --output ./WebFontDest --base ./WebFontSource/fonts.json --fonts ./WebFontSource` This will place a newly generated `fonts.json` file into `./WebFontDest` along with compressed versions of all the fonts. This new `fonts.json` will be the same as `./WebFontDest/fonts.json`, except that it will now contain descriptions and matching rules for Lato and Raleway.

At this point `./WebFontDest` is suitable to serve directly as a custom webfont backend for webviewer (using `setCustomFontURL()`)

{% tabs %}
{% tab title="JavaScript (SDK v8.0+)" %}
{% code lineNumbers="true" %}

```js
Core.setCustomFontURL("...");
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript (SDK v6.0+)" %}
{% code lineNumbers="true" %}

```js
CoreControls.setCustomFontURL("...");
```

{% endcode %}
{% endtab %}
{% endtabs %}

In order for the supported font to be displayed correctly in the `TextEditingPanel` during Content edit mode, certain constraints need to be applied in the font.json file.

Within the fontList, each font entry consists of a list of variants that define various styles for the font. It is crucial to include `Regular, Italic, and Bold` in the variants list, ensuring that the capitalization matches exactly. You have the flexibility to define these styles with or without a hyphen. For example, you could define them as `Lato Regular`, or as `Lato-Regular`.

Failure to adhere to these constraints will result in the font being filtered out by the Webviewer. Please note that in the variants, the key should be left unchanged. You can define the desired values, which will generate corresponding font files with the specified names in the variant after the font.json is compiled by the `WebFontCreate ClI`.

{% tabs %}
{% tab title="Shell" %}
{% code lineNumbers="true" %}

```sh
"fontList": [
   {
      "coverage": ...,
      "ext": ...,
      "family": "Lato",
      "id": "lato1",
      "variants": {
         "500": "Lato-Regular",
         "500I": "Lato Italic",
         "700": "Lato Bold",
      }
   }
]
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Example: use Lato as the primary fallback font

`fonts.json` has two main components: `fontList`, a list of the available fonts on the server, and `matchPatterns`, which tells the office worker how to select the correct font from `fontList`. At this point `fontList` should have an entry for Lato, with the id `lato1`.

The matching algorithm works its way down `matchPatterns` in order, looking for a match for the font family name. A fallback font is something that matches *any* family name. So if the algorithm makes it all the way through the list without finding a match, we want to put the universal match at the bottom, to catch any misses.

We do this using the match type `All`. There are already some `All` matches at the end of the list, and to add `Lato` as the primary fallback, we simply place the object

{% tabs %}
{% tab title="Shell" %}
{% code lineNumbers="true" %}

```sh
{
   "target":"lato1",
   "type":"All"
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

towards the bottom of `matchPatterns`, but before any other match with type `All`


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/web/get-started/faq/self-serve-substitute-fonts.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
