Docs

Developer guide

Integrate the extension into any http or https page. The extension finds forms by DOM attributes, not by a JS register API.

1. Add a marker element

Required: data-ext-fetch and data-ext-fetch-id. Put the marker where the icon should appear — the extension appends the button inside this element.

<div
  data-ext-fetch="dereg-rebate"
  data-ext-fetch-id="order-42"
  data-ext-fetch-name="Dereg rebate"
  data-ext-fetch-access-code="295161"
  data-ext-fetch-vehicle-slug="SNY3466Y"
  data-ext-fetch-intended-date="2026-10-02"
  data-ext-fetch-with-screenshot="true"
>
  Click the extension icon to fetch
</div>

2. Keep attributes in sync with your inputs

The extension does not read your <input> fields. It polls data-ext-fetch-* about every 500ms. Update the attributes whenever the user edits the form.

const marker = document.querySelector("[data-ext-fetch-id='order-42']");

accessCodeInput.addEventListener("input", () => {
  marker.dataset.extFetchAccessCode = accessCodeInput.value;
});
dataset.extFetchAccessCode maps to data-ext-fetch-access-code. Same pattern for vehicle slug and intended date.

3. Listen for the result

The event name includes your form id: form-result--order-42.

window.addEventListener("form-result--order-42", (event) => {
  const { formId, result } = event.detail;
  // result.records            [{ label, value }, ...]
  // result.screenshot         dereg rebate image, or null
  // result.screenshotTF       transfer fee image, or null
  // result.transferFeeError   set if combined TF step failed
  // result.originalDeregRebateData
  // result.originalTransferFeeData
});

4. Detect the extension

window.addEventListener("check-extension-info-result", (event) => {
  const info = event.detail.extensionInfo;
  // { version, name, short_name, icons, description } or missing
}, { once: true });

window.dispatchEvent(new CustomEvent("check-extension-info"));

If nothing replies within ~500ms, treat the extension as not installed. Re-check on visibilitychange and focus so a user who just enabled it is picked up.

Fetch modes

MarkerPages fetched
data-ext-fetch="dereg-rebate" (default) Dereg rebate, then transfer fee
Same + data-ext-fetch-single-fetch-only="true" Dereg rebate only
data-ext-fetch="transfer-fee" Transfer fee only

In combined mode, a transfer-fee failure is optional. You still get dereg rebate records, plus result.transferFeeError. A dereg-rebate failure is fatal and currently shows only in the side panel — the host page does not receive a window error event.

When the icon is disabled

The injected button stays disabled until all of these are set and valid:

Side panel

Clicking the icon opens the side panel and starts the fetch. If the user opens the panel first, the extension asks the page to sync via lta:ask-sync-app-form-input-values. You do not need to handle that event unless you want a custom sync — attribute polling already covers it.

The panel can also run a standalone dereg-rebate form when no host marker is present.

Version gate

If a newer extension version is published, the icon shows a badge. On click:

Iframes

The content script runs in every frame except LTA and Google. Put the marker inside the iframe document that owns the form. The result event fires on that iframe’s window, not the top page.

Firefox

Result event.detail is cloned with cloneInto so page scripts can read it. If your app re-dispatches that object into another context, clone it again the same way.

Known limits to plan around

Minimal integration

<form id="lta-form">
  <input name="accessCode" />
  <input name="vehicleSlug" />
  <input name="intendedDate" type="date" />
</form>

<div id="lta-marker"
     data-ext-fetch="dereg-rebate"
     data-ext-fetch-id="order-42"
     data-ext-fetch-name="Order 42"></div>

<script>
  const form = document.getElementById("lta-form");
  const marker = document.getElementById("lta-marker");

  function sync() {
    const data = new FormData(form);
    marker.dataset.extFetchAccessCode = data.get("accessCode") || "";
    marker.dataset.extFetchVehicleSlug = data.get("vehicleSlug") || "";
    marker.dataset.extFetchIntendedDate = data.get("intendedDate") || "";
  }

  form.addEventListener("input", sync);
  sync();

  window.addEventListener("form-result--order-42", (event) => {
    console.log(event.detail.result.records);
  });
</script>