Обсуждение на вашем сайте

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

Проверьте на своей странице

Впишите адрес страницы — получите код и увидите блок сразу здесь. В предпросмотре тот же сниппет, который вы копируете: один контейнер и один скрипт.

Готовый код

<div data-vpvd-thread data-url="https://example.org/article" data-lang="ru" data-theme="auto">
  <a href="https://vpvd.io/embed/ru?url=https%3A%2F%2Fexample.org%2Farticle&amp;theme=auto" target="_blank" rel="noopener">Открыть обсуждение на vpvd</a>
</div>
<script src="https://vpvd.io/embed.js" async referrerpolicy="no-referrer"></script>

Что увидят читатели

Сайт до запуска закрыт: ветку читают анонимно, а вход пока не работает — читатель на вашей странице увидит кнопку, за которой сейчас ничего нет. Вход откроется в день запуска.

Куда это вставить

Код везде одинаковый; различается только место, куда его кладут.

  • Статика и свои шаблоны Там, где обсуждение должно стоять на странице: в шаблоне записи или статьи.
  • WordPress Блок «Произвольный код» в редакторе записи или виджет с кодом в сайдбаре. Часть редакторов выкидывает вставленный скрипт при сохранении — откройте опубликованную страницу и проверьте, что блок на месте.
  • Tilda Блок для своего кода из раздела «Другое»: вставьте сниппет целиком, вместе с тегом скрипта.
  • Next.js, Nuxt, React Скрипт подключается один раз в общем макете сайта, а компонент ставит контейнер и снимает блок при размонтировании — иначе переход на другую страницу оставит в контейнере старый кадр.
<div data-vpvd-thread data-url="https://example.org/article" data-lang="ru" data-theme="auto">
  <a href="https://vpvd.io/embed/ru?url=https%3A%2F%2Fexample.org%2Farticle&amp;theme=auto" target="_blank" rel="noopener">Открыть обсуждение на vpvd</a>
</div>
<script src="https://vpvd.io/embed.js" async referrerpolicy="no-referrer"></script>

Next.js, Nuxt, React

// components/VpvdThread.tsx — one page's discussion. Load the script once in the layout:
// <Script src="https://vpvd.io/embed.js" strategy="afterInteractive" />
'use client';
import { useEffect, useRef } from 'react';

export default function VpvdThread() {
	const box = useRef<HTMLDivElement>(null);
	useEffect(() => {
		const el = box.current;
		const vpvd = (window as any).vpvd;
		if (el && vpvd) vpvd.mount(el);
		return () => { if (el && vpvd) vpvd.destroy(el); };
	}, []);
	return (
		<div ref={box} data-vpvd-thread data-url="https://example.org/article" data-lang="ru" data-theme="auto">
			<a href="https://vpvd.io/embed/ru?url=https%3A%2F%2Fexample.org%2Farticle&amp;theme=auto" target="_blank" rel="noopener">Открыть обсуждение на vpvd</a>
		</div>
	);
}

Страницы, которые меняются без перезагрузки

React, Vue, Svelte, Nuxt: Тег скрипта живёт в разметке и не переживает смену страницы: контейнер остаётся пустым там, где был блок. Подключите скрипт один раз в общем макете сайта и зовите обновление ниже после каждого перехода — оно проходит по всем контейнерам страницы тем же кодом, что работает при первой загрузке.

// after every client-side transition:
window.vpvd.refresh();

Тема и шрифт

Тема задаётся явно — светлая, тёмная или авто, — а под свой сайт блок подгоняется переменными на контейнере: шрифт, кегль, межстрочный интервал, акцент и радиус углов.

data-theme, --vpvd-font, --vpvd-font-size, --vpvd-line-height, --vpvd-accent, --vpvd-radius

С авто блок берёт тему вашей страницы — ту, что вы включаете на сайте, или системную настройку читателя, — а шрифт, кегль и радиус с самого контейнера. Не нашлось ничего — остаётся наш вид.

Атрибуты

