To use custom fonts offline in an HTML APK, download the WOFF2 files (Google Fonts are open-licensed), place them in a fonts/ folder, declare them with @font-face using relative URLs and font-display: swap, and remove the Google Fonts <link>. Use a variable font or only the weights you need to keep the APK small.
Key takeaways
- WOFF2 is all you need — every WebView supports it.
- A variable font replaces several static weight files.
- Font URLs in CSS are relative to the CSS file, not the page.
system-uineeds no files at all and looks native.
1. Get the files
Google Fonts' family pages have a "Get font" → download button that gives TTF files; WOFF2 is smaller. Options:
- Open the Google Fonts CSS URL from your
<link>in a browser — it listssrc: url(https://fonts.gstatic.com/…woff2)for each subset. Download the Latin file(s). - Use the npm packages from Fontsource (
@fontsource-variable/inter), which include WOFF2 files and ready CSS. - Convert TTF to WOFF2 with Google's
woff2_compresstool.
2. Declare them
/* css/fonts.css — paths are relative to THIS file */
@font-face {
font-family: 'Inter';
src: url('../fonts/inter-latin-variable.woff2') format('woff2');
font-weight: 100 900; /* variable font: one file, every weight */
font-style: normal;
font-display: swap;
}
body { font-family: 'Inter', system-ui, sans-serif; }Then delete the fonts.googleapis.com and fonts.gstatic.com preconnect and stylesheet tags.
3. Keep it small
| Choice | Typical size |
|---|---|
| One variable font, Latin subset (WOFF2) | 40–110 KB |
| Four static weights, Latin subset | 4 × 20–30 KB |
| Full character set incl. Cyrillic, Greek, Vietnamese | 2–4× larger |
| Icon font (Font Awesome full) | ~150–400 KB — consider inline SVG icons instead |
Only bundle the subsets for languages your app shows. If you need other scripts (Arabic, Devanagari, CJK), use the matching Noto font — and note CJK fonts are several megabytes, so system-ui is often the better choice.
4. Avoid a flash of fallback text
<link rel="preload" href="fonts/inter-latin-variable.woff2" as="font" type="font/woff2" crossorigin>Bundled fonts load in milliseconds, so the swap is rarely visible; preloading the one main font removes it entirely.
5. Or skip custom fonts
font-family: system-ui, sans-serif renders in Roboto on most Android phones (or the manufacturer's font, such as One UI Sans on Samsung). It is free, instant and matches the rest of the phone.
Licences
Google Fonts are under the SIL Open Font License or Apache 2.0, which allow embedding in apps. Commercial fonts often need a separate app or "embedding" licence — check before you bundle one.
Frequently asked questions
Why does my font look different in the APK?
The font is probably loaded from Google Fonts or another server and the app is falling back to a default. Bundle the WOFF2 file and reference it with a relative @font-face URL.
Can I bundle icon fonts like Font Awesome?
Yes — copy the webfonts folder next to its CSS. For a handful of icons, inline SVG is much smaller.