When trying to load custom local fonts in Vue CLI 3 the fonts still will not appear. I am not receiving any error messages. The inspector shows the correct rule being loaded, but fonts are falling back to serif
on #app. Fonts are not showing up in my dist folder anywhere.
I have tried adding loaders in vue.config.js, changing url paths, and moving the @font-face rules around to different locations, changing the public path to ' ' and '/', importing scss into main.js.
Font loading:
@font-face {
font-family: 'OpenSans-Regular';
src: url('/assets/fonts/OpenSans-Regular.eot');
src: url('/assets/fonts/OpenSans-Regular.eot?#iefix') format('embedded-opentype'),
url('/assets/fonts/OpenSans-Regular.otf') format('font-opentype'),
url('/assets/fonts/OpenSans-Regular.woff') format('font-woff'),
url('/assets/fonts/OpenSans-Regular.ttf') format('font-truetype'),
url('/assets/fonts/OpenSans-Regular.svg#OpenSans-Regular') format('svg');
font-weight: normal;
font-style: normal;
}
And use within App.vue:
<style lang="scss">
#app {
font-family: 'OpenSans-Regular', serif;
}
</style>
That styling is placed within my main.scss
file. The file structure as follows:
src
assets
fonts
OpenSans-Regular.eot
OpenSans-Regular.woff
etc
styles
main.scss
App.vue
vue.config.js
vue.config.js
file is as follows:
module.exports = {
publicPath: '/',
css: {
sourceMap: true,
loaderOptions: {
sass: {
data: `@import "@/styles/main.scss";`
}
}
},
configureWebpack: {
module: {
rules: [{
test: /\.(ttf|otf|eot|woff|woff2)$/,
use: {
loader: "file-loader",
options: {
name: "fonts/[name].[ext]",
},
},
}]
}
}
}
I have also tried a chainWebpack in vue.config.js
to no avail:
chainWebpack: config => {
config
.module
.rule("file")
.test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/,)
.use("url-loader")
.loader("url-loader")
.options({
limit: 10000,
name: 'assets/fonts/[name].[ext]'
})
.end();
}
Start with the font you want, and always end with a generic family, to let the browser pick a similar font in the generic family, if no other fonts are available. Note: Separate each value with a comma. Note: If a font name contains white-space, it must be quoted.
Vite isn't specific to Vue, but instead is a way to develop JavaScript/TypeScript applications. Let's look at the how the Vue CLI works and how Vite is different. Evan You is at it again. He developed a new tool called Vite (French for fast).
Did you try
@font-face {
font-family: 'OpenSans-Regular';
src: url('~@/assets/fonts/OpenSans-Regular.eot');
src: url('~@/assets/fonts/OpenSans-Regular.eot?#iefix') format('embedded-opentype'),
url('~@/assets/fonts/OpenSans-Regular.otf') format('font-opentype'),
url('~@/assets/fonts/OpenSans-Regular.woff') format('font-woff'),
url('~@/assets/fonts/OpenSans-Regular.ttf') format('font-truetype'),
url('~@/assets/fonts/OpenSans-Regular.svg#OpenSans-Regular') format('svg');
font-weight: normal;
font-style: normal;
}
Works for me Vue CLI 3, no vue.config.js
settings.
I'm loading my styles like this:
import Vue from 'vue';
import router from './router';
import store from './store';
// eslint-disable-next-line
import styles from './scss/app.scss';
import App from './App.vue';
Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app');
Not sure if that is good practice.
What I ended up doing was moving to a file loader method to get the fonts to package over and set the the public path.
vue.config.js
module.exports = {
assetsDir: 'assets/',
publicPath: '/', // Base directory for dev
css: {
sourceMap: true,
loaderOptions: {
sass: {
data: `@import "@/styles/main.scss";`
}
}
},
chainWebpack: config => {
config.module
.rule("fonts")
.test(/\.(ttf|otf|eot|woff|woff2)$/)
.use("file-loader")
.loader("file-loader")
.tap(options => {
options = {
// limit: 10000,
name: '/assets/fonts/[name].[ext]',
}
return options
})
.end()
}
};
File-loader doesn't see the files unless called in the js so I imported them in main.js
The console log is to navigate around the linter flagging unused imports
// Fonts need to be called in js for webpack to see and copy over
import OpenSansReg from './assets/fonts/OpenSans-Regular.ttf';
import OpenSansLight from './assets/fonts/OpenSans-Light.ttf';
import OpenSansBold from './assets/fonts/OpenSans-Bold.ttf';
console.log(OpenSansReg, OpenSansBold, OpenSansLight);
then in one of my scss files
@font-face {
font-family: 'OpenSans-Regular';
src: url('/assets/fonts/OpenSans-Regular.eot?#iefix') format('embedded-opentype'),
url('/assets/fonts/OpenSans-Regular.otf') format('opentype'),
url('/assets/fonts/OpenSans-Regular.woff') format('woff'),
url('/assets/fonts/OpenSans-Regular.ttf') format('truetype'),
url('/assets/fonts/OpenSans-Regular.svg#OpenSans-Regular') format('svg');
font-weight: normal;
font-style: normal;
}
For me, I just took out that 'format()' thing and works... Finally..
I stuck my custom icon-font in the head tags of my initial index.html page Which also has a custom font import. The same page that you would stick your <div id="vue-app"></div>
. All the other pages /components can use the font-family for me.
<head>
...
<link rel="stylesheet" href="icon-font/styles.css" />
</head>
But if i try any other location in the project it fails. and the Scss doesnt even compile.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With