Automatically collects webfont links, imports, and definitions from your Vite project, downloads CSS and font files (privacy-first), adds the fonts to your bundle (or serves them through the dev server), and injects font definitions using a non-render-blocking method. External CSS and font files are stored in a persistent file cache, making them available for offline development.
npm i vite-plugin-webfont-dl -D
Extracts, downloads, and injects fonts from the original Google Fonts code snippet.
<head>:<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300;400&family=Roboto:wght@100&display=swap" rel="stylesheet">
webfontDownload to your Vite plugins without any configuration. The plugin will automatically handle everything:// vite.config.js
import webfontDownload from 'vite-plugin-webfont-dl';
export default {
plugins: [
webfontDownload(),
],
};
dist/index.html:<style>@font-face{font-family:...;src:url(/assets/foo-xxxxxxxx.woff2) format('woff2'),url(/assets/bar-yyyyyyyy.woff) format('woff')}...</style>
*Extracts, downloads, and injects fonts from the configured webfont CSS URL(s).*
<link href="[CSS URL]" rel="stylesheet">
webfontDownload to your Vite plugins with the selected webfont CSS URL(s):// vite.config.js
import webfontDownload from 'vite-plugin-webfont-dl';
export default {
plugins: [
webfontDownload([
'https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap',
'https://fonts.googleapis.com/css2?family=Fira+Code&display=swap'
]),
],
};
The webfonts are injected and ready to use.
The plugin works seamlessly whether you are running a local development server or building for production.
š” Import alias: The plugin can be imported using any of these names:
webfontDownload,webfontDl,viteWebfontDl,ViteWebfontDownload, orviteWebfontDownload. Use whichever style you prefer!
h1 {
font-family: 'Press Start 2P', cursive;
}
h2 {
font-family: 'Fira Code', monospace;
}
To use with the Laravel Vite Plugin, add this line to your Blade file:
@vite('webfonts.css')
cdn.jsdelivr.net): works with Zero config or Simple configrsms.me): works with Zero config or Simple config@font-face definitions works with Simple configinjectAsStyleTag (boolean, default: true)
Inject webfonts as a <style> tag (embedded CSS) or as an external .css file.
async (boolean, default: true)
Controls CSS loading behavior (only applicable when injectAsStyleTag: false):
true: Async loading with media="print" trick (faster, but uses inline event handlers)false: Standard blocking CSS loading (CSP-compliant, no inline scripts)ā ļø For Chrome extensions or strict CSP environments, set async: false to avoid CSP violations.
minifyCss (boolean, default: value of build.minify)
Minify CSS code during the build process.
embedFonts (boolean, default: false)
Embed base64-encoded fonts directly into CSS.
ā ļø This can increase file size if CSS contains multiple references to the same font. Example
assetsSubfolder (string, default: '')
Moves downloaded font files to a separate subfolder within the assets directory.
cache (boolean, default: true)
Persistently stores downloaded CSS and font files in a local file cache.
Respects Vite's cacheDir configuration. Set to false to disable and delete the existing cache.
subsetsAllowed (string[], default: [])
Restricts downloaded fonts to specified Unicode subsets (e.g., ['latin', 'cyrillic']).
Leave empty to allow all subsets.
proxy (false | AxiosProxyConfig, default: false)
Proxy configuration for network requests.throwError (boolean, default: false)
If true, stops the build on font download/processing errors.
If false, errors are logged as warnings and the build continues.// vite.config.js
import webfontDownload from 'vite-plugin-webfont-dl';
export default {
plugins: [
webfontDownload([], {
injectAsStyleTag: true,
minifyCss: true,
embedFonts: false,
async: true,
cache: true,
proxy: false,
assetsSubfolder: 'fonts',
subsetsAllowed: ['latin', 'latin-ext'],
throwError: false,
})
],
};
With font URLs:
webfontDownload([
'https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap',
], {
injectAsStyleTag: true,
cache: true,
})
ā ļø Using the standard method to add third-party webfonts (Google Fonts, Bunny Fonts, or Fontshare) to a webpage can significantly slow down page load. Lighthouse and PageSpeed Insights call them "render-blocking resources", which means the page can't fully render until the webfonts CSS has been fetched from the remote server.
š By avoiding render-blocking resources caused by third-party webfonts, you can boost page performance, leading to a better user experience and improved SEO results.
āļø The plugin downloads the specified fonts from the third-party webfont service (like Google Fonts) and dynamically injects them (as an internal or external stylesheet) into your Vite project, transforming third-party webfonts into self-hosted ones. š¤©
š In addition to the significant performance increase, your visitors will also benefit from privacy protection, since there is no third-party server involved.
Google Fonts generates the following code, which you have to inject into your website's <head> (example):
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fira+Code&display=swap" rel="stylesheet">
š± What happens on the client-side with Google Fonts:
fonts.googleapis.com. This happens in the background to improve performance. [preconnect]fonts.gstatic.com. [preconnect]fonts.googleapis.com (with font-display:swap). [stylesheet]@font-face definitions containing font URLs from the fonts.gstatic.com server.fonts.gstatic.com.In contrast, the Webfont-DL plugin does most of the work at build time, leaving minimal work for the browser.
Webfont-DL plugin
index.html, and generated CSS)<style> tag) or an external webfont CSS file<head> using a non-render-blocking method (example):<style>
@font-face {
font-family: 'Fira Code';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url(/assets/uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_GNsJV37Nv7g.9c348768.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
...
</style>
Or (using the dev server or injectAsStyleTag: false option):
<link rel="preload" as="style" href="/assets/webfonts.b904bd45.css">
<link rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');" href="/assets/webfonts.b904bd45.css">
š± What happens on the client-side with the Webfont-DL plugin:
<style> tag).Or
preload]print stylesheet (non-render-blocking). After loading, it is promoted to an all media type stylesheet (by removing the media attribute). [stylesheet]Comparison using a starter Vite project:
| ā¶ļø Standard Google Fonts | š | ā¶ļø Webfont DL Vite plugin |
|---|---|---|
| š webfont.feat.agency | š webfont-dl.feat.agency |
MIT License Ā© 2022 feat.