Разработчику

Content-Security-Policy

Что разрешить для чата, если сайт отдаёт Content-Security-Policy.

На странице

Если ваш сайт отдаёт Content-Security-Policy, политика должна разрешать виджету загружать скрипт и обращаться к серверу. Если политики нет, эту страницу можно пропустить.

Что нужно виджету

Добавьте эти источники в директивы вашей политики. Свои источники оставьте как есть:

ДирективаДобавитьЗачем
script-srchttps://api.tolkly.io https://ru.tolkly.io/widget.js и части, которые он импортирует из /widget/
connect-srchttps://api.tolkly.io https://ru.tolkly.ioнастройки проекта; вопросы и ответы потоком; живой поток разговора (server-sent events); загрузка и скачивание файлов
img-srchttps://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 не нужен. Звуки создаются прямо в браузере.

Заголовок целиком

HTTP
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> перед любым скриптом:

HTML
<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 на тег. Тогда и в этих браузерах чат будет со стилями:

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

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

JavaScript
// 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.

Если политика не может это разрешить

Если политика блокирует чат, на этих страницах он не работает. Браузер не пропускает скрипт или запросы и пишет об этом в консоли. Не ослабляйте политику сами. Расскажите владельцу сайта, что нужно чату, и пусть решает он.