Use variable font files to customize your font
Streamlit comes with Source Sans as the default font, but you can configure your app to use another font. This tutorial uses variable font files and is a walkthrough of Example 1 from Customize fonts in your Streamlit app. For an example that uses static font files, see Use static font files to customize your font.
Prerequisites
-
This tutorial requires the following version of Streamlit:
streamlit>=1.45.0
-
You should have a clean working directory called
your-repository
. -
You should have a basic understanding of static file serving.
-
You should have a basic understanding of working with font files in web development. Otherwise, start by reading Customize fonts in your Streamlit app up to Example 1.
Summary
The following example uses static file serving to host Google's Noto Sans and Noto Sans Mono fonts and configures the app to use them. Both of these fonts are defined with variable font files that include a parameterized weight. However, because font style is not parameterized, Noto Sans requires two files to define the normal and italic styles separately. Noto Sans Mono does not include a separate file for its italic style. Per CSS rules, because no italic style is explicitly provided, it will be simulated by skewing the normal-style font.
Here's a look at what you'll build:
Directory structure:
your_repository/
βββ .streamlit/
β βββ config.toml
βββ static/
β βββ NotoSans-Italic-VariableFont_wdth,wght.ttf
β βββ NotoSans-VariableFont_wdth,wght.ttf
β βββ NotoSansMono-VariableFont_wdth,wght.ttf
βββ streamlit_app.py
.streamlit/config.toml
:
[server]
enableStaticServing = true
[[theme.fontFaces]]
family="noto-sans"
url="app/static/NotoSans-Italic-VariableFont_wdth,wght.ttf"
style="italic"
[[theme.fontFaces]]
family="noto-sans"
url="app/static/NotoSans-VariableFont_wdth,wght.ttf"
style="normal"
[[theme.fontFaces]]
family="noto-mono"
url="app/static/NotoSansMono-VariableFont_wdth,wght.ttf"
[theme]
font="noto-sans"
codeFont="noto-mono"
streamlit_app.py
:
import streamlit as st
st.write("Normal efg")
st.write("_Italic efg_")
st.write("*Bold efg*")
st.write("***Bold-italic efg***")
st.write("`Code efg`")
Download and save your font files
-
Go to Google fonts.
-
Search for or follow the link to Noto Sans, and select "Get font."
-
Search for or follow the link to Noto Sans Mono, and select "Get font."
-
To download your font files, in the upper-right corner, select the shopping bag (shopping_bag), and then select "download Download all."
-
In your downloads directory, unzip the downloaded file.
-
From the unzipped files, copy and save the TTF font files into a
static/
directory inyour_repository/
.Copy the following files:
Noto_Sans,Noto_Sans_Mono/ βββ Noto_Sans_Mono/ β βββ NotoSansMono-VariableFont_wdth,wght.ttf βββ Noto_Sans/ βββ NotoSans-Italic-VariableFont_wdth,wght.ttf βββ NotoSans-VariableFont_wdth,wght.ttf
Save those files in your repository:
your_repository/ βββ static/ βββ NotoSans-Italic-VariableFont_wdth,wght.ttf βββ NotoSans-VariableFont_wdth,wght.ttf βββ NotoSansMono-VariableFont_wdth,wght.ttf
In this example, the font files are
NotoSans-Italic-VariableFont_wdth,wght.ttf
andNotoSansMono-VariableFont_wdth,wght.ttf
for Noto Sans italic and normal font, respectively.NotoSansMono-VariableFont_wdth,wght.ttf
is the file for Noto Sans Mono.
Create your app configuration
-
In
your_repository/
, create a.streamlit/config.toml
file:your_repository/ βββ .streamlit/ β βββ config.toml βββ static/ βββ NotoSans-Italic-VariableFont_wdth,wght.ttf βββ NotoSans-VariableFont_wdth,wght.ttf βββ NotoSansMono-VariableFont_wdth,wght.ttf
-
To enable static file serving, in
.streamlit/config.toml
, add the following text:[server] enableStaticServing = true
This makes the files in your
static/
directory publicly available through your app's URL at the relative pathapp/static/{filename}
. -
To define your alternative fonts, in
.streamlit/config.toml
, add the following text:[[theme.fontFaces]] family="noto-sans" url="app/static/NotoSans-Italic-VariableFont_wdth,wght.ttf" style="italic" [[theme.fontFaces]] family="noto-sans" url="app/static/NotoSans-VariableFont_wdth,wght.ttf" style="normal" [[theme.fontFaces]] family="noto-mono" url="app/static/NotoSansMono-VariableFont_wdth,wght.ttf"
The
[[theme.fontFaces]]
table can be repeated to use multiple files to define a single font or to define multiple fonts. In this example, the definitions make"noto-sans"
and"noto-mono"
available to other font configuration options.star Tip
For convenience, avoid spaces in your font family names. When you declare the default font, you can also declare fallback fonts. If you avoid spaces in your font family names, you don't need inner quotes.
-
To set your alternative fonts as the default font for your app, in
.streamlit/config.toml
, add the following text:[theme] font="noto-sans" codeFont="noto-mono"
This sets Noto Sans as the default for all text in your app except inline code and code blocks, which will be Noto Sans Mono instead.
Build the example
To verify that your font is loaded correctly, create a simple app.
Initialize your app
-
In your_repository, create a file named
streamlit_app.py
. -
In a terminal, change directories to your_repository, and start your app:
streamlit run app.py
Your app will be blank because you still need to add code.
-
In
streamlit_app.py
, write the following:import streamlit as st
-
Save your
streamlit_app.py
file, and view your running app. -
In your app, select "Always rerun", or press the "A" key.
Your preview will be blank but will automatically update as you save changes to
streamlit_app.py
. -
Return to your code.
Display some text in your app
-
Create a
streamlit_app.py
file in your working directory. -
In
streamlit_app.py
, add the following text:import streamlit as st st.write("Normal efg") st.write("_Italic efg_") st.write("*Bold efg*") st.write("***Bold-italic efg***") st.write("`Code efg`")
The example includes "efg" in each line to better show the typographical differences when you run your app. The italic "f" descends below baseline, but the normal "f" doesn't. The italic "e" has a rounded front, but the normal "e" has a sharp corner.
-
Save your
streamlit_app.py
file, and view your running app.
Still have questions?
Our forums are full of helpful information and Streamlit experts.