Vue Cli 3 Local fonts not loading

P. Jack picture P. Jack · Mar 29, 2019 · Viewed 15.9k times · Source

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();
  }

Answer

Joeri picture Joeri · Apr 23, 2019

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.