Skip to content

JavaScript API ​

Once the asynchronous loader.js has run, the widget exposes a lightweight global at window.zeeker. Calls made before the mode-gated async runtime is ready are queued and replayed. Methods that need the runtime immediately—open(), identify(), identifyObject(), logout(), and load()—start its asynchronous download immediately. refresh() keeps its documented full-page reload behavior and does not download the runtime first.

The interaction-first trigger.js entry point exposes only open() and close() before its first open. The complete API replaces that facade after the runtime loads. Use loader.js when the host must call SSO, object identity, refresh, or event methods before a visitor opens Zeeker.

Methods ​

window.zeeker.open() ​

Opens the configured panel or app surface (floating, pill, or trigger modes). A trigger can open the page discussion, community app, group chat, or private MOD Chat, including a full-screen app surface. Group Chat and MOD Chat integrations call this from a desktop floating chat/support button and from the mobile host app's bottom-tray chat action. No-op if already open or if the mode doesn't have a toggleable surface (anchor or fixed inline content).

js
document.getElementById('my-cta').addEventListener('click', () => {
  window.zeeker.open();
});

window.zeeker.close() ​

Closes the slide-in panel. No-op if it isn't open.

window.zeeker.identify(jwt) ​

Sign the visitor in via SSO. Pass the JWT minted by your server. See SSO.

js
window.zeeker.identify(yourJwt);

Calling identify(null) (or identify()) clears the SSO token without doing a full logout.

window.zeeker.identifyObject(object) ​

Provides a stable native/app object for discussion aggregation. Call it before the first boot when possible. The bootstrap accepts fields such as appId, objectType, objectId, title, description, imageUrl, and url.

js
window.zeeker.identifyObject({
  appId: 'reader-app',
  objectType: 'article',
  objectId: 'article-123',
  title: 'Building a healthier reader community',
  url: 'app://articles/article-123'
});

If the runtime has already booted, changing the object resolves the new discussion in place. The host page does not reload.

window.zeeker.logout() ​

Hard logout. Clears SSO token, Zeeker session, and authenticated state. Emits logout.

window.zeeker.refresh() ​

Resolve the widget again against the current canonical URL and metadata without reloading the host page. The previous surface is retired before the next one is mounted. Registered public event handlers remain available.

window.zeeker.reconfigure(options) ​

Update the embed during host-app navigation. Options can set url, object, threadId, configId, targetId, and theme. Pass object: null when leaving an object-bound page for an ordinary URL-bound discussion.

js
window.zeeker.reconfigure({
  url: window.location.href,
  object: null,
});

Use an explicit url if the SPA has not yet updated its canonical metadata. Changing to another configuration discards configuration-bound identity and scope state; the new configuration's normal access checks apply. Listen for ready before interacting with the newly mounted surface.

window.zeeker.diagnose() ​

Return a local installation report for the active loader and surface. The dashboard's installation diagnostics uses this information when checking an installed page.

window.zeeker.load() ​

Starts the asynchronous runtime without opening a Zeeker surface. This method exists on the lightweight loader.js bootstrap; after the runtime replaces that facade, it is no longer needed. Most integrations should let the bootstrap choose the mode-appropriate start time automatically.

js
window.zeeker.load();

window.zeeker.getState() ​

Snapshot of the widget's current state. Returns an object:

ts
{
  postId: string | null;
  panelOpen: boolean;
  isAuthenticated: boolean;
  selectedReaction: string | null;
  isSaved: boolean;
  replyCount: number;
  pageUrl: string;
  object: Record<string, unknown> | null;
  resolvedDiscussion: unknown;
  configId: string;
  theme: string | null;
}

Before the async runtime is installed, the bootstrap instead returns { loaded: false, pending: number }. That lets host telemetry distinguish a queued bootstrap from a booted widget.

window.zeeker.on(event, handler) ​

Register an event listener. See Events for the full list.

js
window.zeeker.on('ready', state => console.log('widget ready', state));

window.zeeker.off(event, handler?) ​

Remove a listener. Omit handler to remove all listeners for an event.

js
window.zeeker.off('ready');
window.zeeker.off('reaction', myHandler);

Calling before the runtime is ready ​

You do not need to implement a second command queue. Once the bootstrap script has executed, its methods accept and queue calls until runtime.min.js is ready:

html
<script
  id="zeeker-loader"
  src="https://embed.zeeker.com/api/embed/widget/loader.js"
  data-zeeker-config="YOUR_CONFIG_ID"
  async
></script>
<script>
  document.getElementById('zeeker-loader').addEventListener('load', () => {
    window.zeeker.on('ready', state => console.log(state));
    window.zeeker.identify(yourJwt);
  });
</script>

If the host only needs to provide page-object data before the external script arrives, seed that data without replacing the API methods:

html
<script>
  window.zeeker = {
    object: { type: 'article', id: 'article-123', url: location.href }
  };
</script>

TypeScript types ​

Add this to your project for type-checking:

ts
declare global {
  interface Window {
    zeeker?: {
      open(): void;
      close(): void;
      identify(jwt: string | null): void;
      identifyObject(object: {
        appId: string;
        objectType: string;
        objectId: string;
        title?: string;
        description?: string;
        imageUrl?: string;
        url?: string;
      }): boolean | void;
      logout(): void;
      refresh(): void;
      load?(): void;
      getState(): {
        loaded: false;
        pending: number;
      } | {
        postId: string | null;
        panelOpen: boolean;
        isAuthenticated: boolean;
        selectedReaction: string | null;
        isSaved: boolean;
        replyCount: number;
        pageUrl: string;
        object: Record<string, unknown> | null;
        resolvedDiscussion: unknown;
        configId: string;
        theme: string | null;
      };
      on(event: string, handler: (payload?: unknown) => void): void;
      off(event: string, handler?: (payload?: unknown) => void): void;
    };
  }
}
export {};