6

I'm experience a weird situation,

I have a "standard" Nuxt v3 project that comes with vite

Works

<img src="~/assets/img/image.png">
<img src="~/assets/video/video.mp4">

Does not work

<img :src="require('~/assets/img/image.png')">
<img :src="require('~/assets/video/video.mp4')">

Note that the image path is the same so it does exist, the error I'm getting is:

Cannot find module '@/assets/img/image.png' Require stack

The docs don't mention anything that has to be done in order to achieve it

enter image description here

Is there anything I should do?

Toni Michel Caubet
  • 19,333
  • 56
  • 202
  • 378
  • A similar question got asked this morning, here is [my comment](https://stackoverflow.com/questions/74681067/dynamically-add-an-img-in-nuxt-3#comment131822693_74681067). Also, you're reading which documentation here? Looks like the one for Nuxt2 (with Webpack4). Since you're using Vite, please follow my comment. – kissu Dec 05 '22 at 13:32
  • hello @kissu The official docs https://nuxtjs.org/docs/ might be from the nuxt 2 version, do you have the link of the version 3? I don't think I understand your links so I would like to go through it – Toni Michel Caubet Dec 05 '22 at 14:04
  • Here you have the docs for Nuxt3: https://nuxt.com/ – kissu Dec 05 '22 at 14:04
  • thanks! but it doesn't mention any of that.. https://nuxt.com/docs/getting-started/assets I'm trying with: this code `videoUrl.value = new URL(`/src/assets/video/hero-video-double.${props.isIOS ? 'mp4' : 'webm'}`, import.meta.url)` and that string prints out `/src/assets/video/hero-video-double.webm` but `videoUrl` is `http://localhost:3333/undefined` any thougts? – Toni Michel Caubet Dec 05 '22 at 14:11
  • Please read my [initial comment](https://stackoverflow.com/questions/74688433/why-loading-dynamically-assets-fails-on-nuxt-v3?noredirect=1#comment131824989_74688433) Everything is written down there. – kissu Dec 05 '22 at 14:12
  • yes, I'm trying with option 3 of that SO answer's link, but is not explaining why to use like that and is failing to me and I don't know where to get more info.. – Toni Michel Caubet Dec 05 '22 at 14:16
  • Use the `2022 answer: Vite 2.8.6 + Vue 3.2.31` one. – kissu Dec 05 '22 at 14:17
  • I'll give it a shot, although I'm trying to load a video ant that answer is trying to load `().href` – Toni Michel Caubet Dec 05 '22 at 14:31

1 Answers1

8

In Vite, the require function is not used. Instead, you should use the import statement (Vite is the default module bundler for Nuxt 3.)

There are two problems:

  1. After the build, Nuxt will change the assets directory and the file names.
  2. Aliases do not convert to the absolute path when used dynamically.

So you can't even do this even:

<img :src="`_nuxt/assets/img/${imageName}`">

During development mode, it works, but not after the build.

Solution 1

You can import images and then use them like this:

<script lang="ts" setup>
//@ts-ignore
import image1 from "../assets/images/image1.jpg";
//@ts-ignore
import image2 from "../assets/images/image2.jpg";
//@ts-ignore
import image3 from "../assets/images/image3.jpg";

const images = [ image1, image2, image ]
</script>

Solution 2

I found this way:

<script>
const glob = import.meta.glob("~/assets/images/how-to-use/*", {
  eager: true,
});

const getImageAbsolutePath = (imageName: string): string => {
  return glob[`/assets/images/how-to-use/${imageName}`]["default"];
};
</script>

You can pass your imageName (don't forget the extension) to this function and retrieve the absolute path.

This approach continues to function correctly even after the build.

Solution 3

you can put your images in the public directory

learn more: https://nuxt.com/docs/getting-started/assets/#public-directory

The public/ directory content is served at the server root as-is.

sadeq shahmoradi
  • 1,395
  • 1
  • 6
  • 22