nuxt-community / svg-module

Super simple svg loading module for Nuxt.js
MIT License
340 stars 35 forks source link

Can't load SVG using Vite #88

Open kamil-hammouche opened 3 years ago

kamil-hammouche commented 3 years ago

Hello,

I can't manage to load SVG using @nuxtjs/svg. I've added properly the build module in the nuxt.config.js file and they still don't load. I've seen some dev complaining that this might be due to ViteJS, so I aswell added the vite-svg-loader dependency but I have this error:

__vite_ssr_import_0__.createElementVNode is not a function

Here's my nuxt.config.js file

import svgLoader from 'vite-svg-loader'
import { APP_NAME, APP_LANG, APP_ROOT_ID } from "./constants";

export default {
  // Global page headers: https://go.nuxtjs.dev/config-head
  head: {
    title: APP_NAME,
    htmlAttrs: {
      lang: APP_LANG,
    },
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '' },
      { name: 'format-detection', content: 'telephone=no' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },

  globals: {
    id: globalName => APP_ROOT_ID,
  },

  // Global CSS: https://go.nuxtjs.dev/config-css
  css: [
    '@/assets/styles/main.scss',
    '@/assets/styles/variables.scss',
  ],

  // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
  plugins: [
  ],

  // Auto import components: https://go.nuxtjs.dev/config-components
  components: {
    dirs: [
      '~/components',
      '~/components/pages',
      '~/components/ui',
    ],
  },

  // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
  buildModules: [
    // https://go.nuxtjs.dev/eslint
    '@nuxtjs/eslint-module',
    // https://go.nuxtjs.dev/tailwindcss
    '@nuxtjs/tailwindcss',
    '@nuxtjs/svg',
    '@nuxtjs/style-resources',
    'nuxt-vite'
  ],

  // Modules: https://go.nuxtjs.dev/config-modules
  modules: [],

  // Build Configuration: https://go.nuxtjs.dev/config-build
  build: {
    extend(config, ctx) {
      config.module.rules.push({
        test: /\.svg$/,
        loader: 'file-loader',
      });
    },
  },

  styleResources: {
    scss: '@/assets/styles/mixins.scss',
  },

  vite: {
    ssr: false,
    plugins: [svgLoader()],
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@import "@/assets/styles/mixins.scss";',
        },
      },
    },
  },
}

And here's how I load my SVGs :

Icon.vue

<template>
  <component :is="icon"/>
</template>

<script>
import * as icons from "~/assets/images/icons";

export default {
  props: [ 'name' ],
  computed: {
    icon() {
      return icons[this.name]
    }
  },
}
</script>

Usage :

<template>
  <Icon name='add' />
</template>

Best regards,

manuelodelain commented 3 years ago

Duplicate of #86

johannschopplich commented 1 year ago

In Nuxt 3, you don't need svg-module, but can instead create a custom component utilizing Vite's glob import:

<template>
  <span v-if="icon" class="h-[1em] w-[1em]" v-html="icon" />
</template>

<script setup lang="ts">
const props = defineProps<{
  name?: string
}>()

// Auto-load icons
const icons = Object.fromEntries(
  Object.entries(import.meta.glob('~/assets/images/*.svg', { as: 'raw' })).map(
    ([key, value]) => {
      const filename = key.split('/').pop()!.split('.').shift()
      return [filename, value]
    },
  ),
)

// Lazily load the icon
const icon = props.name && (await icons?.[props.name]?.())
</script>