Stationworks developers

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.

Code
<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 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.

Last modified on