Skip to content
XICBOT

Settings

Deutsch
Documentation · Website widget

JavaScript interface and browser storage

window.xicbot with einwilligen, widerrufen and stand, the messages between your page and the chat window, and each browser storage entry with its expiry.

In plain language

The embed code creates a small interface on your page. With it you connect your own consent banner to the chat window. The interface has three methods. This page explains what each method does. It also shows which messages pass between your page and the chat window. It lists each entry the embed code keeps in your browser storage. For each entry it says how long it stays.

Last updated

All documentation topics

The embed code creates a window.xicbot object on your page. Its three methods let your own consent banner work with the chat window. Below you will find what each method does, which messages pass between the loader and the chat window, and every entry the loader keeps in the storage of your page.

The window.xicbot interface

The loader sets up window.xicbot as soon as it runs; with the defer attribute from the embed code, that happens once the browser has parsed the page. If data-xicbot is missing or the base address does not resolve to an http or https URL, no object is created. A second copy of the embed code on the same page has no effect. The loader recognises its handle by a marker of its own, not by its methods: any object your page created under that name beforehand is replaced, including a stub with an einwilligen method. If your page defined the name as read-only, its object stays and the chat window runs without the loader's methods.

MethodEffect
einwilligen()Stores xicbot.einwilligung.<key> with the value ja for 180 days, loads the chat window in the background and returns true. Without usable storage the consent applies to the current page view.
widerrufen()Withdraws consent and closes the chat window if it is open. A loaded chat window withdraws the conversation's consent with the service; the loader then removes the stored conversation ID and takes the chat window out of the page. Returns a promise that resolves to true if the service confirmed the withdrawal within the time limit, otherwise to false.
stand()Returns an object with four fields describing the current state, removing expired entries along the way.

einwilligen()

  • Writes xicbot.einwilligung.<key> with the value ja. Each call restarts the 180-day period.
  • Loads the chat window in the background straight away, even while the page itself is still loading. If a widerrufen() is still waiting for its reply, the loader loads the new chat window right after the old one has been removed. Visitors open it through the launcher.
  • Returns true; consent applies from the moment of the call. If the browser refuses to store it, it applies to the current page view only: stand().einwilligung is true for now, but false on the next page until your banner calls einwilligen() again.
  • If the embed code carries data-einwilligung="erforderlich", which Consent before the first conversation adds, the loader waits for this call before loading the window on its own. A click on the launcher loads it earlier.
  • Consent given on your page does not replace the consent step in the chat window. If the assistant requires it, the window still asks before the first conversation.

widerrufen()

Call widerrufen() when a visitor takes back their consent in your banner.

  • Removes consent at once, that is xicbot.einwilligung.<key> and any consent that applied to the current page view only.
  • Takes a speech bubble from proactive outreach off the page at once. No new one appears until the next page view.
  • Discards a form handover from the previous page that has not been filled in yet and removes xicbot.formular.<key>.
  • Closes the chat window if it is open.
  • If the chat window is loaded, the loader asks it to withdraw the conversation's consent with the service. The window takes the same route as its Withdraw consent button. If the window is still loading, the loader only asks it when a conversation ID is stored, as soon as the window is ready. Without a chat window, no request goes to the service.
  • Waits no more than five seconds for the window's reply. During that time a click on the launcher opens nothing.
  • Then removes xicbot.gespraech.<key> and xicbot.besuch.<key> and takes the chat window out of the page, even if no reply arrived.
  • Returns a promise. It resolves to true if the service confirmed the withdrawal. false means there is no confirmation, for example because there is no conversation, no consent was given in the chat window, or no reply came within the time limit. A second call while the first is still waiting returns the same promise.

After the withdrawal the launcher stays on the page. Clicking it builds a fresh chat window that does not resume the earlier conversation; if the assistant requires consent, the window asks for it again. How visitors give consent inside the chat window is covered in Consent and visitor rights.

stand()

FieldTypeMeaning
torbooleantrue if the embed code carries data-einwilligung="erforderlich".
einwilligungbooleantrue if xicbot.einwilligung.<key> holds ja and has not expired, or if your page called einwilligen() during this page view and has not called widerrufen() since.
gespraechbooleantrue if an unexpired conversation ID is stored.
offenbooleantrue while the chat window is open.

The loader does not announce changes to this state. If your banner needs it, for example to show the right button, call stand() at the moment you need the answer.

The example connects two functions of your own banner to the chat window. The values in the embed code are shortened; copy your own embed code from the app. A script that runs before the loader will not find window.xicbot yet, so call the methods from your banner's events or after DOMContentLoaded at the earliest.

index.html html

<script src="https://cdn.xicbot.de/einbetten.js" data-xicbot="…" data-api="…" data-einwilligung="erforderlich" defer></script>
<script>
  // Visitor agrees in the banner
  function allowChat() {
    if (window.xicbot) window.xicbot.einwilligen();
  }

  // Visitor takes consent back
  function withdrawChat() {
    if (window.xicbot) window.xicbot.widerrufen();
  }
</script>

Messages between page and chat window

