Разработчику
Content-Security-Policy
Что разрешить для чата, если сайт отдаёт Content-Security-Policy.
На странице
Если ваш сайт отдаёт Content-Security-Policy, политика должна разрешать виджету загружать скрипт и обращаться к серверу. Если политики нет, эту страницу можно пропустить.
Что нужно виджету
Добавьте эти источники в директивы вашей политики. Свои источники оставьте как есть:
| Директива | Добавить | Зачем |
|---|---|---|
script-src | https://api.tolkly.io https://ru.tolkly.io | /widget.js и части, которые он импортирует из /widget/ |
connect-src | https://api.tolkly.io https://ru.tolkly.io | настройки проекта; вопросы и ответы потоком; живой поток разговора (server-sent events); загрузка и скачивание файлов |
img-src | https://api.tolkly.io https://ru.tolkly.io blob: | картинки в разговоре, по подписанным ссылкам (/v1/files/…); blob: — превью картинки до отправки |
Менять style-src не нужно, 'unsafe-inline' тоже не нужен. Виджет задаёт стили своего shadow root через constructed stylesheets (adoptedStyleSheets). Политика их не блокирует. Они работают в Chrome 73+, Edge 79+, Firefox 101+ и Safari 16.4+. Про старый Safari — в разделе nonce.
https://api.tolkly.io https://ru.tolkly.io выше — все адреса, с которых может загрузиться виджет: widget.js загружает чат
со следующего, если первый не ответил вовремя (посетители из России). Код
установки, скопированный до 10 ноября 2026 года, может начинаться со встроенного <script> —
загрузчика. Он продолжает работать, с вашим nonce или его хешем в script-src, как раньше;
обычной строке из раздела установка не нужно ни то, ни другое.
Больше ничего не нужно:
'unsafe-eval'не нужен.font-srcне нужен. Чат берёт шрифт сайта по имени (--tolkly-font) и не загружает файлы шрифтов.frame-srcне нужен. Виджет не использует фреймы.media-srcне нужен. Звуки создаются прямо в браузере.
Заголовок целиком
Content-Security-Policy: default-src 'self'; script-src 'self' https://api.tolkly.io https://ru.tolkly.io; connect-src 'self' https://api.tolkly.io https://ru.tolkly.io; img-src 'self' https://api.tolkly.io https://ru.tolkly.io blob:Та же политика мета-тегом, в <head> перед любым скриптом:
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' https://api.tolkly.io https://ru.tolkly.io; connect-src 'self' https://api.tolkly.io https://ru.tolkly.io; img-src 'self' https://api.tolkly.io https://ru.tolkly.io blob:">Nonce и strict-dynamic
В Safari до 16.4 нет constructed stylesheets. Там виджет добавляет стили элементом <style> в свой shadow root, и на него действует style-src. Если ваша политика задаёт nonce для стилей, поставьте тот же nonce на тег. Тогда и в этих браузерах чат будет со стилями:
<tolkly-chat endpoint="https://api.tolkly.io" project="your-project" nonce="SERVER_NONCE"></tolkly-chat>SERVER_NONCE — это nonce, который ваш сервер создаёт для каждого ответа.
- Если у тега нет атрибута
nonce, виджет берёт nonce первого<script nonce>на странице. - Если nonce нет совсем, старый Safari покажет чат без стилей, если в
style-srcнет'unsafe-inline'. Современных браузеров это не касается.
Ещё два случая:
script-srcс'strict-dynamic': адреса вродеhttps://api.tolkly.ioв нём не действуют. Поставьте ваш nonce на тег<script>виджета. Тогда'strict-dynamic'пропустит и части, которые скрипт импортирует.- Только
default-src: он заменяет все директивы выше, которых нет в политике. Добавьте источники вdefault-srcили пропишите эти директивы отдельно.
nginx
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://api.tolkly.io https://ru.tolkly.io; connect-src 'self' https://api.tolkly.io https://ru.tolkly.io; img-src 'self' https://api.tolkly.io https://ru.tolkly.io blob:" always;add_header внутри location заменяет все add_header блока server. Повторите политику в этом location или задавайте её в одном месте.
Next.js
// next.config.mjs
const csp = [
"default-src 'self'",
"script-src 'self' https://api.tolkly.io https://ru.tolkly.io",
"connect-src 'self' https://api.tolkly.io https://ru.tolkly.io",
"img-src 'self' https://api.tolkly.io https://ru.tolkly.io blob:",
].join('; ')
export default {
async headers() {
return [{ source: '/:path*', headers: [{ key: 'Content-Security-Policy', value: csp }] }]
},
}Добавьте эти источники к тому, что приложение уже разрешает. Next.js нужны и свои источники, которых в примере нет: для его встроенных скриптов и стилей или nonce из middleware.
Если политика не может это разрешить
Если политика блокирует чат, на этих страницах он не работает. Браузер не пропускает скрипт или запросы и пишет об этом в консоли. Не ослабляйте политику сами. Расскажите владельцу сайта, что нужно чату, и пусть решает он.