FontLoader + vite + github pages returning a 404 for my font

Hi there, first off I’m new to three and relatively new to js, so apologies in advance for naivete.

When I use build using vite and run the distro locally, I can load my text geometry just fine. However, when I do the same via github pages, I get a 404. I have the font in /public/fonts.

Some weirdness I have noticed with the font loader:

  • I have noticed that the url for fontLoader.load() needs to be relative to my git repo root directory, rather than the directory at which my package.json etc. is (which has occasionally been nested inside a folder in the git repo rather than at the root level). I find this behaviour very strange, and have not encountered it elsewhere - my textureLoader doesn’t behave this way, and I can move the directory wherever I want and my matcaps will all load consistently.
  • Another weird behaviour is that fontLoader.load() seems to need to load from a public folder (whether this is /public or just /public) but will ignore /static in some cases (see below), again unlike any textureLoader or anything else. It means I have to keep a separate static and public folder which is quite inconvenient.

Anyway, I can load my font from static if I run locally using just the vite command (i.e. npm run dev), but not from public. I can load my font from public but not static if I run vite build and then go live locally from /dist. And in no case can I seem to load my font when I push to github, and deploy using a custom workflow and vite build. For clarity, this is true even when my root folder for node modules and for the git repo are the same.

I’m at my wit’s end - can anyone help me with this madness??

Try omitting “/public”from the loader url, eg…

fontLoader.load("/fonts/path-to-your-font/font.json, (font) =>

“/public” doesn’t exist in dist after build is run, anything in public is output to its respective folder in dist directly, “/public/fonts” should become “dist/fonts”

so just changed it to:

fontLoader.load("/fonts/helvetiker_regular.typeface.json", (font) => {

which is the path from my public folder, and now it’s showing up in neither the local vite build nor on github pages

I should also note that in the dist folder, there doesn’t seem to be a .json file anywhere for the font:

OK so trying this made me realise something. The local build is only working because it’s getting the font from OUTSIDE of /dist - i.e. because my pre-build files are available. If I run vite build, then rename the public folder, the font disappears on the live server. So, again, fontLoader doesn’t seem to care that it’s being called from dist and just tries to grab the font from the root of the git repo, for some reason I can’t work out (how does it know it’s in a git repo? Surely it should only know what directory it’s installed to?).

So, I guess my question becomes:

  • why is vite seemingly not packaging up the font into dist (perhaps not a question for this forum)
  • how can I get the font to import sensibly for fontloader to access it - is it maybe better to import the font separately within script.js file somehow and then point fontLoader to that?
  • Alternatively, is there any way to tell fontLoader to use a relative path or something like that?

that’s odd, is the font in a folder called “fonts” inside the public directory? what happens if you put the font in a folder called fonts inside of public and then run build? afaik this should output the folder with it’s contents directly into dist…

when using vite knowing I’ll build for a subdirectory on a live server I’ll always setup the vite config base to be “./” as to draw resources from the relative directory rather than root, give this a try, create a vite.config.js file at the root of your local project, add the following to it and restart your local server…

import { defineConfig } from 'vite'
export default defineConfig({
  base: './',
  //any other config you require...
})

then try loading the font again with…

fontLoader.load("./fonts/helvetiker_regular.typeface.json", (font) => {

ensuring the font.json is in a folder named “fonts” indside the public directory

so this is now the setup of my vite.config.js, which is living in the root of the local project. Previously was this, and I was manually changing the urls in index.html for the local deploy:
base: process.env.NODE_ENV === "production" ? "/threejs-journey/" : "./",

I ran the build and still can’t see any .json in dist for the font. I also ran it with the fonts folder in the root, with no luck.

The only thing I can think of is that I have other subdirectories in root with their own package.json and vite setups inside (for other three.js challenges), but they don’t seem to have been interfering with anything else in the build…

image

Is this line in vite.config.js possibly the issue? I’m going to try changing it to public and see what happens.

OK so I now have the text showing up from the local server produced from the vite command again (via npm run dev), AND I now have the font showing up in dist/fonts/, which is great!

But it’s now not showing up in the local server from the vite build, nor on github pages. So I’m thinking I’m back to it being a fontLoader problem, where it’s not looking for /fonts/… within dist, but at a higher level.

Just going to see what happens if I change the fontLoader url to /dist/fonts…

If your base is set to “. /” font loader should be “. /fonts/…”

Edit: OK I see the problem, main.js is built to dist/assets so the path is wrong after build, keep the font loader as “. /fonts/…” and try dragging the fonts folder into dist/assets…

Eureka! Changing the fontLoader to “./fonts” - it’s now working on all 3 versions!

And to think this all started from having to put fonts in /public…

I’m incredibly appreciative of the help! I don’t fully understand this point:

Edit: OK I see the problem, main.js is built to dist/assets so the path is wrong after build, keep the font loader as “. /fonts/…” and try dragging the fonts folder into dist/assets…

But hopefully that seems not to be the issue then? Since changing vite.config’s publicDir to “../public” seemed to fix the fonts not showing up in dist/assets

1 Like

If you have any words of advice about best practice with regards to using a static folder and a public folder, I’d be eager to hear. Since it seems like I’m limited to one or the other using vite build?

Nice!

I think they’re possibly the same thing apart from a preference of naming convention as vite config’s publicDir can only be set to one directory, the default being root “/public”

1 Like

Ahhh that makes a lot of sense. Really appreciate your help again, have been stuck all day on this!! Thank you!

1 Like

I think it would be a good idea to mark this thread as solved by @Lawrence3DPK

2 Likes