Vue.js 2: Vue cannot find files from /assets folder (v-for)

21,839

Solution 1

Vue.js has a public folder. If you are using the Vue CLI, it should have created a public folder for you, you have to place any assets in this folder. Read more about it in the official Vue.js documentation.

Example folder structure:

/api
/public
/public/assets
/public/favicon.ico
/public/index.html
/src
index.js
app.json

etc...

In public you could put static assets such as images, fonts, favicon, robots.txt, sitemap.xml, etc.

Then to link to these static assets you'd use:

In your template HTML:

<img src="/assets/some-image.svg" alt="Example" />

Or in your component JS:

array: [
        {
          iconUrl: '/assets/some-image-1.svg',
          label: 'Some Label'
        }
      ]

Otherwise you'd have to use require since it is being pulled from the src folder, as someone else has already said. But there probably wouldn't be a real reason to have them in there, so using /public/ folder is recommended.

Solution 2

You need the require because your resource is bundled on the client.

If you want you resource on the server, put it in the public folder instead.

Another issue we often see is when your component in the components folder. If so, try:

default: require('../assets/p1.jpg')

Solution 3

I think this question is a common problem that you can search for. The solution is to put the resource file in the static directory. The files in the asset folder will be processed by webpack, so there is no problem in html module ,buy there is a problem in the code module.

Share:
21,839
Stephen
Author by

Stephen

I am a front-end developer.

Updated on December 17, 2020

Comments

  • Stephen
    Stephen over 3 years

    I am using Vue-cli 3 with Webpack, and my folder structure looks like this:

    /public
    /src
       /assets
          p1.jpg
          p2.jpg
    App.vue
    main.js
    

    I read in several places that in order for Webpack to know where your /assets are, you should use require() if you are in Javascript land.

    I have determined that this code works:

    <template>
        <div>
            <ul>
                <li v-for="photo in photos" :key="photo.id">
                    <img :src="photo.imageUrls.default" />
                </li>
            </ul>
        </div>
    </template>
    
    
    <script>
        /* For webpack to resolve URLs in javascript during the build, you need the require() function */
        export default {
            data() {
                return {
                    photos: [
                        {
                            id: 1,
                            caption: 'P1',
                            series: '',
                            notes: '',
                            imageUrls: {
                                default: require('./assets/p1.jpg')
                            }
                        },
                        {
                            id: 2,
                            caption: 'P2',
                            series: '',
                            notes: '',
                            imageUrls: {
                                default: require('./assets/p2.jpg')
                            }
                        }
                    ]
                }
            }
        }
    </script>
    

    But, this does not work. I am seeing an error in the console: "Error: Cannot find module './assets/p1.jpg'"

    <template>
            <div>
                <ul>
                    <li v-for="photo in photos" :key="photo.id">
                        <img :src="imagePath(photo)" />
                    </li>
                </ul>
            </div>
    </template>
    
    
    <script>
        /* For webpack to resolve URLs in javascript during the build, you need the require() function */
        export default {
            data() {
                return {
                    photos: [
                        {
                            id: 1,
                            caption: 'P1',
                            series: '',
                            notes: '',
                            imageUrls: {
                                default: './assets/p1.jpg'
                            }
                        },
                        {
                            id: 2,
                            caption: 'P2',
                            series: '',
                            notes: '',
                            imageUrls: {
                                default: './assets/p2.jpg'
                            }
                        }
                    ]
                }
            },
            methods: {
                imagePath(photo) {
                    return require(photo.imageUrls.default);
                }
            }
        }
    </script>
    

    Is there anybody who can help explain what is wrong in the second example? I wish to avoid putting require() calls into the data, as that data could come from a server, and it seems weird to me to put a require() call in the data. Thanks.

    EDIT: Per Edgar's advice below, since my images are part of the server and not the app, I can just put them into a folder in the /public folder, and not deal with require() at all.

  • Stephen
    Stephen over 5 years
    Edgar: Thanks for your input. These images would be on the server and are not part of the app itself. I didn't realize that is what the /public folder was for. I moved the images there, and was able to avoid using require()
  • Stephen
    Stephen over 5 years
    Steven: These images are on the server, so I can move them into some folder in the /public folder. I can remove the require() call entirely. Thanks!
  • Edgar Quintero
    Edgar Quintero over 5 years
    Cool - glad I could help :)
  • Eliezer Veras Vargas
    Eliezer Veras Vargas over 2 years
    Hey man! Thanks so much. If it was possible I would give 50 upvotes, there is a bunch of stupid answers out there for these questions. You are the only one explaining how this works.