data-url
адрес страницы, которую обсуждают. Обсуждение привязано к нему: у всех читателей адрес должен совпадать.
data-lang
язык блока — один из языков в списке ниже. Любое другое значение даёт 404: кадра на других языках нет.
  • en — English
  • zh-Hans — 简体中文
  • es — Español
  • ar — العربية
  • ru — Русский
  • vi — Tiếng Việt
  • tr — Türkçe
  • fa — فارسی
data-theme
тема блока: авто (как на вашей странице), светлая или тёмная.
data-height
высота, которую мы резервируем под блок, пока кадр не сообщит свою, в пикселях, например 200. Дальше блок подстраивается под настоящую высоту; значение живёт в границах 120–2000. Задайте её, если на вашей странице заметен прыжок: по умолчанию зарезервировано 160 пикселей.

Когда появился комментарий

Добавьте этот атрибут — и блок сообщит странице, что появился комментарий. В событии одно слово и ничего о читателе:

data-events="on" → vpvd:commented

Сколько комментариев — для списка

Списку статей нужен номер, а не виджет: этот запрос вернёт число реплик у страницы (ноль, если её ещё никто не обсуждал). Он открыт вашей странице, не требует куки и ничего о читателе не знает:

GET /api/nodes/count?url=…

Чего код не делает

Он не читает содержимое вашей страницы и не оставляет на ней наших куки. До нашего сервера доходит только адрес из атрибута: ни текста страницы, ни имён, ни счётчиков. Реферер мы отключаем и у скрипта, и у кадра.

Проверить, что встроилось

Откройте страницу в браузере и выполните в консоли строки ниже — строка, ответ:

  1. кадр на месте: загрузчик заменил им ссылку-запасной путь в контейнере
  2. загрузчик отработал: значение ниже определено, а версия — 1 window.vpvd
  3. кадр сообщил свою высоту: число больше не равно зарезервированным 160, и блок выровнялся по ветке
// 1
document.querySelector('iframe[data-vpvd-frame]')
// 2
window.vpvd.version
// 3
document.querySelector('iframe[data-vpvd-frame]').style.height

Проверяете автоматически, из браузера без окна (Firefox)? Значения страницы вашему скрипту не видны: он живёт в отдельном мире и делит с ней разметку, а не их. Читайте признаки из главного мира — вставьте в документ свой скрипт и возьмите ответ из атрибута.

Строгая политика на вашем сайте

Разрешите наш адрес (https://vpvd.io) в директивах, которые приводят блок:

  • script-src — оттуда приходит скрипт блока
  • frame-src — в кадре показывается сама ветка
  • child-src → frame-src — если она задана на вашем сайте, кадры подчиняются ей, а не общей директиве: значение из другого источника молча блокирует все кадры страницы, включая наш. Назовите наш адрес и здесь — или уберите её.

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

Вопросы

Что видит читатель?

Ветку этой страницы и вход. Читать можно без аккаунта, писать — гостем (реплика живёт около получаса) или после входа прямо в блоке. Вход — решение самого читателя: сессию вашего сайта мы не получаем.

Что вы узнаёте о моих читателях?

Адрес страницы, который вы положили в сниппет, — и всё. Историю браузинга, текст вашей страницы и её посетителей мы не видим: расширение проверяет наличие обсуждения локально, не спрашивая сервер. Куки ставит только кадр и только свои.

Будут ли комментарии в поиске?

Нет: то, что внутри кадра, поисковики не индексируют. Сама ветка индексируется на vpvd, и ссылка на неё стоит в контейнере.

Что я могу как хозяин сайта?

Убрать блок — убрать код. Подтвердите владение адресом — рядом с вашими репликами появится значок; чужие реплики он скрывать не даёт, правила модерации общие. Свои правила и баны на своём домене появятся вместе с панелью хозяина.

Как отозвать доступ?

Доступа к вашему сайту у нас нет: скрипт только ставит кадр. Удалите код — блок исчезнет. Сессия внутри кадра живёт в нашей куке и уходит вместе с ней.

Код для вашей страницы

Генератор соберёт код с выбранными языком и темой.

Открыть генератор