Widget configuration

Every __semio__params option, plus page callbacks, widget events, runtime commands and theming.

Everything the comment widget does is driven by one JavaScript object: __semio__params. You already met it in Getting Started — this page documents every option it accepts, plus the callbacks your page can define, the events the widget emits, and the commands you can send it at runtime.

The configuration object at a glance

var __semio__params = {
  graphcommentId: "<shortname>",   // required — your site's shortname

  behaviour: {
    uid:                 "article-12345",             // recommended — stable thread ID
    url:                 "https://my.site/article",   // canonical URL (if query strings vary)
    readonly:            false,                       // true = display only, no posting
    sort:                "newest",                    // "newest" | "oldest" | "relevance"
    countPerPage:        10,                          // top-level discussions per page
    inapp:               false,                       // true only inside a mobile WebView
    lifetime:            30,                          // days during which commenting stays open
    publication_date:    "2026-06-02T12:00:00Z",      // article publication date (ISO 8601)
    telemetricTroughCmp: false                        // true to enable CMP-gated telemetry
  },

  statistics: {
    pageTitle: "My article title",   // shown in your back-office statistics
    category:  "Tech"                // page category, for your stats
  },

  integration: {
    fixedHeaderHeight: 60            // px height of your fixed header (scroll offset)
  }
};

All three sections are optional — a bare graphcommentId is enough to load the widget. Each option is detailed below.

📘

Using single sign-on?

With SSO the widget takes an extra auth section and loads through a different script. See Single Sign-On — everything on this page still applies.

Which script loads the widget

GraphComment ships two loader scripts, depending on whether you use SSO:

SetupScriptInit function
Standard widget (no SSO)gc_graphlogin.js__semio__gc_graphlogin(__semio__params)
With SSO (helpers_sso.js)gc.js__semio__gc(__semio__params)

Both are served from https://integration.graphcomment.com/ and both read the same __semio__params object. The Getting Started snippet uses the standard loader.

behaviour options

OptionTypeDescription
uidstringRecommended. A stable, unique identifier for the thread (your CMS post ID is ideal). This is what keeps comments attached to their page when URLs change.
urlstringThe canonical URL of the page. Set it explicitly if your page can be reached with varying query strings.
readonlybooleantrue renders the thread in display-only mode: visitors can read but not post.
sortstringSort order: "newest", "oldest" or "relevance" — note that this is one layer of four, see "Who decides the sort order" below.
countPerPagenumberNumber of top-level discussions loaded per page.
inappbooleanSet to true only when the widget runs inside a mobile WebView. See Mobile (WebView).
lifetimenumberNumber of days, counted from the publication date, during which new comments can be posted.
publication_datestringThe article's publication date, ISO 8601 (used with lifetime).
telemetricTroughCmpbooleantrue enables telemetry gated by your consent management platform.

uid and url: thread identity

GraphComment automatically strips query-string parameters from the page URL so that one page resolves to one thread. If your page can be reached with extra parameters, don't rely on the URL for identity — set uid (and url if needed):

behaviour: {
  uid: "post-12345",
  url: "https://your-site.com/article.html"
}
⚠️

uid is the setting that matters most

A stable uid makes your threads survive domain migrations, trailing-slash changes and tracking parameters. Set it once, from an identifier you control, and never change it.

Three rules to keep out of trouble:

  • Never give the same uid to two different pages. Their comments would be mixed into a single thread — and that cannot be undone: two threads can't be merged, or un-merged.
  • If your page is itself rendered inside an iframe (embedded widgets, Google Sites…), the URL the widget sees may be the iframe's, not your page's — uid becomes mandatory there.
  • On WordPress, skip all of this: the plugin manages thread identity automatically.
📘

Building a SPA?

To switch threads on internal navigation without a page reload, update behaviour.uid and call the init function again — the pattern is shown in Single Sign-On and works the same without SSO.

Who decides the sort order

behaviour.sort is one layer of four. The widget resolves the sort order in this priority, highest first:

  1. The visitor's own choice — when someone picks a sort order in the widget, it's remembered in their browser for that page and wins on every return visit.
  2. The logged-in user's saved preference — a GraphComment account carries a sort preference.
  3. Your behaviour.sort — from the snippet.
  4. Your site's back-office setting — the site-wide default when none of the above is set.

So behaviour.sort sets the order for first-time, anonymous visitors — it does not override a choice the visitor already made. Don't be surprised if a returning visitor sees a different order than the snippet forces.

statistics options

These values feed the statistics you see in your GraphComment back-office. They don't change how the widget renders.

