SPOT Writer Web Integration Guide
This document describes how to embed SPOT Writer into a parent site. It is intended for developers implementing site-side workflows such as “Program Receiver” or “Write to SPOT”.
SPOT Writer is intentionally narrow in scope. It does not edit radio content. It accepts a SPOT JSON configuration, connects to a receiver with Web Serial, and writes that configuration to the receiver.
Overview
The web integration model is simple:
- Your site launches SPOT Writer in embedded mode.
-
SPOT Writer sends a
readystatus back to the parent. -
Your site sends a SPOT JSON configuration to
SPOT Writer with
postMessage. - SPOT Writer loads the configuration and writes it to the receiver when the user presses Write.
-
SPOT Writer reports status
changes back to the parent site with additional
postMessageevents.
Requirements
-
The writer page must be served from a secure context. In
production this means
https://. For local testing,http://localhostis acceptable. - The browser must support the Web Serial API.
- The receiver must be connected by USB and powered on before the user attempts to write.
-
Your site may require
allow="serial"in theiframedefinition.
Launch Modes
SPOT Writer supports two site integration styles:
- iframe: recommended when you want the writer visually contained within the parent page.
- popup window: useful when you want the writer isolated in its own window or tab.
In both cases, embedded mode is enabled by loading the writer
with ?embedded in the URL. For example:
https://spotwildlife.org/tools/spot_writer/?embedded
Parent to Writer Message
Once the writer reports that it is ready, the parent site sends a configuration message:
childWindow.postMessage(
{
type: "spot-writer-config",
configText: "{...raw SPOT JSON text...}",
configSource: "Wildlife Central",
showReturnButton: true
},
targetOrigin
);
Fields
-
type: must be"spot-writer-config" -
configText: required SPOT JSON text -
configSource: optional source name shown in the writer UI -
showReturnButton: optional boolean; if true, the writer shows a “Return to …” button
The parent should wait for the writer to send
code: "ready" before posting the first
configuration. After that, the parent may send a replacement
configuration later if it wants to re-arm the same writer page
for another write.
In production, use a specific targetOrigin rather
than "*" when calling postMessage.
Writer to Parent Status
The writer reports its state to the parent site with
spot-writer-status messages:
{
type: "spot-writer-status",
code: "ready" |
"config-accepted" |
"config-rejected" |
"write-started" |
"write-succeeded" |
"write-failed",
message: "Human-readable status text"
}
Status Codes
-
ready: the writer page is loaded and ready to receive a configuration -
config-accepted: the supplied JSON was accepted and loaded -
config-rejected: the supplied JSON was rejected, or a new config arrived while the writer was busy -
write-started: writing has begun; the parent should stop sending replacement configs -
write-succeeded: the write completed successfully -
write-failed: the write failed, including connect failures that prevent writing from starting
If the parent supplies invalid JSON, the writer shows an error in
its own status area and also sends
code: "config-rejected" back to the parent.
Multiple Configurations
The writer can accept more than one parent-supplied
configuration over time. Each accepted
spot-writer-config message replaces the currently
loaded configuration, which allows the parent to re-arm the
writer for another programming pass without reloading the page.
However, if a new configuration arrives while the writer is busy
loading, connecting, or writing, the writer rejects it and sends
spot-writer-status with
code: "config-rejected".
iframe Example
<iframe
id="spot-writer-frame"
src="https://spotwildlife.org/tools/spot_writer/?embedded"
title="SPOT Writer"
></iframe>
const frame = document.getElementById("spot-writer-frame");
const writerOrigin = "https://your-host.example";
const configText = "...raw SPOT JSON text...";
window.addEventListener("message", (event) => {
if (event.origin !== writerOrigin) {
return;
}
if (event.data?.type !== "spot-writer-status") {
return;
}
if (event.data.code === "ready") {
frame.contentWindow?.postMessage(
{
type: "spot-writer-config",
configText,
configSource: "Your Site",
showReturnButton: false
},
writerOrigin
);
}
});
In an iframe integration, the writer remains part of the parent
page, so showReturnButton is usually left
false.
Popup Example
const writerUrl = "https://spotwildlife.org/tools/spot_writer/?embedded";
const writerOrigin = "https://your-host.example";
const popup = window.open(writerUrl, "spot-writer", "popup,width=1280,height=980");
const configText = "...raw SPOT JSON text...";
window.addEventListener("message", (event) => {
if (event.origin !== writerOrigin) {
return;
}
if (event.source !== popup) {
return;
}
if (event.data?.type !== "spot-writer-status") {
return;
}
if (event.data.code === "ready") {
popup?.postMessage(
{
type: "spot-writer-config",
configText,
configSource: "Your Site",
showReturnButton: true
},
writerOrigin
);
}
});
Popup mode is useful when the writer should run in a separate
window or tab. If your site wants the writer page to offer a
return path, set showReturnButton: true. The writer
uses browser history first and falls back to
window.close() when possible.
Practical Notes
- If the user previously chose the wrong serial port and a connection fails, the writer clears remembered serial-port permissions before the next attempt so the browser can prompt again.
-
A parent site may choose to visibly react to status messages
such as
write-started,write-succeeded, andwrite-failed, but that is a site-level policy decision rather than a requirement of the writer. -
Sample integration pages are included with the writer
distribution under
/tools/spot_writer/samples/. - While in embedded mode, SPOT Writer trusts the JSON file sent to it by the parent. In particular, if the parent sends a JSON file with device-specific information, it will be programmed into the target device without question or warning.
Implementation Checklist
-
In general, use the hosted SPOT Writer at
https://spotwildlife.org/tools/spot_writer. -
Listen for
spot-writer-statusand wait forready. -
Send a
spot-writer-configmessage containing valid SPOT JSON text. -
React to
config-rejected,write-started,write-succeeded, andwrite-failedin a way that fits your site. - If you support repeated programming from the same page, only send replacement configs when the writer is not busy.
Testing
For local testing, the sample pages bundled with SPOT Writer are a useful starting point:
/tools/spot_writer/samples/wildlife-central.html/tools/spot_writer/samples/wildlife-popup.html
These demonstrate the expected message exchange and can be used to validate a local or staging deployment before integrating with a production site.