ArcGIS Map SDK for JS: Preparing and Hosting Local .pbf Font Assets, feat. MapBox API & Vite
In this article, I will be demonstrating on how to prepare a .pbf
font asset by converting from a .ttf
file format and host the font asset locally in a Vite
project.
Problem Statement
Let’s say you want to create a graphic
with TextSymbol
of Times New Roman
family:
const textSymbol = new TextSymbol({
text: "Hello World",
color: "black",
font: {
size: 12,
family: "Times New Roman",
},
});
const textGraphic = new Graphic({
geometry: {
type: "point",
longitude: -118.805,
latitude: 34.027,
},
symbol: textSymbol,
});
view.graphics.add(textGraphic);
You will be immediately met with the Couldn't find font xxxxxx. Falling back to Arial Unicode MS Regular
error:
This is because Times New Roman
font is currently not hosted by ArcGIS (check out here for a list of fonts currently hosted by ArcGIS).
Solution
The solution is to host the font assets locally, by setting esriConfig.fontsUrl
, for example:
esriConfig.fontsUrl = "./assets/fonts";
The output error should now resemble the following screenshot:
Note that the URL is now calling localhost
instead of static.arcgis.com
.
Though this has been documented officially, there is a little to no documentation from ESRI nor the Internet on how to obtain a .pbf
file or convert a more popular font format such as .ttf
or woff2
to .pbf
format.
MapBox
Meet MapBox Fonts API, it allows users to add custom fonts in the format of .ttf
or .otf
, and later retrieve them in the format .pbf
.
To start using MapBox Fonts API, create an account here. With the account created, login to MapBox and create an access token here, which is necessary for their Fonts API.
When creating access token, ensure the FONTS:LIST
and FONTS:WRITE
scope are checked under Secret scopes section:
With the access token created, you can now add new custom font to MapBox via its add-a-font Fonts API, for example:
curl -X POST "https://api.mapbox.com/fonts/v1/{username}/?access_token=YOUR_MAPBOX_ACCESS_TOKEN" \
--data-binary @Times-New-Roman-Regular.ttf
Upon successful request, the API will reflect the font family name and style as a response, for example:
{
"family_name": "Times New Roman",
"style_name": "Regular",
"owner": "{username}",
"visibility": "private"
}
With the font added to MapBox, we can now retrieve the .pbf
file of the font via its `retrieve-font-glyph-ranges` Fonts API, for example:
curl "https://api.mapbox.com/fonts/v1/{username}/times%20new%20roman%20regular/0-255.pbf?access_token=YOUR_MAPBOX_ACCESS_TOKEN"
Save the API response, which is in byte, to a file named 0-255.pbf
.
Vite
Now that we have the file available, we can place the 0-255.pbf
file in the correct location. In my case, it is a Vite
project. In the project root public
folder, create the following folder structure: /assets/fonts
as the base fonts URL as configured earlier.
Next create a font folder with the font family name and style as the folder name, for example: /times-new-roman-regular
.
Finally, place the 0-255.pbf
file in this folder. The public
folder should resemble the following:
./public/assets/fonts/times-new-roman-regular/0-255.pbf
With everything done correctly, ArcGIS JS API should be able to locate the font assets and render the TextSymbol
correctly. This can also be observed by inspecting the browser network:
Now you have successfully prepared a .pbf
font asset by converting from a more common .ttf
format using MapBox API, and hosted it locally with Vite
.