# Embed burn status

# Embed burn status

A complete example. Paste it into any page, set `AGENCY_ID` and `KEY`, and
it shows the district's verdict, fire danger and each burn status row, with
a link to the district's own rules. No framework, no build step.

```html
<div id="burn-status" data-agency-id="AGENCY_ID" data-key="KEY">
  <p class="verdict"></p>
  <p class="danger"></p>
  <ul class="rows"></ul>
  <p><a class="more" href="#">Full rules on the district's site</a></p>
</div>

<script>
  (async () => {
    const root = document.getElementById("burn-status");
    const { agencyId, key } = root.dataset;
    const url =
      "https://api.stationworks.app/v1/permits/agencies/" +
      encodeURIComponent(agencyId) +
      "/status?key=" +
      encodeURIComponent(key);

    // Words for the values we know today. An unknown value falls back to
    // the API's own label, so a new value never breaks the page.
    const STATE_WORDS = {
      open: "Open",
      restricted: "Restricted",
      closed: "Closed",
    };
    const DANGER_WORDS = {
      low: "Low",
      moderate: "Moderate",
      high: "High",
      very_high: "Very high",
      extreme: "Extreme",
    };

    let status;
    try {
      const res = await fetch(url);
      if (!res.ok) throw new Error("HTTP " + res.status);
      status = await res.json();
    } catch (err) {
      root.querySelector(".verdict").textContent =
        "Burn status is unavailable right now. Check the district's site.";
      return;
    }

    root.querySelector(".verdict").textContent = status.verdict.label;

    // Nullable: the district may not set a fire-danger level.
    root.querySelector(".danger").textContent =
      status.fireDanger == null
        ? "Fire danger: not set"
        : "Fire danger: " +
          (DANGER_WORDS[status.fireDanger] || status.fireDanger);

    const list = root.querySelector(".rows");
    for (const row of status.statuses) {
      const li = document.createElement("li");
      const word = STATE_WORDS[row.state] || row.state;
      li.textContent = row.label + ": " + word;
      list.appendChild(li);
    }

    root.querySelector(".more").href = status.agency.url;
  })();
</script>
```

## What the example does

- Reads the id and key from `data-` attributes, so the markup is the only
  thing to edit.
- Renders text with `textContent`, never `innerHTML`. Some fields, such as
  `rulesMarkdown`, are CommonMark written by the district; render them with
  a Markdown library and sanitize the result if you show them.
- Falls back to the raw value for an enum it does not know, and to "not
  set" for a `null`. Those two habits are the whole of what the
  [contract](/contract) asks of you.
- Shows one line when the request fails. Your last good response is a
  better fallback if you have one.

## Refreshing

Fetch once per page view. The edge caches for two minutes, so a timer that
refetches every 30 seconds gets the same response back. If you must keep a
page open for hours, refetch every two to five minutes.
