5

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
    })
  ])
}
  • One note is that I have to display symbols from SVG files. – Vinicius Damiati Jun 29 '18 at 00:35
  • You've posted a huge amount of code, and your executable snippets are not executable. To help folk who want to answer, you could try posting a minimal example that reproduces the problem, and just use backticks ( the {} button on the toolbar, ) to post code that will never run in the browser. – bbsimonbb Jun 29 '18 at 07:54

1 Answers1

2

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?

bbsimonbb
  • 27,056
  • 15
  • 80
  • 110
  • I'm new as front end developer, I found in console exactly whats was going on. It was not pointing correctlly to where it should, – Vinicius Damiati Jun 29 '18 at 16:41
  • 4
    Welcome to dev tools ! Have a look around and get comfortable. _You're going to be here for a long time :-)_ – bbsimonbb Jun 29 '18 at 22:32