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

Ligonsker's avatar

How to import fonts with Vite?

Hello,

I tried to import a font with Vite in the following way:

import.meta.glob([
    '../fonts/**',
  ]);
  • I then placed the font asset in the layout file:
<head>
    <!-- Vite -->
    @vite(['resources/css/app.css', 'resources/js/app.js'])

    <!-- Fonts -->
    <link href="{{ Vite::asset('resources/fonts/my_font.ttf') }}" rel="stylesheet" />
</head>

In my app.css file I use the font:

html {
    font-family: 'my_font', sans-serif;
}

But nothing happens. When I open the Network tab in devtools, I see that it did load the font file (and not 404)

What am I doing wrong?

Thanks

0 likes
6 replies
DhPandya's avatar

@ligonsker In your vite.config.js add the below code in defineconfig

import path from 'path'; // add import for path


resolve: {
        alias: [{
            find: '../font',
            replacement: path.resolve(__dirname, 'resources/assets/fonts'), // replace this path with your actual path
        }],
    }
2 likes
Ligonsker's avatar

@DhPandya thanks, but that didn't help. My actual path is /resources/fonts. I changed but nothing happens. The font is in '/resources/fonts/my_font.ttf'`.

Maybe there's another place I need to add it? Maybe I need to use @font-face as well?

DhPandya's avatar

@Ligonsker Ohh.. I'm using this to load fonts in my CSS.

@font-face {
    font-family: 'poppinsblack';
    src: url('../fonts/poppins-black-webfont.woff2') format('woff2'),
         url('../fonts/poppins-black-webfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;
}

body{font-family: 'poppinsblack';}
1 like
Ligonsker's avatar

Update: The Vite docs have the following example:

Importing a static asset will return the resolved public URL when it is served:

// js
import imgUrl from './img.png'
document.getElementById('hero-img').src = imgUrl

For example, imgUrl will be /img.png during development, and become /assets/img.2d8efhg.png in the production build. The behavior is similar to webpack's file-loader. The difference is that the import can be either using absolute public paths (based on project root during dev) or relative paths. url() references in CSS are handled the same way.

The only say url() references in CSS are handled the same way., but I couldn't figure out how to use that as per the JS example. Maybe you can see?

Ligonsker's avatar

Update #2: I made it work by first adding the font using @font-face with path in the resources folder:

@font-face {
    font-family: 'my_font';
    src: url('/resources/fonts/my_font.ttf');
    font-weight: normal;
    font-style: normal;
}

html {
    font-family: 'my_font', sans-serif;
}

So from what I understand, in development, it will directly take the url from the resources folder, and in production after running npm run build it will generate some other public URL.

**Also I completely removed the other code I added:

import.meta.glob([
    '../fonts/**',
  ]);

and

<link href="{{ Vite::asset('resources/fonts/my_font.ttf') }}" rel="stylesheet" />
4 likes

Please or to participate in this conversation.