npm i raw-loader @nuxtjs/svg-sprite
-
-
Save internetztube/42a1410aa9f3d042d0521e8d69480cc9 to your computer and use it in GitHub Desktop.
<template> | |
<svg> | |
<use :href="`#i-${handle}`"></use> | |
</svg> | |
</template> | |
<script> | |
export default { | |
props: { | |
handle: { | |
type: String, | |
required: true | |
} | |
} | |
} | |
</script> |
<template> | |
<div> | |
<svg-symbols></svg-symbols> | |
<nuxt /> | |
</div> | |
</template> |
module.exports = { | |
modules: [ | |
'@nuxtjs/svg-sprite', | |
] | |
} |
import Vue from 'vue' | |
// eslint-disable-next-line import/no-webpack-loader-syntax | |
const svgFileContent = require('!!raw-loader!../assets/sprite/gen/icons.svg').default | |
Vue.component('svg-symbols', { | |
render: function (createElement) { | |
const innerHTML = svg.replace(/.*?$/m, '') // strip declaration | |
const style = 'height: 0; width: 0; position: absolute; top: 0; z-index: -1' | |
return createElement('div', { domProps: { innerHTML }, attrs: { style } }) | |
} | |
}) |
This is really helpful, thankyou.
I'm concerned that it might not be the best approach though. If I understand correctly svg-symbols.js
would bundle cheerio (~$200kb) with your client, even with target: static
. Additionally, we load the raw xml from fs, render it as a dom, select the svg element, serialise it to HTML, and then hand it off to the browser / SSR to render it as a dom again.
You can avoid all of the above by using a regex to strip out the unwanted xml declaration from icons.svg. I know that using regex to manipulate xml isn't ideal, but IMO it's a reasonable measure in this case because we're not looking for tags or anything, just discarding the first line.
I'm using all the same files you've posted with the exception of svg-symbols.js
, mine is a vue SFC svg-symbols.vue
instead of a js file.
<script>
// eslint-disable-next-line import/no-webpack-loader-syntax
const svg = require('!!raw-loader!../assets/sprite/gen/icons.svg').default
export default {
render: (createElement) => {
const innerHTML = svg.replace(/.*?$/m, '') // strip declaration
const style = 'height: 0; width: 0; position: absolute; top: 0; z-index: -1'
return createElement('div', { domProps: { innerHTML }, attrs: { style } })
}
}
</script>
Thanks, @leviwheatcroft! Updated the Snippet.
very helpful post!