# The GeoEngage widget

> What the GeoEngage widget does on your pages, its script tag attributes, and how to call its JavaScript API safely.

The widget is the script your tag loads. It applies the rules you publish, records analytics, and puts a small JavaScript API on `window.GeoEngage` for anything you'd like to do from your own code.

## What it does on a page

1. **Before the first paint**, the tag hides the elements a rule is about to change. It knows which from the rules that ran on the visitor's previous page view, so a visitor's very first page view has nothing hidden. Hidden elements reappear as soon as their rule has run, or after a time limit — 1.5 seconds by default — whichever comes first.
2. **In parallel**, the rest of the widget loads, looks up the visitor's location, and fetches your published rules and tracking settings.
3. **It checks every rule** against the visitor — location, device, traffic source, behavior, time and your own data — and applies the actions of the rules that match.
4. **It records analytics**: page views, plus the clicks, form submissions and scroll depth your tracking settings switch on.
5. **It follows navigation.** In a single-page app, each route change removes the last page's actions and checks the rules again.

## Script tag attributes

| Attribute | Values | What it does |
| --- | --- | --- |
| `data-api-key` | Your site's key | Required. Ties the page to one of your sites. |
| `data-require-consent` | `"true"` or `"false"` | `"true"` turns on [consent mode](https://geoengage.app/docs/widget/consent): nothing is tracked, and no rule but the compliance banner runs, until the visitor accepts. |
| `data-debug` | `"true"` or `"false"` | `"true"` logs each step to the console with a `[GeoEngage]` prefix. Warnings are logged either way. |

## Calling the API

The tag puts `window.GeoEngage` on the page as soon as it runs. The widget itself finishes loading a moment later, after your page's own scripts have started. What you can call in between depends on the method.

### Calls you can make straight away

Everything but the two questions below can be called any time after the tag has run, whether the widget has finished loading or not:

| Methods | Until the widget is ready |
| --- | --- |
| `identify`, `clearIdentity`, `setAttributes`, `clearAttributes`, `trackEvent`, `trackConversion`, `configure` | The call is held, then made for you, in order, as soon as the widget is ready. |
| `onReady`, `onAction`, `onEvent`, `onExitIntent` | The subscription is handed to the widget as soon as it starts, before any rule runs, so it hears the first page load too. |
| `grantConsent`, `revokeConsent` | The call is held until the widget checks for consent as it starts. In consent mode that's before ready, which only comes after consent. |
| `hasConsent` | Answered straight away. |
| `notifyRouteChange` | Ignored: the widget's first page view is of the page the visitor is on by then. |

```js
// In your app's start-up code, or in a script right after the tag.
GeoEngage.identify('jane@example.com');
GeoEngage.trackEvent('pricing_viewed');
GeoEngage.onAction('cta-click', ({ detail }) => console.log(detail.ruleName));
```

- A held call returns nothing, so don't use the return value of an early `setAttributes`. `grantConsent()` still returns its promise.
- In consent mode, the calls in the first row wait until the visitor has accepted.
- Up to 100 calls of each kind are held on a page.
- A script that runs before the tag finds no `GeoEngage`. Keep the tag in the `<head>`, above your own scripts. A script that has to run first can listen for the [`geoengage:ready`](https://geoengage.app/docs/widget/events#dom-events) event instead: its `detail` is `GeoEngage` itself.
- If an ad blocker or a security policy blocks the tag, `GeoEngage` never exists, and a call to it throws. Where that would break your page, such as in a checkout, write `window.GeoEngage?.trackConversion(...)`: the call then does nothing.

### Questions: ask them in `onReady`

`getLocation` and `getAttributes` answer a question, and nothing can answer before the widget has loaded: calling one then throws. Ask them inside [`onReady`](https://geoengage.app/docs/widget/events#onready), which runs your function once the widget is ready, or straight away if it already is, so it works wherever you call it. Your function is handed `GeoEngage` itself:

```js
GeoEngage.onReady((ge) => {
  console.log(ge.getLocation().country, ge.getAttributes());
});
```

In consent mode, `onReady` runs once the visitor has accepted. Consent has its own methods; see [Consent mode](https://geoengage.app/docs/widget/consent#the-consent-api).

`GeoEngage.version` holds the widget's version, which is also a quick way to check that it loaded.

## Debugging

Add `data-debug="true"` to the tag, reload, and open the browser console. The widget logs each step with a `[GeoEngage]` prefix: the location lookup, the rules it checks and what each action does. Take it out again before your changes go live.

## Starting the widget yourself

By default the widget starts as soon as the page's HTML has been parsed. To start it with options — such as the extra route-change detectors in [Single-page apps](https://geoengage.app/docs/widget/single-page-apps#extra-route-change-detectors) — set a flag before the tag, then call `GeoEngage.init()` once the widget has loaded:

```html
<script>window.__geoengage_no_auto_init = true;</script>
<script src="https://cdn.geoengage.app/ge.js" data-api-key="YOUR_API_KEY"></script>
<script>
  (function start() {
    // The tag puts GeoEngage on the page at once; init arrives with the widget.
    if (typeof window.GeoEngage?.init !== 'function') return setTimeout(start, 25);
    GeoEngage.init({ debug: true });
  })();
</script>
```

| Option | Type | What it does |
| --- | --- | --- |
| `debug` | boolean | The same as `data-debug`. |
| `excludeSelectors` | string[] | Elements the click tracker ignores. Replaces the list from your tracking settings. |
| `customSelectors` | object[] | Extra elements to track as calls to action, as `{ selector, name }`. Replaces the list from your tracking settings. |
| `tracking` | object | Overrides for your tracking settings, such as `autoTrack`. |
| `navigation` | object | Extra route-change detectors. See [Single-page apps](https://geoengage.app/docs/widget/single-page-apps#extra-route-change-detectors). |

---

Source: https://geoengage.app/docs/widget
