Skip to content

Instantly share code, notes, and snippets.

@internetztube
Last active August 20, 2021 18:18
Show Gist options
  • Save internetztube/42a1410aa9f3d042d0521e8d69480cc9 to your computer and use it in GitHub Desktop.
Save internetztube/42a1410aa9f3d042d0521e8d69480cc9 to your computer and use it in GitHub Desktop.
Nuxt Inline SVG Symbols
<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 } })
}
})
@addictional
Copy link

very helpful post!

@leviwheatcroft
Copy link

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>

@internetztube
Copy link
Author

Thanks, @leviwheatcroft! Updated the Snippet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment