# Source: https://nuxt.com/raw/docs/3.x/api/kit/plugins.md

# Source: https://nuxt.com/raw/docs/3.x/guide/best-practices/plugins.md

# Source: https://nuxt.com/raw/docs/3.x/directory-structure/plugins.md

# Source: https://nuxt.com/raw/docs/4.x/api/kit/plugins.md

# Source: https://nuxt.com/raw/docs/4.x/guide/best-practices/plugins.md

# Source: https://nuxt.com/raw/docs/4.x/directory-structure/app/plugins.md

# plugins

> Nuxt has a plugins system to use Vue plugins and more at the creation of your Vue application.

Nuxt automatically reads the files in the `app/plugins/` directory and loads them at the creation of the Vue application.

<note>

All plugins inside are auto-registered, you don't need to add them to your `nuxt.config` separately.

</note>

<note>

You can use `.server` or `.client` suffix in the file name to load a plugin only on the server or client side.

</note>

## Registered Plugins

Only files at the top level of the directory (or index files within any subdirectories) will be auto-registered as plugins.

```bash [Directory structure]
-| plugins/
---| foo.ts      // scanned
---| bar/
-----| baz.ts    // not scanned
-----| foz.vue   // not scanned
-----| index.ts  // currently scanned but deprecated
```

Only `foo.ts` and `bar/index.ts` would be registered.

