16

I have a Vue.js app that relies on Vite. In this app, I have two static files that I need to copy to my dist directory: favicon.ico and manifest.json. My vite.config.js file looks like this:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig(({command, mode }) => {
  return {
    assetsDir: 'res',
    plugins: [vue()],
    publicDir: 'dist',
    root: 'src',
    build: {
      emptyOutDir: true,
      outDir: '../dist'
    }
  }
});

My directory structure looks like this:

/
  /dist
  /src
    /assets
      favicon.ico
      manifest.json
    /res
      /css
        theme.css
    App.vue
    main.js
    index.html
  package.json
  README.md
  vite.config.js

When I compile my program using npm run build, I can see a file named index.html that gets created in the dist directory. However, I have been unsuccessful in getting the favicon.ico and manifest.json file copied to the dist directory, which is what I need. I tried adding publicDir: 'assets' to the build options. However, that didn't work. I also tried creating a public directory under the src directory in an effort to follow along with this documentation. However, that did not move the files to the directory. What am I doing wrong?

Dev
  • 921
  • 4
  • 14
  • 31

1 Answers1

27

Reason: The public (vite option) directory is relative to your root (vite option) directory.

So, as you specified root: 'src' and publicDir: 'dist' then your public dir is ./src/dist

Illustration of the folder tree based on your vite.config.js :

enter image description here

More information below


If you have assets that are :

  • Never referenced in source code (e.g. favicon.ico)
  • Must retain the exact same file name (without hashing)
  • ...or you simply don't want to have to import an asset first just to get its URL

Then the doc say:

You can place the asset in a special public directory under your project root. Assets in this directory will be served at root path / during dev, and copied to the root of the dist directory as-is.

This mean that if you simply place the favicon.ico under the /public dir it will be copied to the dist dir after build.

The note above is true if you have a vanilla vite config, but if you change the publicDir options of vite config then read below after the illustration.

enter image description here

favicon.ico copied in dist after vite build


If you set a custom publicDir :

As said on the top of this answer, the public (vite option) directory is relative to your root (vite option) directory.

So, if for example you set root: './src' and set publicDir: 'mypublic' then the public dir will be ./src/mypublic.

flydev
  • 4,327
  • 2
  • 31
  • 36
  • 1
    I added a `public` directory under the `src` directory and at the same level as the `src` directory. Still, the contents of the `public` directory are _not_ copied to the `dist` directory. I suspect it has something to do with either the `assetsDir` value or `root` value, but I haven't confirmed. Regardless, `favicon.ico` and `manifest.json` are not getting copied to the `dist` directory. – Dev Oct 12 '21 at 13:38
  • 1
    Thank you so much for this. I have been digging through Vite's documentation forever looking for this information and either its not there anymore or I'm just bad at reading – dmscs Dec 23 '21 at 22:30
  • Love the emojis in this answer – Elijah Mock Jul 11 '23 at 01:23