Font Optimization
Self-host any font as WOFF2 with correct preload headers.
List each font file in gio.toml. At startup the server puts every file in .gio/fonts/, serves it from /_gio/fonts/, and injects a <link rel="preload"> per file plus a generated @font-face stylesheet into every page's <head> - visitors never make a request to a third-party font CDN.
Declare fonts in gio.toml
Add one [[fonts]] entry per .woff2 file - one weight and style of one family. Projects created with create-giojs ship their fonts in public/fonts/ and declare them like this:
[[fonts]]
family = "Fraunces"
url = "/public/fonts/fraunces-400-normal.woff2" # a file in public/
[[fonts]]
family = "Fraunces"
url = "/public/fonts/fraunces-400-italic.woff2"
style = "italic" # default "normal"
[[fonts]]
family = "JetBrains Mono"
url = "/public/fonts/jetbrains-mono-400-normal.woff2"
[[fonts]]
family = "JetBrains Mono"
url = "/public/fonts/jetbrains-mono-600-normal.woff2"
weight = 600 # default 400Then use the family in your CSS:
body {
font-family: 'Fraunces', Georgia, serif;
}Local files and remote URLs
A url takes one of two forms:
- A
urlwithout a scheme names a file inpublic/, written the way it is served:/public/fonts/a.woff2and/fonts/a.woff2are bothpublic/fonts/a.woff2. It is read at every start, so the server needs no network, and served under a name with a hash of its content (fraunces-400-normal-1a2b3c4d.woff2): an edited file gets a new URL on restart, so browsers and CDNs that cached the old one pick it up. A missing file stops the server at startup with its path. - A remote URL such as
https://cdn.example.com/inter-latin-400.woff2- downloaded on the first start and reused after that (an existing file is never fetched again). The download happens before the server starts listening, and a failed download or an error status stops startup rather than saving an error page as the font. A fresh container or a new standalone folder downloads again on its first start, so the host needs outbound HTTPS to that URL then - or keep.gio/fonts/on a persistent volume. A file inpublic/avoids both.
GIO_FONTS_DIR points the font folder somewhere other than .gio/fonts/.
<link rel="preload"> per font (except entries with preload = false, for fonts only used below the fold) and the generated /_gio/fonts/fonts.css with its @font-face rules (font-display: swap). The .woff2 files are cached as immutable (a URL never gets new content); fonts.css is rewritten from gio.toml on every start under the same URL, so it is served with Cache-Control: public, max-age=0, must-revalidate and revalidated via Last-Modified.Static export
[[fonts]] is applied by the Rust server, so gio export does not see it. A static site declares its fonts with @font-face in an imported stylesheet instead; the CSS pipeline bundles the files its url()s name with hashed names:
@font-face {
font-family: 'Fraunces';
src: url('../public/fonts/fraunces-400-normal.woff2') format('woff2');
font-weight: 400;
font-display: swap;
}