OptionTypeDescription
pageTitlestringThe article title, as you want it to appear in your stats.
categorystringA free-form category for the page (e.g. "Tech", "News").

integration options

OptionTypeDescription
fixedHeaderHeightnumberHeight in px of your site's fixed header. The widget uses it as a scroll offset so anchored scrolling doesn't land under your header.

Consent management (TCF v2)

If your site runs a consent management platform implementing IAB TCF v2, the widget integrates with it through the standard window.__tcfapi interface: it reads the vendor consent status via getTCData and behaves accordingly — consent refused means comments are not loaded, consent pending means the widget waits, consent granted means normal loading.

Page callbacks

Your page can define two global callbacks. Define them before the loader script runs:

// Called when a visitor posts a new comment
window.gcOnComment = function (commentData) {
  // e.g. notify your analytics
};

// Called when the widget is ready
window.onGcLoaded = function () {
  // e.g. remove your placeholder/skeleton
};

Widget events (postMessage)

The widget runs in an iframe and reports its lifecycle to the parent page with postMessage. The loader script consumes most of these itself (that's how the iframe auto-resizes), but your page can listen too:

EventEmitted when
gc-readyThe widget is ready.
gc-loadedThe widget is fully loaded.
gc-new-commentA new comment was posted (carries the comment data).
gc-heightThe widget's height changed (carries the new height in px).
gc-scrollThe widget requests a scroll of the parent page.
gc-reloadThe widget requests a comments reload.

Messages are JSON payloads whose name field carries the event name:

window.addEventListener("message", function (ev) {
  var msg;
  try {
    msg = typeof ev.data === "string" ? JSON.parse(ev.data) : ev.data;
  } catch (e) { return; }
  if (msg && msg.name === "gc-new-comment") {
    // react to the new comment
  }
});
👍

Prefer the callbacks

For the two common cases — "a comment was posted" and "the widget is ready" — window.gcOnComment and window.onGcLoaded do the message plumbing for you.

Runtime commands

The loader script exposes these functions on window; they act on the widget immediately — from your own code or straight from the browser console.

CommandSignatureEffect
__semio__gcSetLang('fr')Switch the widget's UI language.
__semio__gcToggleCommentScores()Show/hide comment scores.
__semio__gcLightTheme(accent?)Switch to the light theme. accent is a named preset or a #rrggbb hex color.
__semio__gcDarkTheme(palette?, accent?)Switch to the dark theme. palette is one of neutral, slate, deep-blue, moonlit, carbon.

Light and dark themes

The theme is decided in this order:

  1. Your back-office setting (Settings → Customization) comes first. If you've forced light or dark there, that wins.
  2. When the back-office setting is auto (the default), the widget detects the theme from the colors of the page that embeds it.
  3. At runtime, you can switch explicitly:
// Force the light theme with your brand accent color
__semio__gcLightTheme('#f35b5b');

// Force the dark theme
__semio__gcDarkTheme('slate');

Call these at any time after the widget has loaded — for example from your site's own dark-mode toggle, so the comment thread follows your theme switch instantly.

Advanced options

⚠️

Not part of the stable public contract

The options below exist and work, but they are internal integration options: they may change without notice and are not covered by the documented baseline above. Use them knowingly.

behaviour (advanced):

OptionTypeDescription
commentIdstringScroll to this specific comment on load.
disableAdsbooleanDisable ads in the widget.
disableLiveRepliesbooleanDisable live replies.

integration (advanced):

OptionTypeDescription
targetDOM elementCustom mount point, instead of #graphcomment.
themestringForce 'dark' or 'light' at load — only applies when your back-office theme setting is auto.
fontstringFont family (a Google Font or a system font); takes priority over the back-office setting.

Side panel mode. Dedicated bundles (gc_sidePanel.js, gc_sidePanel_graphlogin.js) render the comments in a sliding overlay panel instead of an inline block, configured through a sidePanel section:

sidePanel: {
  visible: true,          // panel open by default
  width: 600,             // panel width in px (desktop)
  zindex: 99,
  button: { label: 'Comments', background: '#f35b5b' },
  bubble: { background: '#f35b5b', zindex: 98 }
}

All the panel's CSS is generated by the bundle — nothing to add to your own stylesheets.

Runtime commands (advanced):

CommandSignatureEffect
__semio__gcSetFont('Roboto')Change the widget font (Google Font or system font).
__semio__gcSetDarkBg('#1a1e24' | '')Override the iframe background in dark mode; '' resets.

Next steps


Did this page help you?