How to preload a CSS @font-face font that is bundled by webpack4+babel?
Solution 1
was able to make it work on webpack4 by installing version 3beta and using while list option:
yarn add -D [email protected]
new PreloadWebpackPlugin({
rel: 'preload',
as: 'font',
include: 'allAssets',
fileWhitelist: [/\.(woff2?|eot|ttf|otf)(\?.*)?$/i],
}),
Solution 2
Posting this since I think it might help someone in a similar position - I realize it doesn't solve the described issue.
Had the same problem - didn't need to hash my font-files but had another part of the url that was not static. A bit hackish, but solved my problem. Maybe it can help someone. In theory you can create your own hash-id and set that as the htmlWebpack-plugin variable.
In my index.html
<html>
<head>
<link rel="preload" href="<%= htmlWebpackPlugin.options.woffSrc %>" as="font" type="font/woff" crossorigin>
<link rel="preload" href="<%= htmlWebpackPlugin.options.woff2Src %>" as="font" type="font/woff2" crossorigin>
//rest of html
webpack.prod.conf.js - updated HtmlWebpackPlugin
plugins: [
new HtmlWebpackPlugin({
...config,
woffSrc: `https://url.to.my.page.com/${ASSETS_FOLDER}/static/assets/fonts/GilroyRegular.woff`,
woff2Src: `https://url.to.my.page.com/${ASSETS_FOLDER}/static/assets/fonts/GilroyExtraBold.woff2`
})
]
I reasoned that the font-files didn't need to have the hash - since that is mainly used to control cache and I won't change the font files, so I turned that of in my webpack file-loader. Please correct me if I'm wrong here.
Having the loader:
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 2000,
name: utils.assetsPath('assets/fonts/[name].[ext]')
}
}
Was unable to get the preload-webpack-plugin to work due to build errors and got tired troubleshooting after 2 days.
Solution 3
I found a workaround for this. It isn't pleasant but I think is't better than nothing.
here I only wanted to preload woff
and woff2
files.
new PreloadWebpackPlugin({
rel: 'preload',
include: 'allAssets',
fileBlacklist: [/\.(js|ttf|png|eot|jpe?g|css|svg)/]
}),
Related videos on Youtube
Comments
-
Frank almost 2 years
I have a webpack4+babel bundler setup for a react web app. In a LESS file, I reference a local font. This font gets copied over to the
dist
folder on build and its filename is hashed. I want to be able to preload this font.Here is my LESS file:
@font-face { font-family: 'Test'; src: url('../fonts/test.ttf') format('truetype'); font-weight: 400; }
I have tried the following approaches but so far with no success:
- Add custom import to my app's main JS file.
import(/* webpackPreload: true */ "../fonts/test.ttf");
Here is my
.babelrc
file:{ "presets": [ "@babel/preset-env", "@babel/preset-react" ], "plugins": [ "@babel/plugin-syntax-dynamic-import" ] }
Running
webpack
does not produce preload directions anywhere as far as I can see in the outputted html - I have searched through thedist
folder contents and found nothing.- preload-webpack-plugin
I add this to my
webpack.config.js
file:plugins: [ new HtmlWebpackPlugin(), new PreloadWebpackPlugin({ rel: 'preload', as(entry) { if (/\.css$/.test(entry)) return 'style'; if (/\.woff$/.test(entry)) return 'font'; if (/\.png$/.test(entry)) return 'image'; return 'script'; } }) ]
This creates preloads for the JS script file bundles but not for the CSS and fonts.
Any ideas on how to get this to work?
-
Frank about 5 yearsThanks for the response but my problem is that the font filenames are hashed by webpack and so I don't know what they will be after they are copied across to the
dist
folder. Perhaps there is a way of using a placeholder in the HTML file? -
GProst about 5 yearsAre your font files going to change often? Why do you need to include them to your webpack compilation process? I think you can create another
assets
folder to server static files which don't need to be compiled by webpack in parallel with adist
folder and serve static files from this folder as well -
Frank about 5 yearsThat's a fair point. The fonts won't change and even if they do, copying them across after the webpack build isn't too much effort. I presume that linking to the font files in the HTML (for preload) and also linking using @font-face in CSS (where they'll actually be used) is fine - i.e. once they are preloaded by the browser, then it won't bother doing so again?
-
GProst about 5 yearsI don't think there is any other way of preloading fonts other than using
link
. So even if you used some Webpack preload solution it would just insert thelink
with preload attribute that would load your asset. So yes I believe a browser shouldn't make another request if it already preloaded the asset however I think you'd want to put somecache-control
headers so that browser cached the asset. -
Frank about 5 yearsCheers. Your recommended approach is now in and working well.
-
GProst about 5 yearsGlad to hear that!
-
Brandon Minton about 4 yearsnot what the user was looking for but that helped me out +1
-
cbrwizard over 3 yearsThis can be the best solution when you want only specific fonts to be preloaded.