The chat window runs in an iframe with sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox", without allow-same-origin and with referrerpolicy="no-referrer". That gives it an opaque origin: it cannot reach into your page, your page cannot reach into it, and it cannot use storage of its own. When building it, the loader passes everything the window needs to start in the URL fragment rahmen.html#…: key, API address, the origin of your page, position, language, shape and width class of the shell, the stored conversation ID and the styling defaults read from the page. Browsers do not send the fragment to any server. Everything after that goes through postMessage; each message is an object with xb: 1 and an art field.

From the chat window to the loader

TypeFieldsWhen it is sent and what it does
bereittitel, farbe, platz, senkrecht, abstand_x, abstand_y, breite, hoehe, skalierung, rundung, avatar, sprache, plus ansprache_regeln and formulareOnce, as soon as the settings have loaded, even if the assistant is not ready yet. The loader applies language, name, colour, launcher image, position and dimensions and reports the shell. ansprache_regeln hands it the rules from Proactive outreach, of which it evaluates five at most; if the assistant is not ready yet, this list is empty and the loader shows no speech bubble. From formulare it takes over up to ten approved forms with up to 20 fields each.
aendernthe same styling fields, without rules or formsWhen the window is opened and when the tab becomes visible again, in each case no sooner than 60 seconds after the settings were last fetched and only if the styling has changed. The loader applies it without a page reload.
schliessennoneEscape inside the chat window, its close button, or declining consent in the window. The loader closes the window and moves focus to the launcher.
gespraechidAfter a conversation starts, carrying its ID; the loader stores it for 30 days. With an empty ID after Delete conversation in the window, or when the service no longer finds the stored conversation; the loader then removes the entry.
fokus-rausrueckwaertsTab or Shift+Tab leaves the last or first element of the window. The loader moves focus to the launcher; if the shell fills the screen, it sends back fokus-erste or fokus-letzte instead.
formular-fuellenaufruf, werkzeug, selektor, seite, felder, absenden, bestaetigtOnce, after the visitor has confirmed a form suggestion. The loader only fills in the form if bestaetigt is set and tool and selector match an approved form; see Form prefill.
widerrufen-quittungokReply to widerrufen. ok is true if the service withdrew the conversation's consent; without a conversation or after an error it is false. The loader passes the result on to widerrufen(), removes the stored conversation ID and the visit marker and takes the window out of the page.
wegnoneThe service reports the assistant as unknown (unknown_widget) or the demo as expired (demo_expired), whether while loading the settings, starting a conversation or loading the history. The loader removes the launcher, speech bubble and window; the stored conversation ID is kept.

The loader checks the dimensions from bereit and aendern again before applying them. A value outside its range is ignored while the remaining values still apply: abstand_x and abstand_y 0 to 400 pixels, breite 280 to 720 pixels, hoehe 320 to 1200 pixels, skalierung 80 to 150 percent, rundung 0 to 40 pixels. Until a valid message arrives, the loader uses a 20-pixel offset, a width of 384 and a height of 620 pixels, 100 percent scale and an 18-pixel radius. How these dimensions play out on the page is covered in Appearance and accessibility.

From the loader to the chat window

TypeFieldsWhen it is sent and what it does
oeffnennoneWhen the launcher opens the window. The window starts a conversation if none exists yet and any required consent has been given in the window, checks for changed settings, checks whether a staff member has taken over an ongoing conversation and puts focus in the text field.
schliessennoneWhen the window is closed. The chat window notes that it is closed and, until it is opened again, no longer checks on its own whether a staff member has taken over the conversation.
schalevoll, breiteOnce the window is ready, on opening, when the position or dimensions of the shell change, and when the viewport width crosses 560 pixels. voll is true up to a viewport width of 560 pixels. breite is handy below 640, tablet below 1024, desktop below 1536 pixels and breit above that.
fokus-erstenoneTab on the launcher while the window is open, or fokus-raus while the shell fills the screen. The window moves focus to its first focusable element, usually the shield icon Privacy in the header.
fokus-letztenoneShift+Tab on the launcher while the window is open, or a backward fokus-raus while the shell fills the screen. The window moves focus to its last focusable element, usually the send button; if that button is disabled, to the last focusable element before it.
formular-berichtaufruf, gefuellt, fehlend, gesperrt, abgesendet, gefundenOutcome of a fill instruction, sent only if it carries a call ID. The chat window passes it on to the service, and the visitor sees it on the suggestion card.
widerrufennoneAfter window.xicbot.widerrufen(); for a window that is still loading, as soon as it reports bereit, and the loader then applies nothing from that message. The window withdraws consent the same way as its Withdraw consent button and replies with widerrufen-quittung.

Checks on both sides

  • The loader only accepts messages sent by its own chat window (checked via event.source), whose origin is null or the origin of the base address, and which carry xb: 1.
  • The loader posts with the target * because the chat window has no origin that could be named. As long as there is no chat window, it sends nothing.
  • The chat window only accepts messages from its parent window whose origin equals the page origin it was given at start.
  • The chat window posts to the origin of your page, since its messages carry the conversation ID.
  • A message with an unknown art has no effect on either side.

