Vinicius Damiati
Vinicius Damiati

Reputation: 71

VueJs not displaying SVGs

I'm creating a single page application using VueJs and I'm facing a problem that all my SVGs are not being rendered. I'm using webpack-simple CLI and I'm using SLDS(Salesforce Lightning Design System) as CSS framework, which is providing me all my svgs.

Here is one of my components which are not displaying the SVGs:

export default {
        props: ['tabData']
    }
<template>
    <li class="slds-context-bar__item slds-context-bar__item_tab" role="presentation">
        <a href="javascript:void(0);" class="slds-context-bar__label-action" role="tab" title="Tab Item 2"
           aria-selected="false" tabindex="-1" aria-controls="context-tab-panel-3" id="context-tab-id-3">
            <div class="slds-icon_container" :title="tabData.tabName">
                <svg class="slds-icon slds-icon_small slds-icon-text-default" aria-hidden="true">
                    <use xmlns:xlink="http://www.w3.org/1999/xlink"
                         xlink:href="../../assets/lightning/assets/icons/standard-sprite/svg/symbols.svg#case"/>
                </svg>
            </div>
            <span class="slds-truncate" :title="tabData.tabName">{{ tabData.tabName }}</span>
        </a>
        
        <div class="slds-context-bar__icon-action slds-context-bar__dropdown-trigger slds-dropdown-trigger slds-dropdown-trigger_click slds-p-left_none slds-p-right_none">
            <button class="slds-button slds-button_icon slds-button_icon-container slds-button_icon-x-small"
                    aria-haspopup="true"
                    tabindex="-1">
                <svg class="slds-button__icon" aria-hidden="true">
                    <use xmlns:xlink="http://www.w3.org/1999/xlink"
                         xlink:href="../../assets/lightning/assets/icons/utility-sprite/svg/symbols.svg#chevrondown"/>
                </svg>
            </button>
        </div>
        
        <div class="slds-context-bar__icon-action slds-col_bump-left slds-p-left_none">
            <button class="slds-button slds-button_icon slds-button_icon-container slds-button_icon-x-small"
                    tabindex="-1" :title="'Fechar ' + tabData.tabName">
                <svg class="slds-button__icon" aria-hidden="true">
                    <use xmlns:xlink="http://www.w3.org/1999/xlink"
                         xlink:href="../../assets/lightning/assets/icons/utility-sprite/svg/symbols.svg#close"/>
                </svg>
            </button>
        </div>
    </li>
</template>

This component above is called in other component named GlobalNavigation:

import DashboardTab from '../navigation-tabs/DashboardTab.vue';
    import TabsContainer from '../navigation-tabs/TabsContainer.vue';
    import NavigationTab from '../navigation-tabs/NavigationTab.vue';
    
    export default {
        data() {
            return {
                navigationTabs: [
                    {
                        tabName: 'Organizações',
                        hasMenu: true
                    },
                    {
                        tabName: 'Contas',
                        hasMenu: false
                    }
                ]
            };
        },
        components: {
            ursusDashboardTab: DashboardTab,
            ursusTabsContainer: TabsContainer,
            ursusNavigationTab: NavigationTab
        }
    }
.slds-global-navigation {
        margin-top: 50px;
    }
<template>
    <div class="slds-global-navigation">
        <div class="slds-context-bar slds-context-bar_tabs">
            <div class="slds-context-bar__primary">
                <ursus-dashboard-tab></ursus-dashboard-tab>
            </div>
            <ursus-tabs-container>
                <ursus-navigation-tab
                        v-for="tab in navigationTabs"
                        :tabData="tab"/>
            </ursus-tabs-container>
        </div>
    </div>
</template>

And finally GlobalNavigation is called in my App.vue file

export default {
    data() {
        return {
            displayTrialBar: false,
            displayAlert: false
        }
    }
}
.slds-unscrollable-page {
        overflow: hidden;
    }
<template>
    <div class="slds-unscrollable-page">
        <ursus-trial-bar v-if="displayTrialBar"></ursus-trial-bar>
        <ursus-alert v-if="displayAlert"></ursus-alert>
        <ursus-global-header></ursus-global-header>
        <ursus-global-navigation></ursus-global-navigation>
        <ursus-main-area></ursus-main-area>
    </div>
</template>

And here you can check my main.js

import Vue from 'vue';
import VueRouter from 'vue-router';
import VueResource from 'vue-resource';
import App from './App.vue';
import {routes} from './routes';
import { store } from './store';

import TrialBar from './components/global/TrialBar.vue';
import Alert from './components/global/Alert.vue';
import GlobalHeader from './components/global/GlobalHeader.vue';
import GlobalNavigation from './components/global/GlobalNavigation.vue';
import MainArea from './components/global/MainArea.vue';
import PageHeader from './components/page/PageHeader.vue';
import PageBody from './components/page/PageBody.vue';

Vue.use(VueRouter);
Vue.use(VueResource);

Vue.component('ursus-trial-bar', TrialBar);
Vue.component('ursus-alert', Alert);
Vue.component('ursus-global-header', GlobalHeader);
Vue.component('ursus-global-navigation', GlobalNavigation);
Vue.component('ursus-main-area', MainArea);
Vue.component('ursus-page-header', PageHeader);
Vue.component('ursus-page-body', PageBody);

const router = new VueRouter({
    routes,
    mode: 'history'
});

new Vue({
  el: '#app',
  store,
  router,
  render: h => h(App)
})

And also here is my webpack.config.js

var path = require('path')
var webpack = require('webpack')

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ],
      },
      {
        test: /\.scss$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'sass-loader'
        ],
      },
      {
        test: /\.sass$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'sass-loader?indentedSyntax'
        ],
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
            // the "scss" and "sass" values for the lang attribute to the right configs here.
            // other preprocessors should work out of the box, no loader config like this necessary.
            'scss': [
              'vue-style-loader',
              'css-loader',
              'sass-loader'
            ],
            'sass': [
              'vue-style-loader',
              'css-loader',
              'sass-loader?indentedSyntax'
            ]
          }
          // other vue-loader options go here
        }
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]'
        }
      }
    ]
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    },
    extensions: ['*', '.js', '.vue', '.json']
  },
  devServer: {
    historyApiFallback: true,
    noInfo: true,
    overlay: true
  },
  performance: {
    hints: false
  },
  devtool: '#eval-source-map'
}

if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
}

Upvotes: 5

Views: 9748

Answers (1)

bbsimonbb
bbsimonbb

Reputation: 28992

What does your browser debug show? Your svgs have <use> tags with relative urls. These will be resolved by the browser, and it's likely that they're not pointing to where you think. Your browser network tab should tell you what's going on?

Upvotes: 2

Related Questions