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
authsection 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:
| Setup | Script | Init 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
behaviour options| Option | Type | Description |
|---|---|---|
uid | string | Recommended. 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. |
url | string | The canonical URL of the page. Set it explicitly if your page can be reached with varying query strings. |
readonly | boolean | true renders the thread in display-only mode: visitors can read but not post. |
sort | string | Sort order: "newest", "oldest" or "relevance" — note that this is one layer of four, see "Who decides the sort order" below. |
countPerPage | number | Number of top-level discussions loaded per page. |
inapp | boolean | Set to true only when the widget runs inside a mobile WebView. See Mobile (WebView). |
lifetime | number | Number of days, counted from the publication date, during which new comments can be posted. |
publication_date | string | The article's publication date, ISO 8601 (used with lifetime). |
telemetricTroughCmp | boolean | true enables telemetry gated by your consent management platform. |
uid and url: thread identity
uid and url: thread identityGraphComment 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"
}
uidis the setting that matters mostA stable
uidmakes 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
uidto 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 —
uidbecomes 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.uidand 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:
- 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.
- The logged-in user's saved preference — a GraphComment account carries a sort preference.
- Your
behaviour.sort— from the snippet. - 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
statistics optionsThese values feed the statistics you see in your GraphComment back-office. They don't change how the widget renders.
| Option | Type | Description |
|---|---|---|
pageTitle | string | The article title, as you want it to appear in your stats. |
category | string | A free-form category for the page (e.g. "Tech", "News"). |
integration options
integration options| Option | Type | Description |
|---|---|---|
fixedHeaderHeight | number | Height 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:
| Event | Emitted when |
|---|---|
gc-ready | The widget is ready. |
gc-loaded | The widget is fully loaded. |
gc-new-comment | A new comment was posted (carries the comment data). |
gc-height | The widget's height changed (carries the new height in px). |
gc-scroll | The widget requests a scroll of the parent page. |
gc-reload | The 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 callbacksFor the two common cases — "a comment was posted" and "the widget is ready" —
window.gcOnCommentandwindow.onGcLoadeddo 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.
| Command | Signature | Effect |
|---|---|---|
__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:
- Your back-office setting (Settings → Customization) comes first. If you've forced light or dark there, that wins.
- When the back-office setting is auto (the default), the widget detects the theme from the colors of the page that embeds it.
- 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 contractThe 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):
| Option | Type | Description |
|---|---|---|
commentId | string | Scroll to this specific comment on load. |
disableAds | boolean | Disable ads in the widget. |
disableLiveReplies | boolean | Disable live replies. |
integration (advanced):
| Option | Type | Description |
|---|---|---|
target | DOM element | Custom mount point, instead of #graphcomment. |
theme | string | Force 'dark' or 'light' at load — only applies when your back-office theme setting is auto. |
font | string | Font 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):
| Command | Signature | Effect |
|---|---|---|
__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
- Single Sign-On — sign your users in with their existing account.
- Mobile (WebView) — the
inappflow for native apps. - Comment count — show comment counts next to article links.
Updated about 1 month ago