Entries in browser storage

Because of the sandbox, the chat window cannot use storage of its own. Anything that has to survive a page change is therefore kept by the loader in the storage of your page, under the origin of your website. <key> stands for the value of data-xicbot in the embed code.

EntryStorageValueExpiryWrittenRemoved
xicbot.gespraech.<key>localStorageconversation ID30 days from the start of the conversationwhen a conversation starts in the chat windowafter Delete conversation in the window, when the service no longer finds the conversation, after widerrufen(), or on reading once expired
xicbot.einwilligung.<key>localStorageja180 days, restarted by every call to einwilligen()by window.xicbot.einwilligen()immediately on widerrufen(), or on reading once expired
xicbot.besuch.<key>localStorageja90 days from the last writewhen the chat window has loaded and an On a second visit rule is prepared for the current pageafter widerrufen(), or on reading once expired
xicbot.formular.<key>sessionStorage of the tabfill instruction including field values2 minuteswhen a confirmed form sits on another page of your website, right before the page changethe next time the loader starts in this tab, or immediately on widerrufen()

The expiry of the conversation ID runs from the start of the conversation and is not extended by later visits; after 30 days the visitor starts a new conversation. The visit marker holds only ja and no identifier. Entry names contain the key from the embed code, so after Generate a new key and replacing the embed code, the loader no longer reads the entries stored under the old name.

Storage format with expiry

Each entry the loader writes to localStorage is a JSON object holding the value and the expiry time in milliseconds since 1 January 1970:

localStorage json

{"wert":"ja","bis":1805000000000}
  • bis is the time of writing plus the expiry period.
  • On reading, an entry whose bis has passed counts as absent and the loader deletes it. Until it is read again, an expired entry stays in storage.
  • An entry in another format, such as plain text from an older loader version, is used as the value as it stands and gets an expiry on the next write. If only bis is missing, the entry does not expire.
  • Writing an empty value deletes the entry.
  • Storage errors, for instance blocked or full storage, are caught by the loader; the entry is then simply missing.

Form handover across a page change

If an approved form is set to live on another page of your website, the loader carries the confirmed instruction across the page change. The values do not travel in the URL but in the sessionStorage of the tab.

  • Content: aufruf, werkzeug, selektor, seite, up to 20 felder with their values, absenden, bestaetigt and bis.
  • It is only written for another page of the same origin, and the loader navigates to that page right afterwards. If the page is on a different domain or subdomain, no handover is created.
  • On its next start in this tab, the loader reads the entry once and deletes it straight away, even if it then discards it.
  • It is discarded if it cannot be read, if bis has passed or if it lies more than two minutes in the future.
  • It is only carried out once the chat window has reported the settings, and only on the page it was written for, which must also be the page set for the form.
  • Without usable sessionStorage the page change does not happen; the chat window receives a formular-bericht with no fields filled.

Approval, field types and the filling itself are covered in Form prefill.

When the browser blocks storage

If the browser blocks storage for your page, every page view starts from scratch. Within a single page view the chat window works as usual, but it does not resume the conversation after a page change. The On a second visit rule does not fire. einwilligen() then applies to the current page view: stand().einwilligung is true, and with data-einwilligung="erforderlich" the window loads straight away. On the next page the loader waits again for einwilligen() or a click on the launcher.

Further reading

Frequent questions

How do I connect my consent banner to the chat?

Call window.xicbot.einwilligen() when the visitor agrees and window.xicbot.widerrufen() when they take it back. With Consent before the first conversation the embed code carries data-einwilligung="erforderlich", so the loader only loads the window on its own after einwilligen(); a click on the launcher loads it earlier.

Why does the chat window start a new conversation instead of resuming the old one?

A conversation only resumes if its ID is stored and the service still knows it. A new one starts if the ID is older than 30 days, the visitor chose Delete conversation, widerrufen() removed the ID, or the service no longer finds the conversation. The same applies if the browser blocks storage, if the page lives under a different origin, or if the embed code carries a new key.

How long does a conversation carry over between pages?

The ID stays in the localStorage of your page for 30 days from the start of the conversation. During that time the window resumes the conversation on any page of the same origin, provided the browser does not block storage.

Which entries does the widget keep in the browser?

Up to three localStorage entries, each with an expiry: the conversation ID, the consent and the visit marker. On top of that, a form handover sits in sessionStorage for two minutes at most. The table above lists value, expiry and trigger for each entry.

Can my page open the chat window by script?

window.xicbot has no method for that; it only offers einwilligen(), widerrufen() and stand(). Visitors open the window through the launcher.

Something still unclear?

Tell us which page and which step you mean. We reply personally.

Enquiry in three steps

  1. 1. Topic
  2. 2. Your case
  3. 3. Contact

What is this about?

One click is enough, everything else is optional.

Tell us briefly about your case

Everything in this step is optional. It helps us reply with something concrete straight away instead of asking back.

Enquiries per month, roughly (optional)
When should it start? (optional)
How can we reach you?

Name and email address are enough. We reply personally.

We use your details to handle your enquiry. More on this in the privacy policy.