What Causes This Warning?
This warning appears when you declare a local variable or function with the same name as an auto-imported function from Nuxt or Vue. The local declaration shadows the auto-import.
The Problem
<script setup>
// ❌ 'ref' is auto-imported from Vue, but you're declaring a local variable
const ref = document.querySelector('.my-ref')
// ❌ 'useState' is auto-imported, but declared locally
function useState() {
return { count: 0 }
}
// ❌ 'useFetch' shadowed by local function
const useFetch = () => {
return fetch('/api/data')
}
</script>
The Fix
Rename Your Local Declaration
<script setup>
// ✅ Use different names
const elementRef = document.querySelector('.my-ref')
function useLocalState() {
return { count: 0 }
}
const fetchData = () => {
return fetch('/api/data')
}
</script>
Common Naming Conflicts
| Auto-Import | Better Local Name |
|---|---|
ref | elementRef, domRef, inputRef |
useState | useLocalState, useCustomState |
useFetch | fetchData, loadData, apiCall |
computed | calculatedValue, derivedValue |
watch | watchHandler, observer |
useRoute | currentRoute, routeInfo |
useRouter | routerInstance, nav |
Understanding Auto-Imports
Nuxt auto-imports these by default:
From Vue
// Automatically available - don't redeclare!
ref, reactive, computed, watch, watchEffect,
onMounted, onUnmounted, onBeforeMount,
toRef, toRefs, unref, isRef,
shallowRef, triggerRef,
readonly, shallowReactive,
nextTick, provide, inject
From Nuxt
// Automatically available
useAsyncData, useFetch, useLazyFetch,
useState, useError, useRoute, useRouter,
useRuntimeConfig, useAppConfig, useCookie,
useHead, useSeoMeta, useNuxtApp,
navigateTo, abortNavigation, createError,
definePageMeta, defineNuxtComponent
From Your Composables
// composables/useCounter.ts
export function useCounter() { ... }
// Auto-imported everywhere!
// Don't redeclare 'useCounter'
Intentional Shadowing
If you intentionally want to override an auto-import:
<script setup>
// ✅ Explicitly import what you need
import { ref as vueRef } from 'vue'
// Now you can use your own 'ref'
const ref = document.querySelector('.target')
// And still access Vue's ref
const count = vueRef(0)
</script>
Or disable the specific auto-import:
// nuxt.config.ts
export default defineNuxtConfig({
imports: {
// Disable specific auto-imports
disabled: ['ref']
}
})
Best Practices
Prefix DOM References
<script setup>
// ✅ Clear naming for DOM references
const inputEl = ref<HTMLInputElement | null>(null)
const formEl = ref<HTMLFormElement | null>(null)
const containerDiv = ref<HTMLDivElement | null>(null)
</script>
<template>
<form ref="formEl">
<input ref="inputEl" />
<div ref="containerDiv"></div>
</form>
</template>
Prefix Custom Composables
// composables/useAppCounter.ts
// ✅ Prefix to avoid conflicts
export function useAppCounter() {
const count = ref(0)
return { count }
}
// composables/useProjectFetch.ts
// ✅ Project-specific prefix
export function useProjectFetch(url: string) {
return useFetch(url, {
// Custom defaults
})
}
Check Auto-Import List
// nuxt.config.ts
export default defineNuxtConfig({
hooks: {
'imports:extend'(imports) {
console.log('Auto-imports:', imports.map(i => i.name))
}
}
})
Configuring Auto-Imports
Disable All Auto-Imports
// nuxt.config.ts
export default defineNuxtConfig({
imports: {
autoImport: false
}
})
Disable Specific Imports
// nuxt.config.ts
export default defineNuxtConfig({
imports: {
presets: [
{
from: 'vue',
imports: [
// Only import what you explicitly list
'defineComponent',
'computed'
]
}
]
}
})
Add Custom Auto-Imports
// nuxt.config.ts
export default defineNuxtConfig({
imports: {
imports: [
// Add custom imports
{ name: 'myFunction', from: '~/utils/helpers' }
]
}
})
TypeScript Help
Enable strict TypeScript to catch these issues:
// tsconfig.json
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true
}
}
Quick Checklist
- Rename local variables that conflict with auto-imports
- Use descriptive names like
elementRefinstead ofref - Prefix project composables to avoid conflicts
- Check the auto-import list in your project
- Use explicit imports if intentionally overriding
- Enable TypeScript strict mode for better detection