# plugins

> В Nuxt плагины подключают код при создании Vue-приложения: плагины Vue, хуки и другое.

Nuxt автоматически считывает файлы из директории `plugins/` и загружает их при создании приложения Vue.

<note>

Все плагины внутри автоматически регистрируются, вам не нужно отдельно добавлять их в `nuxt.config`.

</note>

<note>

Вы можете использовать суффикс `.server` или `.client` в имени файла, чтобы загрузить плагин только на сервере или клиента.

</note>

## Зарегистрированные плагины

Только файлы на верхнем уровне директории (или индексные файлы в любых поддиректориях) будут автоматически зарегистрированы как плагины.

```bash [Directory structure]
-| plugins/
---| foo.ts      // отсканировано
---| bar/
-----| baz.ts    // не сканируется
-----| foz.vue   // не сканируется
-----| index.ts  // в настоящее время сканируется, но устарел
```

Будут зарегистрированы только `foo.ts` и `bar/index.ts`.

Чтобы добавить плагины в поддиректориях, вы можете использовать опцию [`plugins`](/docs/3.x/api/nuxt-config#plugins-1) в `nuxt.config.ts`:

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

## Создание плагинов

Единственным аргументом, передаваемым плагину, является [`nuxtApp`](/docs/3.x/api/composables/use-nuxt-app).

```ts [plugins/hello.ts]twoslash
export default defineNuxtPlugin((nuxtApp) => {
  // Делаем что-то с nuxtApp
})
```

### Плагины в объектном синтаксисе

Также, для более сложных случаев использования, можно определить плагин, используя синтаксис объекта. Например:

```ts [plugins/hello.ts]twoslash
export default defineNuxtPlugin({
  name: 'my-plugin',
  enforce: 'pre', // или 'post'
  async setup (nuxtApp) {
    // это эквивалент обычного функционального плагина
  },
  hooks: {
    // Здесь можно зарегистрировать хуки приложения Nuxt на этапе выполнения
    'app:created' () {
      const nuxtApp = useNuxtApp()
      // сделать что-то в хуке
    },
  },
  env: {
    // Установите это значение в `false`, если вы не хотите, чтобы плагин запускался при рендеринге только серверных или island-компонентов.
    islands: true,
  },
})
```

<video-accordion title="Посмотрите видео от Александра Лихтера об объектном синтаксисе для плагинов Nuxt" video-id="2aXZyXB1QGQ">



</video-accordion>

<note>

Если вы используете объектный синтаксис, свойства анализируются статически, чтобы создать более оптимизированную сборку. Поэтому не следует определять их во время рантайма. <br />


Например, установка `enforce: import.meta.server ? 'pre' : 'post'` приведет к невозможности дальнейшей оптимизации, которую Nuxt сможет выполнить для ваших плагинов.
При использовании объектного синтаксиса, Nuxt статически предварительно загружает все слушатели хуков, позволяя вам определять хуки, не заботясь о порядке регистрации плагинов.

</note>

## Порядок регистрации

Вы можете контролировать порядок регистрации плагинов, добавляя к именам файлов префикс с алфавитной нумерацией.

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

В этом примере `02.myOtherPlugin.ts` сможет получить доступ ко всему, что было внедрено `01.myPlugin.ts`.

Это полезно в ситуациях, когда у вас есть плагин, который зависит от другого плагина.

<note>

Если вы новичок в алфавитной нумерации, помните: имена файлов сортируются как строки, а не как числа. Например, `10.myPlugin.ts` окажется раньше `2.myOtherPlugin.ts`. Поэтому в примере однозначные номера дополняют нулём.

</note>

## Стратегия загрузки

### Параллельные плагины

По умолчанию Nuxt загружает плагины последовательно. Можно пометить плагин как `parallel`: тогда Nuxt не будет ждать завершения его `setup` перед запуском следующего плагина.

```ts [plugins/my-plugin.ts]twoslash
export default defineNuxtPlugin({
  name: 'my-plugin',
  parallel: true,
  async setup (nuxtApp) {
    // следующий плагин будет выполнен немедленно
  },
})
```

### Плагины с зависимостями

Если плагину необходимо дождаться запуска другого плагина, вы можете добавить его имя в массив `dependsOn`.

```ts [plugins/depending-on-my-plugin.ts]twoslash
export default defineNuxtPlugin({
  name: 'depends-on-my-plugin',
  dependsOn: ['my-plugin'],
  async setup (nuxtApp) {
    // этот плагин будет ждать окончания выполнения `my-plugin` перед запуском
  },
})
```

## Использование композаблов

В плагинах Nuxt можно использовать [композаблы](/docs/3.x/directory-structure/composables) и [утилиты](/docs/3.x/directory-structure/utils):

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

Однако имейте в виду, что существуют некоторые ограничения и различия:

<important>

**Если композабл зависит от другого плагина, зарегистрированного позже, он может не сработать.** <br />



Плагины вызываются последовательно и перед всем остальным. Вы можете использовать композабл, который зависит от другого плагина, который ещё не был вызван.

</important>

<important>

**Если композабл зависит от жизненного цикла Vue.js, он не будет работать.** <br />



Обычно композаблы Vue привязаны к экземпляру компонента, а в плагине контекст — это [`nuxtApp`](/docs/3.x/api/composables/use-nuxt-app).

</important>

## Предоставление хелперов

Чтобы добавить хелпер в [`NuxtApp`](/docs/3.x/api/composables/use-nuxt-app), верните его из плагина в поле `provide`.

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

Затем хелпер можно вызывать в компонентах:

```vue [components/Hello.vue]
<script setup lang="ts">
// альтернативно, вы также можете использовать его здесь
const { $hello } = useNuxtApp()
</script>

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

<important>

Надёжнее подключать логику через [`композаблы`](/docs/3.x/directory-structure/composables), а не через глобальные хелперы: так меньше риск засорить глобальное пространство имён и раздуть точку входа бандла.

</important>

<warning>

**Если ваш плагин предоставляет ref или computed, он не будет развернут в <template> компонента.** <br />


Это связано с тем, как Vue обрабатывает `ref`, не лежащие на верхнем уровне шаблона. Подробнее — [в документации Vue](https://vuejs.org/guide/essentials/reactivity-fundamentals#caveat-when-unwrapping-in-templates).

</warning>

## Типизация плагинов

Хелперы, возвращённые из плагина, получают типизацию автоматически — в том числе при вызове из `useNuxtApp()` и в шаблонах.

<note>

Чтобы вызвать хелпер из другого плагина, используйте [`useNuxtApp()`](/docs/3.x/api/composables/use-nuxt-app) — так вы получите типизированный доступ. Избегайте этого, если не уверены в порядке загрузки плагинов.

</note>

Для более сложных случаев использования можно объявить тип внедряемых свойств следующим образом:

```ts [index.d.ts]
declare module '#app' {
  interface NuxtApp {
    $hello (msg: string): string
  }
}

declare module 'vue' {
  interface ComponentCustomProperties {
    $hello (msg: string): string
  }
}

export {}
```

## Плагины Vue

Если вы хотите использовать плагины Vue, например [vue-gtag](https://github.com/MatteoGabriele/vue-gtag) для добавления тегов Google Analytics, вы можете использовать для этого плагин Nuxt.

Сначала установите зависимость плагина Vue:

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

Затем создайте файл плагина:

```ts [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

Аналогичным образом вы можете зарегистрировать в плагине пользовательскую директиву Vue.

```ts [plugins/my-directive.ts]twoslash
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.directive('focus', {
    mounted (el) {
      el.focus()
    },
    getSSRProps (binding, vnode) {
      // Здесь вы можете предоставить входные параметры, специфичные для SSR
      return {}
    },
  })
})
```

<warning>

Если вы регистрируете директиву Vue, вы *должны* зарегистрировать её как на стороне клиента, так и на стороне сервера, если вы не используете её при рендеринге только на одной стороне. Если директива имеет смысл только на клиенте, вы всегда можете переместить её в `~/plugins/my-directive.client.ts` и предоставить для сервера директиву-«заглушку» в `~/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>
