Nuxt/docs/content/2.guide/2.directory-structure/1.plugins.md

166 lines
4.0 KiB
Markdown

---
icon: IconDirectory
title: 'plugins'
head.title: Plugins Directory
---
# Plugins Directory
Nuxt will automatically read the files in your `plugins` directory and load them. You can use `.server` or `.client` suffix in the file name to load a plugin only on the server or client side.
::alert{type=warning}
All plugins in your `plugins/` directory are auto-registered, so you should not add them to your `nuxt.config` separately.
::
## Which Files Are Registered
Only files at the top level of the `plugins/` directory (or index files within any subdirectories) will be registered as plugins.
For example:
```bash
plugins
| - myPlugin.ts
| - myOtherPlugin
| --- supportingFile.ts
| --- componentToRegister.vue
| --- index.ts
```
Only `myPlugin.ts` and `myOtherPlugin/index.ts` would be registered.
## Creating Plugins
The only argument passed to a plugin is [`nuxtApp`](/api/composables/use-nuxt-app).
```ts
export default defineNuxtPlugin(nuxtApp => {
// Doing something with nuxtApp
})
```
## Using Composables Within Plugins
You can use [composables](/guide/directory-structure/composables) within Nuxt plugins:
```ts
export default defineNuxtPlugin((NuxtApp) => {
const foo = useFoo()
})
```
However, keep in mind there are some limitations and differences:
**If a composable depends on another plugin registered later, it might not work.**
**Reason:** Plugins are called in order sequencially and before everything else. You might use a composable that dependants on another plugin which is not called yet.
**If a composable depends on the Vue.js lifecycle, it won't work.**
**Reason:** Normally, Vue.js composables are bound to the current component instance while plugins are only bound to `nuxtApp` instance.
## Automatically Providing Helpers
If you would like to provide a helper on the `NuxtApp` instance, return it from the plugin under a `provide` key. For example:
```ts
export default defineNuxtPlugin(() => {
return {
provide: {
hello: (msg: string) => `Hello ${msg}!`
}
}
})
```
In another file you can use this:
```vue
<template>
<div>
{{ $hello('world') }}
</div>
</template>
<script setup lang="ts">
// alternatively, you can also use it here
const { $hello } = useNuxtApp()
</script>
```
## Typing Plugins
If you return your helpers from the plugin, they will be typed automatically; you'll find them typed for the return of `useNuxtApp()` and within your templates.
::alert
If you need to use a provided helper _within_ another plugin, you can call `useNuxtApp()` to get the typed version. But in general, this should be avoided unless you are certain of the plugins' order.
::
### Advanced
For advanced use-cases, you can declare the type of injected properties like this:
```ts [index.d.ts]
declare module '#app' {
interface NuxtApp {
$hello (msg: string): string
}
}
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$hello (msg: string): string
}
}
export { }
```
## Vue Plugins
If you want to use Vue plugins, like [vue-gtag](https://github.com/MatteoGabriele/vue-gtag) to add Google Analytics tags, you can use a Nuxt plugin to do so.
> There is an Open RFC to make this even easier! See [nuxt/framework#1175](https://github.com/nuxt/framework/discussions/1175)
First, install the plugin you want.
```bash
yarn add --dev vue-gtag-next
```
Then create a plugin file `plugins/vue-gtag.client.js`.
```ts
import VueGtag from 'vue-gtag-next'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(VueGtag, {
property: {
id: 'GA_MEASUREMENT_ID'
}
})
})
```
## Vue Directives
Similarly, you can register a custom Vue directive in a plugin. For example, in `plugins/directive.ts`:
```ts
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.directive('focus', {
mounted (el) {
el.focus()
},
getSSRProps (binding, vnode) {
// you can provide SSR-specific props here
return {}
}
})
})
```
:ReadMore{link="https://vuejs.org/guide/reusability/custom-directives.html"}
:LinkExample{link="/examples/app/plugins"}