vue.jsfont-facevue-clivue-cli-3webpack-file-loader

Vue Cli 3 Local fonts not loading


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

Solution

  • 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.