nuxt / image

Plug-and-play image optimization for Nuxt applications.
https://image.nuxt.com
MIT License
1.34k stars 270 forks source link

Loading SVG as inline #585

Open marvincaspar opened 2 years ago

marvincaspar commented 2 years ago

Hi,

it would be great if there is an option for svgs to load them inline instead of just loading it via the img tag. Then you have the option to set css stuff like fill color and you reduce the http requests. My current solution is to fetch the img src, get the response text and than output it into a span tag but it would be nice if this is part of the nuxt image.

sevillaarvin commented 2 years ago

Hello, I use the ?raw option of @nuxtjs/svg and v-html for inlining svg images. One disadvantage of this is that there is an extra div wrapper. I couldn't get the ?inline option to work for some reason.

I am using vue3/nuxt3, see partial implementation below:

#+name: ./components/MyComponent.vue #+begin_src vue ```vue ``` #+end_src
#+name: package.json #+begin_src json ```json { "dependencies": { "@nuxtjs/svg": "^0.4.0" } } ``` #+end_src
#+name: nuxt.config.js #+begin_src js ```js import { defineNuxtConfig } from "nuxt" export default defineNuxtConfig({ // ...other options buildModules: [ "@nuxtjs/svg" ] // ...other options }) ``` #+end_src
marvincaspar commented 2 years ago

My issue is, that the svgs are stored in storyblok and I just receive the url

awacode21 commented 1 year ago

i am dealing with the same issue where storyblok editors can provide svg illustrations but i need to be able to color them based on their context.

cstuncsik commented 1 month ago

You can create a component that accepts the URL for the SVG file, fetch it (as text) and parse it into a DOM node

<script lang="ts" setup>
import { onMounted } from 'vue'

const props = defineProps<{ url: string }>()
const svgString = ref('')

onMounted(() => {
  fetch(props.url)
    .then(response => response.text())
    .then((svg) => {
      const parser = new DOMParser()
      const doc = parser.parseFromString(svg, 'image/svg+xml')
      const svgElement = doc.documentElement
      const svgContainer = document.createElement('div')
      svgContainer.appendChild(svgElement)
      svgString.value = svgContainer.innerHTML
    })
  })
</script>
<template>
  <div v-html="svgString" />
</template>
Rednas83 commented 1 month ago

With hyperscript you can do the same in one line for nuxt icons. Not sure how to set it up for external svg images🤞

Something like

// import { glob } from "node:fs/promises" // Only works on server level
import { glob } from "glob"
import { Icon } from "#components"

const APPLICATION = "NewApp"
for (const item in glob(`.././assets/${APPLICATION}/*.svg`)) {
  var body = h(Icon, { name: `${APPLICATION}:${item}`, mode: "svg" }).el // Nuxt icon
  var color = body?.querySelector("#color")?.getAttributeNS(null, "fill") || "black"
  console.log( item, color, body)
}