Trouble with fonts in Lovable? Learn why files might not load, how to install custom fonts, and best practices for typography.

Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
Fonts fail to load in Lovable for a few predictable reasons: wrong file paths or filenames (case-sensitivity), missing font files in the repo (not committed into public/assets), external font links blocked by HTTPS/CORS/CSP or wrong URL, or runtime build/base-path differences that break relative URLs. These are the most common root causes you should check first.
Paste this into Lovable's chat so it inspects the codebase and lists exact matches and locations:
Please search the repository for these tokens and show file paths and matching lines: "@font-face", "fonts.googleapis.com", "fonts.gstatic.com", ".woff", ".woff2", ".ttf", ".otf", "url(" and "font-family". Return a simple list of matches with file path and line snippet so I can see where fonts are referenced.
Paste into Lovable to modify the entry file so Preview shows font-loading errors in the browser console (this helps identify CORS/mime/missing file errors). Update either src/main.jsx or src/main.tsx (where your app mounts) by inserting the diagnostic block near the top before the app renders:
Please update src/main.jsx (or src/main.tsx if TypeScript) and add this diagnostic code near the top before the React render/mount so Preview will log font loading errors:
// Add font loading diagnostics to surface load errors in Preview
try {
if (typeof document !== 'undefined' && document.fonts) {
document.fonts.ready.then(() => console.log('document.fonts.ready resolved'));
document.fonts.onloadingerror = (evt) => console.error('document.fonts onloadingerror', evt);
document.fonts.forEach(ff => {
// ff is a FontFace
if (ff && ff.family) {
ff.loaded.then(() => console.log('font loaded:', ff.family)).catch(err => console.error('font failed:', ff.family, err));
}
});
}
} catch (e) {
console.error('font diagnostics failed to initialize', e);
}
Paste into Lovable to check actual files and filenames and report missing ones:
Please list files under public/fonts and public/assets/fonts (and src/assets/fonts if present). Show exact filenames (with case) and sizes. Then compare those filenames to the references found earlier and list any mismatches or missing files.
Paste into Lovable to have it open the specific files so you can inspect for protocol, relative path, or CSP issues:
Open these files and copy the @font-face declarations or any <link href="...fonts..."> entries: src/styles/global.css, src/index.css, src/App.css and public/index.html. Also show any <meta http-equiv="Content-Security-Policy"> or server header settings in public/index.html. Highlight lines where external font URLs are used.
If Lovable reports missing font files, paste this to create a directory and add the missing font files (you upload them via Lovable's file editor):
Create directory public/fonts if it doesn't exist. Add/upload these missing files into public/fonts (use the file uploader in the editor): <list the exact filenames reported missing>. After upload, commit the changes so Preview and Publish see them.
Paste into Lovable to check remote URLs and ensure they use HTTPS and to surface console errors from Preview (relies on the diagnostics added earlier):
For each external font URL found earlier (e.g., fonts.googleapis.com), confirm it uses https://. Then open the Preview, reproduce the page load, and copy any console errors related to fonts (CORS, CSP, mixed content, 404, or mime type). Paste the console errors here.
Use this when Lovable confirms the repo is correct but headers or build tooling must change; mark it as outside Lovable:
The fix requires changing server response headers or running a build step locally (terminal required). Please export/sync to GitHub (use Lovable's GitHub sync) so I can update the repo and then run the build/deploy from a terminal. Mark this as "outside Lovable (terminal required)" and list exact files/changes needed.
This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.
To load and use a custom font in Lovable, add the font file(s) to your project (upload to the Files panel or sync via GitHub if needed), create @font-face rules in a global CSS file, import that CSS from your app entry (src/main.tsx, src/index.tsx, or src/App.tsx), then apply the font via a CSS variable or direct font-family. Use Lovable’s editor to create files, Preview to check, and Publish or GitHub sync when ready.
Use this prompt in Lovable chat to make the changes. It tells Lovable exactly what files to create/update and where to upload the font binaries.
// Please make these project edits and file additions in the Lovable editor.
// 1) Create a folder assets/fonts/ and I will upload font files there (e.g., MyCustom-Regular.woff2 and MyCustom-Bold.woff2).
// 2) Create file src/styles/fonts.css with the contents below.
// 3) Update the app entry file (src/main.tsx or src/index.tsx — pick the one that exists) to add: import './styles/fonts.css';
// 4) Update src/index.css (or src/global.css if present) to use the CSS variable --font-sans shown below so the whole app uses the font.
//// file: src/styles/fonts.css
@font-face {
// Local regular font
font-family: 'MyCustom';
src: url('/assets/fonts/MyCustom-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
// Local bold font
font-family: 'MyCustom';
src: url('/assets/fonts/MyCustom-Bold.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
:root {
--font-sans: 'MyCustom', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial;
}
//// If you have src/index.css, add or replace the body rule:
body {
// Use the custom font for the whole app
font-family: var(--font-sans);
}
After pasting the prompt above, upload your .woff/.woff2 files into assets/fonts/ using Lovable’s Files panel or drag-and-drop. Then Preview the app and verify text uses the new font. If files are large or you prefer version control, use GitHub sync to add the font files in the repo (outside Lovable).
If you prefer linking a hosted font, use this Lovable prompt to add a link tag or an @import and then apply the font globally.
// Please update files as follows:
// 1) Edit public/index.html (or src/index.html if your project has it) and add the <link> to the hosted font in the <head>.
// 2) Create or update src/styles/fonts.css to set the CSS variable and body font-family, then ensure the file is imported in src/main.tsx or src/index.tsx.
//// Example head addition in public/index.html (insert inside <head>):
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
//// file: src/styles/fonts.css
:root {
--font-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial;
}
body {
// Use the hosted font for the whole app
font-family: var(--font-sans);
}
Then Preview to confirm. If your app uses Tailwind, update tailwind.config.js to extend fontFamily with the same variable or name and restart via GitHub sync if restart is needed outside Lovable.
Use a centralized, token-driven typographic system (CSS variables or JS tokens), prefer system font stacks with clear fallbacks, keep a consistent scale and responsive line-heights, prioritize performance (avoid blocking fonts), and use Lovable’s Preview/Publish plus GitHub sync when you must add binary font assets. Centralize changes so future edits happen in one place and test across devices in Lovable’s Preview.
Create a single source-of-truth for sizes, weights, line-heights and font-family fallbacks. This makes visual changes safe and easy.
// Lovable prompt: create src/styles/typography.css with a centralized
// token set and base typographic rules. Import this file in the app entry.
Please create file src/styles/typography.css with this content:
:root {
--font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Segoe UI Emoji", "Apple Color Emoji", "Noto Color Emoji", sans-serif;
--type-xxs: 0.75rem;
--type-xs: 0.875rem;
--type-sm: 0.95rem;
--type-base: 1rem;
--type-lg: 1.125rem;
--type-xl: 1.25rem;
--type-2xl: 1.5rem;
--leading-tight: 1.1;
--leading-normal: 1.5;
--weight-regular: 400;
--weight-medium: 500;
--weight-bold: 700;
}
/* Base element rules */
html, body {
font-family: var(--font-sans);
font-size: var(--type-base);
line-height: var(--leading-normal);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Example utility classes */
.text-lg { font-size: var(--type-lg); line-height: var(--leading-normal); }
.text-2xl { font-size: var(--type-2xl); line-height: var(--leading-normal); }
.lead { line-height: var(--leading-normal); font-weight: var(--weight-medium); }
<h3>Apply tokens to your JS/React UI</h3>
<ul>
<li><b>Import the CSS tokens once</b> at your app entry so all components inherit them.</li>
<li><b>Provide a JS/TS theme wrapper</b> for styled-components/emotion or component libraries so tokens are accessible everywhere.</li>
</ul>
// Lovable prompt: update the app entry to import the typography tokens.
// If your project uses src/main.jsx or src/index.tsx, update that file.
// Otherwise detect the main entry and add the import at the top.
Please update src/main.jsx (or src/index.tsx) to add this at the top:
// Import centralized typography tokens
import './styles/typography.css';
<h3>Tailwind projects</h3>
<ul>
<li><b>Extend theme with the same system stack and scales</b> so utilities match CSS tokens.</li>
<li>Keep typographic scales in one place so Tailwind and components stay consistent.</li>
</ul>
// Lovable prompt: if Tailwind is present, update tailwind.config.js.
// Add a safe system stack and map sizes to the token scale.
Please update tailwind.config.js to extend the theme like this:
module.exports = {
theme: {
extend: {
fontFamily: {
sans: ['system-ui', '-apple-system', '"Segoe UI"', 'Roboto', '"Helvetica Neue"', 'Arial', 'sans-serif'],
},
fontSize: {
'xs': 'var(--type-xs)',
'sm': 'var(--type-sm)',
'base': 'var(--type-base)',
'lg': 'var(--type-lg)',
'xl': 'var(--type-xl)',
'2xl': 'var(--type-2xl)',
},
},
},
};
```
When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.