3 · Reacting to the result from your own JavaScript

The SDK writes four attributes onto the element it fills. Those attributes are the integration surface — read them, don't race the fetch. It also pushes two events to dataLayer, so GTM can react without any DOM code at all.

Switch the page language: English (default) Čeština (?lang=cs)

Watch the attributes

var el = document.getElementById("myDoc");

new MutationObserver(function () {
  if (el.getAttribute("data-waulter-document-state") !== "loaded") return;
  console.log({
    from:     el.getAttribute("data-waulter-document-resolved-from"),
    servedId: el.getAttribute("data-waulter-document-resolved-id"),
    language: el.getAttribute("data-waulter-document-language")
  });
}).observe(el, {
  attributes: true,
  attributeFilter: [
    "data-waulter-document-state",
    "data-waulter-document-resolved-from",
    "data-waulter-document-resolved-id",
    "data-waulter-document-language"
  ]
});
Do not poll on a fixed window. An earlier version of this very panel polled 30× at 200 ms and then stopped, freezing whatever it last read — so any fetch slower than six seconds showed loading permanently and looked like a failure. MutationObserver fires whenever the SDK writes, however long that takes.

Result

waiting…

What your own listener saw

(nothing yet)

dataLayer events

Both entry points push these, so GTM can trigger on them:

{ event: "waulter.document.loaded", elementId, requestedAgreementId, resolvedAgreementId }
{ event: "waulter.document.error",  elementId, requestedAgreementId, reason }

// reason ∈ empty_agreement_id | no_element | no_content | fetch_failed | sdk_never_started
(no document events on dataLayer yet)