What Causes This Error?
This error occurs when you try to configure Vite’s publicDir option directly in the Nuxt config. Nuxt manages this setting and provides its own way to configure it.
The Problem
// nuxt.config.ts
export default defineNuxtConfig({
vite: {
// ❌ Wrong - can't configure publicDir directly
publicDir: './assets/public'
}
})
The Fix
Use dir.public
// nuxt.config.ts
export default defineNuxtConfig({
// ✅ Correct - use Nuxt's dir option
dir: {
public: 'public' // Default value
}
})
Custom Public Directory
Change Location
// nuxt.config.ts
export default defineNuxtConfig({
dir: {
public: 'static' // Use 'static' instead of 'public'
}
})
Then structure:
my-nuxt-app/
├── static/ ← Custom public directory
│ ├── favicon.ico
│ ├── robots.txt
│ └── images/
├── nuxt.config.ts
└── ...
Multiple Locations (Not Directly Supported)
If you need files from multiple locations:
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
publicAssets: [
{
dir: 'public',
baseURL: '/'
},
{
dir: 'assets/static',
baseURL: '/static'
}
]
}
})
All dir Options
// nuxt.config.ts
export default defineNuxtConfig({
dir: {
// All available directory options
assets: 'assets', // CSS, images for build
layouts: 'layouts', // Layout components
middleware: 'middleware',
modules: 'modules',
pages: 'pages',
plugins: 'plugins',
public: 'public', // Static files (served as-is)
static: 'public' // Alias for public (Nuxt 2 compat)
}
})
Understanding public vs assets
public/ Directory
- Files served as-is at root URL
- Not processed by bundler
- Use for:
robots.txt,favicon.ico,sitemap.xml - Access:
/robots.txt→public/robots.txt
public/
├── robots.txt → /robots.txt
├── favicon.ico → /favicon.ico
└── images/
└── logo.png → /images/logo.png
assets/ Directory
- Processed by Vite/bundler
- Fingerprinted for caching
- Use for: Images, CSS, fonts referenced in code
- Import in code:
import logo from '~/assets/logo.png'
assets/
├── css/
│ └── main.css → import '~/assets/css/main.css'
└── images/
└── logo.png → import logo from '~/assets/images/logo.png'
Nitro Static Assets
For production deployment:
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
publicAssets: [
{
dir: 'public',
maxAge: 60 * 60 * 24 * 365 // 1 year cache
}
]
}
})
Common Directory Structures
Default
my-nuxt-app/
├── public/ ← Static files
├── assets/ ← Processed assets
├── pages/
├── components/
└── nuxt.config.ts
Custom (src Directory)
// nuxt.config.ts
export default defineNuxtConfig({
srcDir: 'src',
dir: {
public: '../public' // Relative to srcDir
}
})
my-nuxt-app/
├── public/ ← Static files (outside src)
├── src/
│ ├── pages/
│ ├── components/
│ └── assets/
└── nuxt.config.ts
Migration from Nuxt 2
// Nuxt 2
export default {
dir: {
static: 'static' // Called 'static' in Nuxt 2
}
}
// Nuxt 3
export default defineNuxtConfig({
dir: {
public: 'static' // Now called 'public', but can use 'static' folder
}
})
Quick Checklist
- Use
dir.publicinstead ofvite.publicDir - Public files go in
public/directory - Processed assets go in
assets/directory - Use
nitro.publicAssetsfor advanced configuration - Path is relative to project root (or srcDir)