To add plugins in subdirectories, you can use the [`app/plugins`](/docs/4.x/api/nuxt-config#plugins-1) option in `nuxt.config.ts`:

```ts [nuxt.config.ts]twoslash
export default defineNuxtConfig({
  plugins: [
    '~/plugins/bar/baz',
    '~/plugins/bar/foz',
  ],
})
```

## Creating Plugins

The only argument passed to a plugin is [`nuxtApp`](/docs/4.x/api/composables/use-nuxt-app).

```ts [plugins/hello.ts]twoslash
export default defineNuxtPlugin((nuxtApp) => {
  // Doing something with nuxtApp
})
```

### Object Syntax Plugins

It is also possible to define a plugin using an object syntax, for more advanced use cases. For example:

```ts [plugins/hello.ts]twoslash
export default defineNuxtPlugin({
  name: 'my-plugin',
  enforce: 'pre', // or 'post'
  async setup (nuxtApp) {
    // this is the equivalent of a normal functional plugin
  },
  hooks: {
    // You can directly register Nuxt app runtime hooks here
    'app:created' () {
      const nuxtApp = useNuxtApp()
      // do something in the hook
    },
  },
  env: {
    // Set this value to `false` if you don't want the plugin to run when rendering server-only or island components.
    islands: true,
  },
})
```

<video-accordion title="Watch a video from Alexander Lichter about the Object Syntax for Nuxt plugins" video-id="2aXZyXB1QGQ">



</video-accordion>

<note>

If you are using the object-syntax, the properties are statically analyzed to produce a more optimized build. So you should not define them at runtime. <br />


For example, setting `enforce: import.meta.server ? 'pre' : 'post'` would defeat any future optimization Nuxt is able to do for your plugins.
Nuxt does statically pre-load any hook listeners when using object-syntax, allowing you to define hooks without needing to worry about order of plugin registration.

</note>

## Registration Order

You can control the order in which plugins are registered by prefixing with 'alphabetical' numbering to the file names.

```bash [Directory structure]
plugins/
 | - 01.myPlugin.ts
 | - 02.myOtherPlugin.ts
```

In this example, `02.myOtherPlugin.ts` will be able to access anything that was injected by `01.myPlugin.ts`.

This is useful in situations where you have a plugin that depends on another plugin.

<note>

In case you're new to 'alphabetical' numbering, remember that filenames are sorted as strings, not as numeric values. For example, `10.myPlugin.ts` would come before `2.myOtherPlugin.ts`. This is why the example prefixes single digit numbers with `0`.

</note>

## Loading Strategy

### Parallel Plugins

By default, Nuxt loads plugins sequentially. You can define a plugin as `parallel` so Nuxt won't wait until the end of the plugin's execution before loading the next plugin.

```ts [plugins/my-plugin.ts]twoslash
export default defineNuxtPlugin({
  name: 'my-plugin',
  parallel: true,
  async setup (nuxtApp) {
    // the next plugin will be executed immediately
  },
})
```

### Plugins With Dependencies

If a plugin needs to wait for another plugin before it runs, you can add the plugin's name to the `dependsOn` array.

```ts [plugins/depending-on-my-plugin.ts]twoslash
export default defineNuxtPlugin({
  name: 'depends-on-my-plugin',
  dependsOn: ['my-plugin'],
  async setup (nuxtApp) {
    // this plugin will wait for the end of `my-plugin`'s execution before it runs
  },
})
```

## Using Composables

You can use [composables](/docs/4.x/directory-structure/app/composables) as well as [utils](/docs/4.x/directory-structure/app/utils) within Nuxt plugins:

```ts [app/plugins/hello.ts]
export default defineNuxtPlugin((nuxtApp) => {
  const foo = useFoo()
})
```

However, keep in mind there are some limitations and differences:

<important>

**If a composable depends on another plugin registered later, it might not work.** <br />



Plugins are called in order sequentially and before everything else. You might use a composable that depends on another plugin which has not been called yet.

</important>

<important>

**If a composable depends on the Vue.js lifecycle, it won't work.** <br />



Normally, Vue.js composables are bound to the current component instance while plugins are only bound to [`nuxtApp`](/docs/4.x/api/composables/use-nuxt-app) instance.

</important>

## Providing Helpers

If you would like to provide a helper on the [`NuxtApp`](/docs/4.x/api/composables/use-nuxt-app) instance, return it from the plugin under a `provide` key.

<code-group>

```ts [plugins/hello.ts]twoslash
export default defineNuxtPlugin(() => {
  return {
    provide: {
      hello: (msg: string) => `Hello ${msg}!`,
    },
  }
})
```

```ts [plugins/hello-object-syntax.ts]twoslash
export default defineNuxtPlugin({
  name: 'hello',
  setup () {
    return {
      provide: {
        hello: (msg: string) => `Hello ${msg}!`,
      },
    }
  },
})
```

</code-group>

You can then use the helper in your components:

```vue [app/components/Hello.vue]
<script setup lang="ts">
// alternatively, you can also use it here
const { $hello } = useNuxtApp()
</script>

<template>
  <div>
    {{ $hello('world') }}
  </div>
</template>
```

<important>

Note that we highly recommend using [`composables`](/docs/4.x/directory-structure/app/composables) instead of providing helpers to avoid polluting the global namespace and keep your main bundle entry small.

</important>

<warning>

**If your plugin provides a ref or computed, it will not be unwrapped in a component <template>.** <br />


This is due to how Vue works with refs that aren't top-level to the template. You can read more about it [in the Vue documentation](https://vuejs.org/guide/essentials/reactivity-fundamentals#caveat-when-unwrapping-in-templates).

</warning>

## 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.

<note>

If you need to use a provided helper *within* another plugin, you can call [`useNuxtApp()`](/docs/4.x/api/composables/use-nuxt-app) to get the typed version. But in general, this should be avoided unless you are certain of the plugins' order.

</note>

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' {
  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.

First, install the Vue plugin dependency:

<code-group sync="pm">

```bash [npm]
npm install --save-dev vue-gtag-next
```

```bash [yarn]
yarn add --dev vue-gtag-next
```

```bash [pnpm]
pnpm add -D vue-gtag-next
```

```bash [bun]
bun add -D vue-gtag-next
```

```bash [deno]
deno add -D npm:vue-gtag-next
```

</code-group>

Then create a plugin file:

```ts [app/plugins/vue-gtag.client.ts]
import VueGtag, { trackRouter } from 'vue-gtag-next'

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(VueGtag, {
    property: {
      id: 'GA_MEASUREMENT_ID',
    },
  })
  trackRouter(useRouter())
})
```

## Vue Directives

Similarly, you can register a custom Vue directive in a plugin.

```ts [plugins/my-directive.ts]twoslash
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.directive('focus', {
    mounted (el) {
      el.focus()
    },
    getSSRProps (binding, vnode) {
      // you can provide SSR-specific props here
      return {}
    },
  })
})
```

<warning>

If you register a Vue directive, you *must* register it on both client and server side unless you are only using it when rendering one side. If the directive only makes sense from a client side, you can always move it to `~/plugins/my-directive.client.ts` and provide a 'stub' directive for the server in `~/plugins/my-directive.server.ts`.

</warning>

<read-more icon="i-simple-icons-vuedotjs" target="_blank" title="Custom Directives on Vue Docs" to="https://vuejs.org/guide/reusability/custom-directives.html">



</read-more>