Drop a .vue Into components/, Use It Anywhere
Auto-Imported Components
Files in components/ are auto-imported by filename. Folder prefixes become name prefixes, and a Lazy prefix defers loading.
What you'll learn
- Add components/MyButton.vue and use it without imports
- Use folder-prefixed names like UiCard
- Lazy-load heavy components with the Lazy prefix
Nuxt scans the components/ directory and registers every .vue file globally. You never write import MyButton from '~/components/MyButton.vue' — you just use the tag.
A First Auto-Imported Component
<!-- components/MyButton.vue -->
<script setup lang="ts">
defineProps<{ label: string }>()
</script>
<template>
<button class="btn">{{ label }}</button>
</template> <!-- pages/index.vue -->
<template>
<MyButton label="Click me" />
</template> No import, no registration step. Save, refresh, done.
Folder Prefixes Become Name Prefixes
To avoid name collisions in larger apps, Nuxt joins folder names with the file name in PascalCase:
components/
├─ Button.vue → <Button>
├─ ui/
│ ├─ Card.vue → <UiCard>
│ └─ Modal.vue → <UiModal>
└─ form/
└─ TextInput.vue → <FormTextInput> You get namespacing for free — no Ui prefix needed in the filenames.
Lazy Loading with the Lazy Prefix
Prefix any auto-imported component with Lazy in markup, and Nuxt code-splits it into its own chunk:
<template>
<button @click="show = true">Open chart</button>
<LazyHeavyChart v-if="show" :data="data" />
</template>
<script setup lang="ts">
const show = ref(false)
const data = [/* ... */]
</script> The chart bundle is only fetched when show flips to true. This is the cheapest performance win in a Nuxt app.