# Фреймворки

> Куда вставить две строки в Next.js, Nuxt, React, Vue, Angular, WordPress, Tilda и Битрикс.

В любом стеке нужны те же две строки ([Установка на сайт](https://tolkly.io/docs/ru/install.md)). Скрипт и элемент
добавляются по одному разу, в общий шаблон всех страниц. Замените `your-project` на id проекта.

## Обычный HTML
Вставьте строки перед `</body>` на каждой странице или в шаблоне, из которого они собираются:

```html
  <script type="module" src="https://api.tolkly.io/widget.js"></script>
  <tolkly-chat endpoint="https://api.tolkly.io" project="your-project"></tolkly-chat>
</body>
```

С другими серверными шаблонами — так же: layout Blade в Laravel, `base.html` в Django,
`application.html.erb` в Rails. Строки идут перед `</body>` базового layout.

## Next.js (App Router)
Корневой layout не пропадает при переходах между страницами. Поставьте чат туда:

```tsx
// app/layout.tsx
import Script from 'next/script'
import type { ReactNode } from 'react'

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <tolkly-chat endpoint="https://api.tolkly.io" project="your-project"></tolkly-chat>
        <Script type="module" src="https://api.tolkly.io/widget.js" strategy="afterInteractive" />
      </body>
    </html>
  )
}
```

- `next/script` передаёт `type="module"` в тег скрипта, который добавляет.
- С `afterInteractive` виджет запускается после гидрации страницы.
- React 19 выводит custom element с атрибутами в том виде, как они написаны.
- Добавьте [объявление типа](#typescript-and-jsx) ниже, иначе TypeScript не примет `<tolkly-chat>`.

## Next.js (Pages Router)
`_app` оборачивает каждую страницу и не размонтируется при переходах:

```tsx
// pages/_app.tsx
import type { AppProps } from 'next/app'
import Script from 'next/script'

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <Component {...pageProps} />
      <tolkly-chat endpoint="https://api.tolkly.io" project="your-project"></tolkly-chat>
      <Script type="module" src="https://api.tolkly.io/widget.js" strategy="afterInteractive" />
    </>
  )
}
```

## TypeScript и JSX
Типы React 19 берут intrinsic elements из `React.JSX`. Объявите тег один раз в любом файле `.d.ts`,
который входит в ваш `tsconfig.json`, например в `tolkly.d.ts`:

```ts
import type { DetailedHTMLProps, HTMLAttributes } from 'react'

type TolklyChatProps = DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement> & {
  endpoint?: string
  project?: string
  name?: string
  greeting?: string
  handoff?: string
  teaser?: string
  position?: 'left' | 'right'
  theme?: 'site' | 'system' | 'light' | 'dark'
  'send-icon'?: 'arrow' | 'plane' | 'forward'
  collapse?: string
  'data-identity'?: string
}

declare module 'react' {
  namespace JSX {
    interface IntrinsicElements {
      'tolkly-chat': TolklyChatProps
    }
  }
}
```

`import` делает файл модулем. Благодаря этому `declare module 'react'` дополняет типы React, а не
заменяет их. `HTMLAttributes` уже включает `lang`, `nonce`, `style` и `className`.

Не передавайте `open` и `inline` в JSX. Если у элемента есть DOM-свойство с тем же именем, React 19
записывает prop в это свойство. А у `<tolkly-chat>` есть метод `open()` и свойство `inline` только
для чтения. Пишите эти атрибуты в `index.html` или вызывайте `open({ focus: false })` у элемента из
эффекта.

## Nuxt 3
Подключите скрипт в `nuxt.config.ts` и сообщите Vue, что тег — это custom element:

```ts
// nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      script: [{ src: 'https://api.tolkly.io/widget.js', type: 'module' }],
    },
  },
  vue: {
    compilerOptions: {
      isCustomElement: (tag) => tag.startsWith('tolkly-'),
    },
  },
})
```

Затем поставьте элемент в `app.vue`, вне `<NuxtPage>`:

```vue
<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
  <tolkly-chat endpoint="https://api.tolkly.io" project="your-project"></tolkly-chat>
</template>
```

## React на Vite
Вставьте обе строки в `index.html`, перед `</body>`, вне элемента `#root`, в который рисует React.
Код React менять не нужно. Если хотите выводить `<tolkly-chat>` из JSX, выводите его один раз в
корневом компоненте и добавьте [объявление типа](#typescript-and-jsx).

## Vue 3 на Vite
Вставьте обе строки в `index.html`, перед `</body>`, вне элемента `#app`. Если хотите использовать
тег в шаблоне Vue, сообщите компилятору, что это custom element:

```ts
// vite.config.ts
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: { isCustomElement: (tag) => tag.startsWith('tolkly-') },
      },
    }),
  ],
})
```

## Angular
Вставьте обе строки в `src/index.html`, перед `</body>`, вне корневого элемента приложения. Не
добавляйте скрипт в `scripts` файла `angular.json`. Тогда он попадёт в сборку как обычный скрипт и
не запустится.

Если хотите использовать тег в шаблоне компонента, разрешите там custom elements:

```ts
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppComponent {}
```

## WordPress
Вставьте строки прямо перед `</body>` в `footer.php` вашей темы. Берите дочернюю тему, чтобы
обновление не стёрло вставку. Или добавьте их через `functions.php` темы:

```php
add_action('wp_footer', function () {
    echo '<script type="module" src="https://api.tolkly.io/widget.js"></script>';
    echo '<tolkly-chat endpoint="https://api.tolkly.io" project="your-project"></tolkly-chat>';
});
```

Нет доступа к файлам темы? Подойдёт любой плагин, который добавляет свой код перед `</body>` на
всех страницах. Затем очистите кэш страниц, если он есть.

## Tilda
Добавьте обе строки в блок HTML-кода (T123). Поставьте блок в подвал, общий для всех страниц, или на
каждую страницу, где нужен чат. Затем опубликуйте страницы заново.

## 1С-Битрикс
Вставьте строки прямо перед `</body>` в `footer.php` шаблона сайта. Он лежит в
`/local/templates/<template>/footer.php` или `/bitrix/templates/<template>/footer.php`. Если шаблон
кэшируется, затем очистите кэш сайта.
