2021-10-11 12:57:54 +00:00
---
icon: IconDirectory
title: 'components'
head.title: Components directory
---
# Components directory
2022-02-07 10:16:45 +00:00
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)).
2021-10-14 15:21:54 +00:00
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]
< template >
< div >
< TheHeader / >
2021-11-19 11:36:25 +00:00
< slot / >
2021-10-14 15:21:54 +00:00
< TheFooter / >
< / div >
< / template >
```
## Component Names
2021-11-21 12:31:44 +00:00
If you have a component in nested directories such as:
2021-10-14 15:21:54 +00:00
```bash
| components/
--| base/
----| foo/
------| Button.vue
```
2021-11-21 12:31:44 +00:00
... 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:
2021-10-14 15:21:54 +00:00
```html
< BaseFooButton / >
```
::alert
2021-11-21 12:31:44 +00:00
For clarity, it is recommended that the component's file name matches its name. (So, in the example above, you could rename `Button.vue` to be `BaseFooButton.vue` .)
2021-10-14 15:21:54 +00:00
::
## Dynamic Imports
2021-11-21 12:31:44 +00:00
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.
2021-10-14 15:21:54 +00:00
```html{}[layouts/default.vue]
< template >
< div >
< TheHeader / >
2021-11-19 11:36:25 +00:00
< slot / >
2021-10-14 15:21:54 +00:00
< LazyTheFooter / >
< / div >
< / template >
```
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]
< template >
< div >
< h1 > Mountains< / h1 >
< LazyMountainsList v-if = "show" / >
< button v-if = "!show" @click =" show = true" > Show List</ button >
< / div >
< / template >
< script >
export default {
data() {
return {
show: false
}
}
}
< / script >
```
2021-11-15 12:00:14 +00:00
## `<ClientOnly>` Component
2021-11-21 12:31:44 +00:00
Nuxt provides the `<ClientOnly>` 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.
2021-11-15 12:00:14 +00:00
```html{}[pages/example.vue]
< template >
< div >
< Sidebar / >
< ClientOnly >
<!-- this component will only be rendered on client - side -->
< Comments / >
< / ClientOnly >
< / div >
< / template >
```
2021-11-21 12:31:44 +00:00
Use a slot as fallback until `<ClientOnly>` is mounted on client side.
2021-11-15 12:00:14 +00:00
```html{}[pages/example.vue]
< template >
< div >
< Sidebar / >
< ClientOnly >
2021-11-21 12:31:44 +00:00
<!-- this component will only be rendered on client side -->
2021-11-15 12:00:14 +00:00
< Comments / >
< template #fallback >
2021-11-21 12:31:44 +00:00
<!-- this will be rendered on server side -->
2021-11-15 12:00:14 +00:00
< p > Loading comments...< / p >
< / template >
< / ClientOnly >
< / div >
< / template >
```
2021-10-14 15:21:54 +00:00
## Library Authors
Making Vue component libraries with automatic tree-shaking and component registration is super easy ✨
You can use the `components:dirs` hook to easily 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 { join } from 'pathe'
2021-11-11 13:58:08 +00:00
import { defineNuxtModule } from '@nuxt/kit'
2021-10-14 15:21:54 +00:00
export default defineNuxtModule({
hooks: {
'components:dirs'(dirs) {
// Add ./components dir to the list
dirs.push({
path: join(__dirname, 'components'),
prefix: 'awesome'
})
}
}
})
```
2021-11-21 12:31:44 +00:00
That's it! Now in your project, you can import your ui library as a Nuxt module in your `nuxt.config` file:
2021-10-14 15:21:54 +00:00
```js
export default {
buildModules: ['awesome-ui/nuxt']
}
```
2021-11-21 12:31:44 +00:00
... and directly use the module components (prefixed with `awesome-` ) in our `pages/index.vue` :
2021-10-14 15:21:54 +00:00
```vue
< template >
< div >
My < AwesomeButton > UI button< / AwesomeButton > !
< awesome-alert > Here's an alert!< / awesome-alert >
< / div >
< / template >
```
It will automatically import the components only if used and also support HMR when updating your components in `node_modules/awesome-ui/components/` .