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.comhttp://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:
- Panel-managed: Panel Comments loads its selected preset, configured colors, and optional custom CSS inside Shadow DOM.
- 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
- Confirm
embed.jsloads from the expected Panel Comments address. - Confirm one
<panel-comments>element mounts at the intended position. - In browser developer tools, confirm
api/index.php?action=bootstrapsucceeds rather than returning an origin error. - Confirm the canonical/current page URL identifies the intended discussion.
- Check mobile width, keyboard focus, light and dark color schemes, empty/loading/error states, replies, search, pagination, Load All, and the composer.
- 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.