Panel CommentsAdmin sign in
Documentation

Integration

Integrating Panel Comments

Panel Comments supports Astro and ordinary static HTML through one classic script. The loader derives the Panel Comments server from its own URL and derives the discussion from the embedding page.

Register the website

In Panel Comments, open Websites, choose Add website, and enter the embedding website's origin. An origin is only the scheme, hostname, and optional non-default port:

  • https://www.example.com
  • http://localhost:4321

Do not enter an article path. Browser security treats http and https, different hostnames, and different ports as different origins, so the value must exactly match the website being tested.

Local staging is supported. Register http://localhost:4321 while developing. At launch, open the selected website's General page and replace it with the live address. Panel Comments changes the discussion URLs to the new origin while preserving their paths, comments, and moderation state.

Static HTML

Place the loader where the comments should appear:

<script data-cfasync="false" src="https://comments.example.com/embed.js" defer></script>

For an installation in a subfolder, include that path:

<script data-cfasync="false" src="https://example.com/comments/embed.js" defer></script>

The loader inserts <panel-comments> immediately after the script. To control placement explicitly, provide a target:

<section data-panel-comments></section>
<script
  data-cfasync="false"
  src="https://comments.example.com/embed.js"
  data-target="[data-panel-comments]"
  defer
></script>

Load the script once per page.

The loader is lazy by default and starts the widget as it approaches the viewport. Use data-loading="eager" only when comments must initialize immediately. data-composer-position="top" or "bottom" can override the website default for a particular integration. The website setting remains the preferred place for a consistent choice.

Astro

Place the integration in a page or reusable component:

<section data-panel-comments></section>
<script
  is:inline
  data-cfasync="false"
  src="https://comments.example.com/embed.js"
  data-target="[data-panel-comments]"
  defer
></script>

is:inline keeps Astro from rewriting the external classic script. The loader listens for astro:page-load and remounts after view transitions when the page URL changes.

Discussion identity

By default, the loader uses a same-origin canonical link when one exists and otherwise uses location.href. A canonical URL on https://www.example.com/article/ must not point to a different origin. Panel Comments removes fragments and applies the website's allowed-query-key policy before resolving the discussion.

Use data-page-key only when a project deliberately needs a stable identity unrelated to its URL. Most sites should leave it unset so address changes and discussion tools work naturally.

Choose the styling owner

Each registered website has two exclusive rendering modes:

  1. Panel-managed: Panel Comments loads its selected preset, configured colors, and optional custom CSS inside Shadow DOM.
  2. Host-managed: clear Let Panel Comments load this stylesheet under Appearance. The widget requests no comment CSS and renders light-DOM HTML for the embedding website to style.

For a theme built alongside the Astro or static site, use host-managed mode and scope every rule beneath panel-comments. See the styling contract. Never modify assets/widget.js or depend on internal honeypot fields.

Article and comment reactions, the rich editor, and the allowed reaction choices are website settings under Engagement. Integrations do not need reaction-specific JavaScript. The widget preserves historical counts for a reaction an administrator later disables, but visitors cannot add that choice. Host-managed themes should style the published reaction, editor, table, preview, and code-copy hooks in the styling contract.

Metadata events

The custom element emits bubbling, composed panel-comments:metadata events after bootstrap and public state changes, plus panel-comments:ready after the initial thread renders. event.detail contains schema_version, normalized public page identity/state/counts, article reaction totals, and the number of comments currently loaded. This is an optional read-only enhancement for host layouts; do not replace the supported widget with a direct API client.

Verify the integration

  1. Confirm embed.js loads from the expected Panel Comments address.
  2. Confirm one <panel-comments> element mounts at the intended position.
  3. In browser developer tools, confirm api/index.php?action=bootstrap succeeds rather than returning an origin error.
  4. Confirm the canonical/current page URL identifies the intended discussion.
  5. Check mobile width, keyboard focus, light and dark color schemes, empty/loading/error states, replies, search, pagination, Load All, and the composer.
  6. Submit a real test comment only when the website owner authorizes it.

Do not put Turnstile secrets, administrator credentials, or any other server secret in the embedding website. The browser embed contains only public configuration.