Разработчику
Фреймворки
Куда вставить две строки в Next.js, Nuxt, React, Vue, Angular, WordPress, Tilda и Битрикс.
На странице
В любом стеке нужны те же две строки (Установка на сайт). Скрипт и элемент
добавляются по одному разу, в общий шаблон всех страниц. Замените your-project на id проекта.
Обычный HTML
Вставьте строки перед </body> на каждой странице или в шаблоне, из которого они собираются:
<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 не пропадает при переходах между страницами. Поставьте чат туда:
// 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 не примет
<tolkly-chat>.
Next.js (Pages Router)
_app оборачивает каждую страницу и не размонтируется при переходах:
// 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:
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:
// 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>:
<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, выводите его один раз в
корневом компоненте и добавьте объявление типа.
Vue 3 на Vite
Вставьте обе строки в index.html, перед </body>, вне элемента #app. Если хотите использовать
тег в шаблоне Vue, сообщите компилятору, что это custom element:
// 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:
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 темы:
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. Если шаблон
кэшируется, затем очистите кэш сайта.