Wardan
Wardan
NNuxt
Created by Wardan on 11/16/2024 in #❓・help
Question about image tag and svgs in production
Hello I am working in Nuxt3 and am fairly new to web dev and very new to Nuxt3 I am trying to learn how to properly use a svg that will work in production. Here is the code that was in my page before moving to a component, it worked in dev and production
<span
class="inline-flex items-center rounded-full border border-primary-300 bg-card-fill px-4 py-3 text-xs font-semibold text-highlight backdrop-blur-sm md:text-base"
>
<img
src="~/assets/images/icons/person.svg"
alt="Person"
class="mr-2 w-3.5 md:w-auto"
/>
Name
</span>
<span
class="inline-flex items-center rounded-full border border-primary-300 bg-card-fill px-4 py-3 text-xs font-semibold text-highlight backdrop-blur-sm md:text-base"
>
<img
src="~/assets/images/icons/person.svg"
alt="Person"
class="mr-2 w-3.5 md:w-auto"
/>
Name
</span>
I have many of these so I moved it to a component, once moving it to a component the svg's broke and no longer loaded. so I just changed it to a more static URL (instead of ~/assets) as shown below However, this only works in dev and not production
<script setup lang="ts">
interface Props {
imgSrc: string;
text: string;
}
defineProps<Props>();
</script>
<template>
<span
class="inline-flex items-center rounded-full border border-primary-300 bg-card-fill px-4 py-3 text-xs font-semibold text-highlight backdrop-blur-sm md:text-base"
>
<img :src="`/_nuxt/assets/images/icons/${imgSrc}`" :alt="text" class="mr-2 w-3.5 md:w-auto" />
<p>{{ text }}</p>
</span>
</template>
<script setup lang="ts">
interface Props {
imgSrc: string;
text: string;
}
defineProps<Props>();
</script>
<template>
<span
class="inline-flex items-center rounded-full border border-primary-300 bg-card-fill px-4 py-3 text-xs font-semibold text-highlight backdrop-blur-sm md:text-base"
>
<img :src="`/_nuxt/assets/images/icons/${imgSrc}`" :alt="text" class="mr-2 w-3.5 md:w-auto" />
<p>{{ text }}</p>
</span>
</template>
I then tried to changed the img src to
"`~/assets/images/icons/${imgSrc}`"
"`~/assets/images/icons/${imgSrc}`"
just to try it in production (or dev) but it did not work and it would show that path if I inspected I googled and search for a solution and did not find one. maybe I am not understanding something properly I tried this chatgpt solution
<script setup lang="ts">
interface Props {
imgSrc: string;
text: string;
}

defineProps<Props>();

// Dynamically resolve the image
const resolveImg = (imgSrc: string) => {
return new URL(`~/assets/images/icons/${imgSrc}`, import.meta.url).href;
};
</script>

<template>
<span
class="inline-flex items-center rounded-full border border-primary-300 bg-card-fill px-4 py-3 text-xs font-semibold text-highlight backdrop-blur-sm md:text-base"
>
<img :src="resolveImg(imgSrc)" :alt="text" class="mr-2 w-3.5 md:w-auto" />
<p>{{ text }}</p>
</span>
</template>
<script setup lang="ts">
interface Props {
imgSrc: string;
text: string;
}

defineProps<Props>();

// Dynamically resolve the image
const resolveImg = (imgSrc: string) => {
return new URL(`~/assets/images/icons/${imgSrc}`, import.meta.url).href;
};
</script>

<template>
<span
class="inline-flex items-center rounded-full border border-primary-300 bg-card-fill px-4 py-3 text-xs font-semibold text-highlight backdrop-blur-sm md:text-base"
>
<img :src="resolveImg(imgSrc)" :alt="text" class="mr-2 w-3.5 md:w-auto" />
<p>{{ text }}</p>
</span>
</template>
It worked in dev but not production, when inspecting I'd get this URL
<img src="file:///var/www/SITENAME/live/nuxt_app/.output/server/assets/images/icons/home.svg" alt="Address" class="mr-2 w-3.5 md:w-auto">
<img src="file:///var/www/SITENAME/live/nuxt_app/.output/server/assets/images/icons/home.svg" alt="Address" class="mr-2 w-3.5 md:w-auto">
I then tried a second chat gpt solution which works, but feels very hacky and I'd like to learn how to properly handle this The second working chatgpt solution was to create a map of the images and use them in the component via the key
import attachMoney from '~/assets/images/icons/attach_money.svg';

export const icons = {
attachMoney,
... // more values
};
import attachMoney from '~/assets/images/icons/attach_money.svg';

export const icons = {
attachMoney,
... // more values
};
I have not tried sticking the svg's in the public folder but I also do want them to accessible at a static URL which is why I havent tried this. Some insight/explanation on how to properly do this would be fantastic and appreciated.
15 replies