Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Nuxt 3.x reference covering SSR, file-based routing, auto-imports, server routes, and Nitro deployment.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/features-components-autoimport.md
1---2name: components-auto-imports3description: Auto-imported components, lazy loading, and hydration strategies4---56# Components Auto-imports78Nuxt automatically imports Vue components from `app/components/` directory.910## Basic Auto-imports1112```13components/14├── Button.vue → <Button />15├── Card.vue → <Card />16└── AppHeader.vue → <AppHeader />17```1819```vue20<template>21<!-- No imports needed -->22<AppHeader />23<Card>24<Button>Click me</Button>25</Card>26</template>27```2829## Naming Conventions3031### Nested Directory Names3233Component names include directory path:3435```36components/37├── base/38│ └── Button.vue → <BaseButton />39├── form/40│ ├── Input.vue → <FormInput />41│ └── Select.vue → <FormSelect />42└── ui/43└── modal/44└── Dialog.vue → <UiModalDialog />45```4647### Disable Path Prefix4849```ts50// nuxt.config.ts51export default defineNuxtConfig({52components: [53{54path: '~/components',55pathPrefix: false, // Use filename only56},57],58})59```6061With `pathPrefix: false`:62```63components/base/Button.vue → <Button />64```6566## Lazy Loading6768Prefix with `Lazy` for dynamic imports:6970```vue71<script setup lang="ts">72const showChart = ref(false)73</script>7475<template>76<!-- Component code loaded only when rendered -->77<LazyHeavyChart v-if="showChart" />78<button @click="showChart = true">Show Chart</button>79</template>80```8182Benefits:83- Reduces initial bundle size84- Code-splits component into separate chunk85- Loads on-demand8687## Lazy Hydration Strategies8889Control when lazy components become interactive:9091### `hydrate-on-visible`9293Hydrate when component enters viewport:9495```vue96<template>97<LazyComments hydrate-on-visible />98</template>99```100101### `hydrate-on-idle`102103Hydrate when browser is idle:104105```vue106<template>107<LazyAnalytics hydrate-on-idle />108</template>109```110111### `hydrate-on-interaction`112113Hydrate on user interaction:114115```vue116<template>117<!-- Hydrates on click, focus, or pointerenter -->118<LazyDropdown hydrate-on-interaction />119120<!-- Specific event -->121<LazyTooltip hydrate-on-interaction="mouseover" />122</template>123```124125### `hydrate-on-media-query`126127Hydrate when media query matches:128129```vue130<template>131<LazyMobileMenu hydrate-on-media-query="(max-width: 768px)" />132</template>133```134135### `hydrate-after`136137Hydrate after delay (milliseconds):138139```vue140<template>141<LazyAds :hydrate-after="3000" />142</template>143```144145### `hydrate-when`146147Hydrate on condition:148149```vue150<script setup lang="ts">151const isReady = ref(false)152</script>153154<template>155<LazyEditor :hydrate-when="isReady" />156</template>157```158159### `hydrate-never`160161Never hydrate (static only):162163```vue164<template>165<LazyStaticFooter hydrate-never />166</template>167```168169### Hydration Event170171```vue172<template>173<LazyChart hydrate-on-visible @hydrated="onChartReady" />174</template>175176<script setup>177function onChartReady() {178console.log('Chart is now interactive')179}180</script>181```182183## Client/Server Components184185### Client-only (`.client.vue`)186187```188components/189└── BrowserChart.client.vue190```191192```vue193<template>194<!-- Only rendered in browser -->195<BrowserChart />196</template>197```198199### Server-only (`.server.vue`)200201```202components/203└── ServerMarkdown.server.vue204```205206```vue207<template>208<!-- Rendered on server, not hydrated -->209<ServerMarkdown :content="markdown" />210</template>211```212213Requires experimental flag:214215```ts216// nuxt.config.ts217export default defineNuxtConfig({218experimental: {219componentIslands: true,220},221})222```223224### Paired Components225226```227components/228├── Comments.client.vue # Browser version229└── Comments.server.vue # SSR version230```231232Server version renders during SSR, client version takes over after hydration.233234## Dynamic Components235236```vue237<script setup lang="ts">238import { SomeComponent } from '#components'239240const dynamicComponent = resolveComponent('MyButton')241</script>242243<template>244<component :is="dynamicComponent" />245<component :is="SomeComponent" />246</template>247```248249## Direct Imports250251Bypass auto-imports when needed:252253```vue254<script setup lang="ts">255import { LazyMountainsList, NuxtLink } from '#components'256</script>257```258259## Custom Directories260261```ts262// nuxt.config.ts263export default defineNuxtConfig({264components: [265{ path: '~/components/ui', prefix: 'Ui' },266{ path: '~/components/forms', prefix: 'Form' },267'~/components', // Default, should come last268],269})270```271272## Global Components273274Register globally (creates async chunks):275276```ts277// nuxt.config.ts278export default defineNuxtConfig({279components: {280global: true,281dirs: ['~/components'],282},283})284```285286Or use `.global.vue` suffix:287288```289components/290└── Icon.global.vue → Available globally291```292293## Disabling Component Auto-imports294295```ts296// nuxt.config.ts297export default defineNuxtConfig({298components: {299dirs: [], // Disable auto-imports300},301})302```303304## Library Authors305306Register components from npm package:307308```ts309// my-ui-lib/nuxt.ts310import { addComponentsDir, createResolver, defineNuxtModule } from '@nuxt/kit'311312export default defineNuxtModule({313setup() {314const resolver = createResolver(import.meta.url)315316addComponentsDir({317path: resolver.resolve('./components'),318prefix: 'MyUi',319})320},321})322```323324<!--325Source references:326- https://nuxt.com/docs/directory-structure/app/components327- https://nuxt.com/docs/guide/concepts/auto-imports#auto-imported-components328-->329