Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

RobDeKort's avatar

Vite @font-face fonts 404 on dev server

Hi folks!

I'm switching from Mix to Vite to compile my JS and TailwindCSS as it's so fast. But I'm stuck on fonts (or any asset references from CSS) 404'ing on the dev server.

Any font I load like this 404's when running npm run dev:

@font-face {
    src: url('/fonts/BreveDisplay-Regular.woff2') format('woff2');
}

It does work for the production build: npm run build.

The dev server keeps serving the fonts under http:/ /127.0.0.1:3000/correct/font/path but that results in a 404 as in my case should resolve under http:/ /mysite.test/correct/font/path as I use Valet.

I've tried to set origin in my server block but that doesn't help.

This is my config:

import laravel from 'laravel-vite-plugin'
import { defineConfig, loadEnv } from 'vite'

export default defineConfig(({ command, mode }) => {
    const env = loadEnv(mode, process.cwd(), '')
    return {
        plugins: [
            laravel([
                'resources/css/site.css',
                'resources/js/site.js',
            ])
        ],
        base: env.APP_URL,
        server: {
            open: env.APP_URL
        }
    }
});

Thanks for your help in advance!

0 likes
11 replies
Snapey's avatar

http:/ /127.0.0.1:3000/correct/font/path is equivalent to your valet site so should work?

Its not going to be resolved by dnsmasq because it does not need to, its going directly to the source of the assets.

1 like
RobDeKort's avatar

Hey thanks for your reply. I'm afraid I don't really understand. But I think the issue is my valet site is under http: //mysite.test/ and not under that Vite Dev Server IP + port. So fonts should be served under http: //mysite.test/correct/font/path instead of via that IP.

RobDeKort's avatar
RobDeKort
OP
Best Answer
Level 3

Ok, this seems to be resolved by referencing the fonts like:

src: url('/public/fonts/sofia-pro.woff2')

Instead of:

src: url('/fonts/sofia-pro.woff2')

Somehow a friend got that idea from your answer @snapey. So thank you! This is way over my head ;-).

7 likes
Snapey's avatar

@RobDeKort You should never see public in a URL. If you do then your site is at risk from being hacked.

2 likes
RobDeKort's avatar

@Snapey Gotcha. It doesn’t compile with that URL though. Vite copies the files to the build folder and references those in the compiled CSS. So all is good I think.

1 like
Taelkir's avatar

@RobDeKort Can confirm I'm seeing the same - fonts are now appearing in /build directory/url rather than /public after running a build. For future readers just converting to Vite; it's probably worth ensuring that directory view is disabled on your server if navigating to http://yoursite.test/build is showing a list of your assets.

mhyeganeh's avatar

Yeah. This works! But the problem with this approach is that after npm run build we have duplicates of these fonts inside public/build/assets directory and I don't beleive this is a good way!

wanahmadfiras's avatar

I found a simpler solution. Before this, since I'm using Tailwind CSS, I declare the @font-face inside resources/css/app.css. I think it got to do with how PostCSS and Vite handle public assets: https://vitejs.dev/guide/assets.html#the-public-directory

Regarding the duplicates mentioned by @mhyeganeh, they have an experimental option to disable it but I think this only works if the source is not imported via a transformed source: https://vitejs.dev/config/build-options.html#build-copypublicdir

My simple solution is to add:

<style>
		@font-face { ... }
</style>

directly on the index/welcome blade file so that it is considered as a completely static non-transformed asset. The file will not be copied.

Alternatively, you can move the fonts folder into resources directory, and use relative URL in the resources/css/app.css like url(../fonts/fontfile.otf). This way, you can benefit from the asset hashing and you don't clutter your public directory.

2 likes

Please or to participate in this conversation.