---
url: https://docs.comnto.com/integration/window-api.md
description: >-
  Options accepted by window.comnto(options), mounting several widgets on one
  page, and re-rendering inside single page apps.
---

# Using the `window.comnto()` API

Call `window.comnto(options)` to mount the widget yourself. This returns an API object that lets you adjust theme, locale, or reload topics later. The loader is global, so you can call it multiple times for different containers.

> Always supply the site id via `site: 'your-site-id'` unless the target container already includes `data-site="your-site-id"`.

```html
<div id="comments"></div>
<script src="https://comnto.com/embed.js" defer></script>
<script>
  window.addEventListener('DOMContentLoaded', () => {
    const widget = window.comnto({
      el: '#comments',
      site: 'my-blog',
      topic: 'article-123',
      locale: 'en'
    });

    // Example: update theme when your site toggles dark mode
    // Note: If the theme is `auto`, this is usually unnecessary
    // the widget updates automatically. This is just a demo of the API.
    matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => {
      widget.setTheme(event.matches ? 'dark' : 'light');
    });
  });
</script>
```

## Options

| Option | Type | Description |
| --- | --- | --- |
| `el` | selector or `HTMLElement` | Target container. Defaults to `[data-comnto]`. |
| `site` | string | Site id. Required unless the target container carries `data-site`. |
| `topic` | string | Topic/thread id. When omitted a stable id is derived from the URL. |
| `locale` | string | Starting language for UI strings. |
| `theme` | string | `auto`, `light`, or `dark`. |
| `sort` | string | `popular`, `latest`, or `oldest`. |
| `colors` | object or array | Brand colour overrides. See [Appearance](/customization/appearance). |
| `localization` | object | Custom translation overrides (see [Localization](/customization/localization)). |
| `direction` | string | Optional text direction hint: `ltr`, `rtl`, or `auto`. |
| `sso` | string | Optional SSO token to authenticate the viewer immediately. You can reload with a new token later. |
| `login_button_visible` | boolean | Show the login button even in SSO-only mode. |
| `css` | string | Inline CSS override. The loader sanitises the snippet (no HTML tags or `javascript:` URLs) and caps it at 16 KB. |

> The full API surface—including methods such as `setLocale`, `setColors`, `reload`, and `on`—is covered in [Widget API Reference](/reference/widget-api).

> The comment box’s formatting tools, image limit, and mention limit are not options here. They are applied when a comment is saved rather than in the browser, so an embed cannot override them — set them in the dashboard instead, under [Editor Tools](/customization/editor-tools).

## Multiple widgets on one page

Call `window.comnto()` for each container. Reuse the same embed script; the loader will automatically create separate iframes.

```js
const articleWidget = window.comnto({ 
  el: '#article-comments', 
  site: 'my-blog', 
  topic: 'article-123'
});

const productWidget = window.comnto({
  el: '#product-comments',
  site: 'my-blog',
  topic: 'product-456',
  locale: 'fr'
});
```

Each call returns its own API object. Keep references so you can update or destroy the widget when the related content disappears.

## Working with single page apps

If your router swaps views without reloading the page:

1. Destroy the existing widget with `widget.destroy()` when the view unmounts.
2. Call `window.comnto()` again for the new container and topic.
3. Alternatively, if the container remains the same but only the topic changes, use `widget.reload({ topic: newTopicId })` to refresh the iframe in place.
