I'm trying to switch over from CRA to Vite to build my React projects, and I'm running into an issue where I can't get my fonts to load at all. The browser gives me the following error.
GET
http://localhost:5173/assets/fonts/Roboto-Regular.woff
[HTTP/1.1 404 Not Found 1ms]
downloadable font: download failed (font-family: "Roboto" style:normal weight:400 stretch:100 src index:0): status=2147746065 source: http://localhost:5173/assets/fonts/Roboto-Regular.woff
These are the font face rules I'm using.
// _fonts.scss
@font-face {
font-family: "Roboto";
src: url("../../assets/fonts/Roboto-Regular.woff") format("woff");
font-weight: 400;
}
And this is my index.scss file.
@use "./styles/partials/fonts" as *;
body {
font-family: "Roboto", Arial, Helvetica, sans-serif;
}
I thought it might be my folder structure, but that's not it either. I'm really confused as to why my fonts are loading when I do npm run dev
and I've even tried to replicate the issue in a CRA project with no success at all.
I'm trying to switch over from CRA to Vite to build my React projects, and I'm running into an issue where I can't get my fonts to load at all. The browser gives me the following error.
GET
http://localhost:5173/assets/fonts/Roboto-Regular.woff
[HTTP/1.1 404 Not Found 1ms]
downloadable font: download failed (font-family: "Roboto" style:normal weight:400 stretch:100 src index:0): status=2147746065 source: http://localhost:5173/assets/fonts/Roboto-Regular.woff
These are the font face rules I'm using.
// _fonts.scss
@font-face {
font-family: "Roboto";
src: url("../../assets/fonts/Roboto-Regular.woff") format("woff");
font-weight: 400;
}
And this is my index.scss file.
@use "./styles/partials/fonts" as *;
body {
font-family: "Roboto", Arial, Helvetica, sans-serif;
}
I thought it might be my folder structure, but that's not it either. I'm really confused as to why my fonts are loading when I do npm run dev
and I've even tried to replicate the issue in a CRA project with no success at all.
5 Answers
Reset to default 6I found the issue. It has to do with how partial files work. If you aren't using a module bundler, sass expects you to write all links in your partial file as though you were writing a relative path to the scss file that would use that partial instead. So instead of writing:
src: url("../../assets/fonts/Roboto-Regular.woff") format("woff");
It should have been:
src: url("./assets/fonts/Roboto-Regular.woff") format("woff");
because that's the relative url that index.scss would use. You don't have to do this when using create-react-app
so I mistakenly assumed Vite expected me to do something different entirely.
I had the same issue (Vite + React) and leaving this here just in case it helps someone.
My CSS file was importing the font like this:
@font-face {
font-family: "Optimus Princeps";
src: url("./fonts/OptimusPrinceps.ttf") format("ttf") <- note the explicit format declaration
}
And it wouldn't work, visiting localhost:5173/src/fonts/OptimusPrinceps.ttf
would download the file but the browser wouldn't display it.
What fixed it was removing the explicit declaration, blind guess. However, this could be because of how this specific font works and has nothing to do with Vite.
Working CSS:
@font-face {
font-family: "Optimus Princeps";
src: url("./fonts/OptimusPrinceps.ttf");
}
The issue for me was using ~
in the font urls.
Before:
@font-face {
src: url('~@/assets/fonts/Regular.ttf') format('truetype'),
After:
@font-face {
src: url('@/assets/fonts/Regular.ttf') format('truetype'),
Vite is "smart" enough to know how to change relative paths for assets in CSS files.
https://vitejs.dev/guide/assets#importing-asset-as-url
I don't know why others stated it helped them to remove the format(...)
part from the src
property value, which makes no sense, but if a font isn't loading (in Vite's development server), it's most likely an incorrect URL path.
This can be verified in devtools' network
tab. When a font file is loaded correctly it can be previewed:
And this is how I load the font file, relative to the CSS file:
@font-face {
font-family: "Roboto";
src:
local("Roboto"),
url("../assets/fonts/RobotoFlex.woff2") format("woff2");
font-weight: 300 700; /* Range of weights supported by the variable font */
font-style: normal; /* Include if the font has italic styles */
}
File system tree:
Just in case, remember to check and remove any hardcoded tag at index.html
.
I had a <link href="https://fonts.googleapis.com/css?family=Montserrat:wght@400;700" rel="stylesheet">
just to make it painful.