--- icon: IconDirectory title: 'components' head.title: Components directory --- # Components directory The `components/` directory is where you put all your Vue components which can then be imported inside your pages or other components ([learn more](https://vuejs.org/guide/essentials/component-basics.html#components-basics)). Nuxt automatically imports any components in your `components/` directory (along with components that are registered by any modules you may be using). ```bash | components/ --| TheHeader.vue --| TheFooter.vue ``` ```html{}[layouts/default.vue] ``` ## Component Names If you have a component in nested directories such as: ```bash | components/ --| base/ ----| foo/ ------| Button.vue ``` ... then the component's name will be based on its own path directory and filename, with duplicate segments being removed. Therefore, the component's name will be: ```html ``` ::alert For clarity, we recommend that the component's filename matches its name. (So, in the example above, you could rename `Button.vue` to be `BaseFooButton.vue`.) :: ## Dynamic components If you want to use the Vue `` syntax, then you will need to use the `resolveComponent` helper provided by Vue. For example: ```vue ``` ::alert{type=warning} If you are using `resolveComponent` to handle dynamic components, make sure not to insert anything but the name of the component, which must be a string and not a variable. :: Alternatively, though not recommended, you can register all your components globally, which will create async chunks for all your components and make them available throughout your application. ```diff import { defineNuxtConfig } from 'nuxt' export default defineNuxtConfig({ components: { + global: true, + dirs: ['~/components'] }, }) ``` ::alert{type=info} The `global` option can also be set per component directory. :: ## Dynamic Imports To dynamically import a component (also known as lazy-loading a component) all you need to do is add the `Lazy` prefix to the component's name. ```html{}[layouts/default.vue] ``` This is particularly useful if the component is not always needed. By using the `Lazy` prefix you can delay loading the component code until the right moment, which can be helpful for optimizing your JavaScript bundle size. ```html{}[pages/index.vue] ``` ## Direct imports You can also explicitly import components from `#components` if you want or need to bypass Nuxt's auto-importing functionality. ```html{}[pages/index.vue] ``` ## `` Component Nuxt provides the `` component for purposely rendering a component only on client side. To import a component only on the client, register the component in a client-side only plugin. ```html{}[pages/example.vue] ``` Use a slot as fallback until `` is mounted on client side. ```html{}[pages/example.vue] ``` ## Library Authors Making Vue component libraries with automatic tree-shaking and component registration is super easy ✨ You can use the `components:dirs` hook to extend the directory list without requiring user configuration in your Nuxt module. Imagine a directory structure like this: ```bash | node_modules/ ---| awesome-ui/ ------| components/ ---------| Alert.vue ---------| Button.vue ------| nuxt.js | pages/ ---| index.vue | nuxt.config.js ``` Then in `awesome-ui/nuxt.js` you can use the `components:dirs` hook: ```js import { defineNuxtModule } from '@nuxt/kit' import { fileURLToPath } from 'node:url' export default defineNuxtModule({ hooks: { 'components:dirs'(dirs) { // Add ./components dir to the list dirs.push({ path: fileURLToPath(new URL('./components', import.meta.url)), prefix: 'awesome' }) } } }) ``` That's it! Now in your project, you can import your UI library as a Nuxt module in your `nuxt.config` file: ```js export default { modules: ['awesome-ui/nuxt'] } ``` ... and directly use the module components (prefixed with `awesome-`) in our `pages/index.vue`: ```vue ``` It will automatically import the components only if used and also support HMR when updating your components in `node_modules/awesome-ui/components/`. :LinkExample{link="/examples/auto-imports/components"}