Repository navigation
Releases: MeshCore-Beacon/beacon-web
Release list
Beacon Web - v2.0.5
Beacon Web 2.0.5
Improvements
- Hash search now finds older packets. Typing 4 to 16 hex characters asks the server for every matching packet instead of only filtering what's already loaded, and live packets still filter as they arrive.
- Clearing a search box restores the full list right away.
- Node details show MeshMapper repeater info when available: site details, admins, default and confirmed scopes, and when it was last fetched. CARpeaters get a badge next to their name.
Upgrade notes
- Built for Beacon Server 2.0.7. On older servers hash search falls back to the loaded packets and the MeshMapper section stays hidden; nothing breaks.
Beacon Web - v2.0.4
Beacon Web 2.0.4
Improvements
- Top advertisers can be ranked by flood or direct adverts with a new Flood / Direct toggle (flood by default). The server now does the ranking, so the list is correct and no longer favours chatty direct-routed nodes.
- Bump source-map-js to 1.2.2 (CVE-2026-93749, build-time only).
Bug fixes
- Chart colours no longer collide in themes that reuse a colour (Phosphor, Radar, Amber, Earth). Every other theme looks exactly as before. Thanks @Bjorkan!
Upgrade notes
- Requires Beacon Server 2.0.5. Top advertisers needs the server's new
sortparameter. - Beacon Server 2.0.5 requires Beacon Web 2.0.4 or newer. Older web builds show a full-screen reload screen, so pull the web image together with the server.
Beacon Web - v2.0.3
Beacon Web 2.0.3
Improvements
- Route search makes at most two requests per search instead of one per pair of areas. Searching many areas no longer floods the server.
- The area picker is optional: with nothing picked, search uses your region, or every area. Up to 100 areas can be picked.
- Routes within an area and routes that cross between areas now share one table, shortest first.
- A new search, Clear, or leaving the page cancels a search still in progress.
Bug fixes
- A failed route search now shows the server's message or a timeout notice instead of "no routes".
- Hashes are checked before searching (2, 4, 6 or 8 hex characters).
Upgrade notes
- Requires Beacon Server 2.0.4. Upgrade the server first; route search fails against older servers.
- Beacon Server 2.0.4 requires Beacon Web 2.0.3 or newer. Older web builds show a full-screen reload screen, so pull the web image together with the server. Operators can raise the minimum with
web.min_web_version.
Beacon Web - v2.0.2
Beacon Web 2.0.2
Improvements
- The observer directory now loads in pages, with server-side filtering and sorting by name or available traffic over the last seven days.
- Traffic rankings use the available history, clearly flag incomplete coverage, and stay independent of the dashboard time range.
Bug fixes
- Fixed channel-page scrolling and missed bottom-navigation taps on mobile.
Upgrade notes
- Upgrade Beacon Server alongside the web app: the observer directory requires the new
/observers/directoryAPI. - MeshMapper integration requires an API key. The same regional or grouped-region key that regional admins generate for coverage now works for the MeshMapper APIs Beacon uses.
- Set
MESHMAPPER_API_KEYin the backend environment and recreate the backend container. Without a key, Beacon keeps running and retains saved imports, but MeshMapper imports do not refresh.
Beacon Web - v2.0.1
Beacon Web 2.0.1
Thanks to Bjorkan for the Swedish translation.
Runs with any Beacon Server 2.0.x. Nothing to change on upgrade: pull the new image.
Languages
- Swedish. Pick Svenska in the header language picker.
Beacon Web - v2.0.0
Beacon Web 2.0.0
A huge thank you to n30nex for helping get Beacon to this point. Many of the dashboards and features in 2.0.0, from the observer dashboard and the new analytics tabs to channel scopes and the French translation, are there because of his help.
This release pairs with Beacon Server 2.0.0 and needs it: the analytics tabs, observer dashboard and region-filtered scope lists all read endpoints that only exist on 2.0.0.
Breaking change: the server needs a fresh database
Server 2.0.0 starts from a new schema baseline and will not run against a 1.x database. 1.x history does not carry over. There is nothing to migrate on the web side, but read the upgrade guide before you pull either image. The deployment template now requires an explicit BEACON_WEB_IMAGE.
Built for big instances
MeshMapper's instance at analyzer.meshmapper.net handles around 400,000 packets every 15 minutes on 2.0.0 and barely sweats. On the web side, analytics now read the server's hourly rollups instead of live scans, the packet-path canvas loads on demand, lists wait for the selected region before requesting, and the client backs off cleanly when the server rate limits it.
MeshMapper integration
MeshMapper has expanded its API and Beacon Server now ingests it: scoped traffic is tagged from MeshMapper's scope catalogues, regions and geo borders can be set up automatically from its zones, and regional public channels are imported. In the web app that shows up as region-filtered scope lists, scope chips on packets and channel messages, imported region borders on the map, and the Possibly foreign label on repeaters.
Versioning from here on
Starting with 2.0.0, Beacon Web and Beacon Server share the same major and minor version. Only the patch number moves on its own, so web 2.0.1 runs with server 2.0.3. Keep both on the same 2.X. The latest image tag is now reserved for stable releases from main; pin :2.0 on both images if you want to choose when to move to the next minor.
Everything since v1.3.0
Observers
- The Observers tab is now a dashboard. The list sits beside it on desktop with status, type, broker, scope and name filters, Activity or Name sort, hearing counts and activity bars, and live status over the websocket.
- The dashboard leads with packets heard per hour and day, packet-type mix, received signal, airtime TX and RX, and device telemetry (battery, uptime, noise floor, queue length, receive errors, channel busy) over 24h, 7d or 30d.
- Airtime is charted as a percent of elapsed time, and four heard-activity charts (channel busy, packets heard, SNR heard, payload type) come from the new per-observer activity endpoint.
- Observer header shows labelled device, public key, brokers and first seen rows, with Copy link and Compare with actions.
- Compare with compares two observers on aligned windows, with packet overlap at 24h and 7d.
- Adverts heard is a collapsible section inside the dashboard.
- Inspect observer from a packet observation opens the dashboard directly and keeps the packet in the side drawer on desktop. On mobile it opens as an overlay, and Close steps back to the packet it came from.
- The Analytics Observer section is gone. Old
?statsTab=observerlinks land on the Observers tab.
Analytics
- Analytics is served from the server's hourly rollups. Sparklines break at missing or partial hours instead of joining across them, and hours before the first rollup draw as gaps instead of zero.
- Hourly sparklines on every stat card backed by hourly data (Mesh, Traffic, Signal, Paths), plus Most path entries, the Scoped packets and Active scopes cards, and the Observers and Default-scope nodes cards on Scopes.
- New RF / Signal tab: SNR and RSSI distributions, hourly means, sample availability and exact tables.
- New Paths and Hashes tab: hash-width share, received entry counts, hourly trends, coverage categories and exact tables.
- New Traffic tab: hourly reception trends by IATA, a UTC heatmap, reception share and exact counts.
- New Scopes tab: scope charts, search and exact counts. The Mesh scope card follows the selected region.
- New Compare observers tab: pick two observers and a time window to see distinct flood packets heard only by A, only by B or both. The URL carries the selection.
- KPI cards say Last 24h, and a region with no IATAs shows empty data instead of the whole network.
- Refresh buttons and repeated page titles are gone (data reloads every minute). Explanations moved into info tooltips beside the section chooser.
- Talkers rows open the node, and Talkers and Mesh overview no longer show stale rows or previous-region data while a refresh is pending.
- Clock Drift shows compact cards on phones. Charts are drawn in UTC consistently.
Packets and analyzer
- One Observations list in the analyzer. Reception evidence and the Observations dropdown are merged into a single section grouped by path, each report a selectable signal card with Inspect observer and Map report links. It starts collapsed with counts visible and opens when a specific report was picked.
- Observation card edges are coloured by SNR level, and expanded rows show observation cards below the md breakpoint.
- Packet Structure breaks out the transport codes (bytes, value, matched scope). The raw hex view on TRANSPORT packets was off by the 4 transport-code bytes and is fixed.
- Payload summaries appear in packet rows without opening the packet: adverts show one node chip and trace and ACK summaries replace n/a.
- Latest path search: enter whole hop hashes to filter loaded packets by consecutive hops.
- A
?hashselection outside the loaded results shows a notice with an Open analyzer action. - Load older packets button when filters leave too few rows to scroll.
- Endpoint chips show every ambiguous candidate without picking a winner.
- Route evidence is folded into Route Detail: clicking a route opens summary, hops, first and last seen, and a Recent packets list bounded by retention.
- The packet drawer and stacked windows stay open across tabs on desktop.
- Rate limiting is handled: a 429 shows a RATE LIMITED badge in the header, queries stop retrying 4xx, and websocket reconnects back off exponentially and jump to the longest wait on close codes 1008 and 1013.
- PING packets render with the TRACE payload renderer.
- The packet-path canvas loads on demand. The initial gzip payload dropped from 448 KB to 172 KB.
Channels
- Channels loads every channel Beacon has a key for first and hides the rest behind Load other channels.
- Channel messages show the packet scope, with a server-side Scope filter in the channel header. Unresolved scopes get a muted chip.
- Scope filter dropdowns on packets, nodes, observers and channels list only the selected region's scopes. A selected out-of-region scope stays so shared links keep filtering.
- Load more channels pages the directory without losing the open channel.
- Channel live messages recover after an overflow that settles under a 429.
Nodes and map
- Repeaters the server flags as
possiblyForeignshow a Possibly foreign label in rows, cards and the detail panel. - View on map in node panels opens the Map tab framed at zoom 14 and keeps the panel open on desktop.
- A node's position is cleared when the server sends an explicit null in
nodeUpdate. Explicit 0/0 resets and invalid coordinates are omitted from markers, neighbour lines, path maps and live flow. - Turning the IATA borders toggle off clears the drawn borders, and missing boundaries are retried.
- Map cluster clicks work again after a dataset reset.
- maplibre-gl 6.
Languages
- Language picker in the header with English and French. The choice is saved in the browser.
- Translated: navigation and shared controls, every analytics tab, Clock Drift, relative timestamps, observer monitoring, channel scopes, packet investigation, nodes, channels, map, packets (list, table, analyzer, observations), routes, traces, MapLibre control tooltips, chart series names and node type labels, with French plural forms.
- Kept in English on purpose: protocol and enum names, SNR, RSSI and dB units, theme names and raw node-type values.
Layout and mobile
- The header collapses to one row on phones with language, theme and GitHub in a menu. The region picker is left-anchored on phones and right-anchored on desktop.
- Region filter input is 16px on phones to avoid iOS focus zoom.
- Routes search stacks into from/to and IATA/Search rows on mobile. Observer list is edge-to-edge with row dividers on mobile, like Nodes.
- Stat card sublabels wrap under the title on narrow screens.
- Plain wording across panels: observations, Heard by N observers, Packets heard, area instead of IATA, sentence-case analytics tabs, Map path and Map all paths.
- Lists, map, neighbour graph and observer comparison wait for a named region's IATAs before requesting, so there is no brief whole-network fetch.
- Desktop tab order puts Observers after Nodes.
Configuration
- New
VITE_BANNER: an optional notice above the header on every page, for example on a test instance.[label](url)and bare URLs become links. - Runtime config is injected through
/config.jswritten at container start instead of rewriting the bundle. - The image workflow no longer publishes
latestfromdev. The deployment template requires an explicitBEACON_WEB_IMAGE. - Deployment docs moved to beacon-docs.
Fixes
- Compare tab no longer shows a spurious invalid link alert after a tab change.
- Observer Copy link keeps only region params.
- Route table no longer navigates on region change with no route open, and routes paging is tie-safe.
- Live o...
Beacon Web - v1.3.0
Beacon v1.3.0
A big release for the packet analyzer: the packet list becomes a full table with expandable per-observer detail, packet routes get a self-contained path map, Analytics gains Talkers and Clock Drift tabs, and the map picks up an IATA border overlay.
✨ Highlights
- Packet list is now a table. On desktop the list is a proper table with one-line rows under a sticky header, and expanding a row opens an inline per-observer breakdown in place of the old card.
- See a packet's route on a map. "View path on map" opens a self-contained mini-map of the packet's resolved route(s), floating over the analyzer so closing it returns you exactly where you were.
- Two new Analytics tabs. Talkers ranks top advertisers and sender names, and Clock Drift flags repeaters and room servers whose clock has drifted past the server threshold.
📥 Packets (new table layout)
- Single-line rows. Each packet is one row under a sticky header showing hash, type, route, observation count, hops, hash size, source → destination, IATA and age. Mobile keeps the card layout on narrow screens.
- Expand a row for per-observer detail. Opening a row reveals a timing strip (observer, first/last heard, spread) and a per-observer table with SNR, RSSI, propagation, hops and resolved path for each observer, plus loading, error/retry and empty states.
- Source → destination chips. The Src → Dst column shows a packet's resolved endpoints as confidence-tinted chips (high / ambiguous / unresolved) and truncates cleanly on narrow screens. Historical rows read n/a, since endpoints are only resolved on the live feed for now.
- Jump straight to an observation. Clicking an observation opens the analyzer on that exact observation.
- Separate link states for rows and the analyzer. ?hash expands a row and ?analyze=1 opens the analyzer drawer, independently. Closing the analyzer leaves the row expanded, and a reload no longer reopens a drawer you closed.
- Live detail while open. While a row is open, its detail refreshes on each new observation, so the table keeps pace as the count ticks up.
🧭 Packet path map
- View path on map. From the analyzer or an expanded row, this opens a self-contained mini-map of the packet's resolved route(s). It floats over the analyzer instead of switching tabs, so closing returns you where you were.
- A path per observation. One coloured route per observation, sorted fastest first. "All paths" overlays every route, and clicking an observer isolates theirs. Path nodes are tappable for name and coordinates.
- Full chain, no guessing. Paths draw source → relay hops → destination. Endpoints are only plotted when they resolved unambiguously, so an ambiguous 1-byte prefix is left off rather than guessed.
- Shareable. ?path= deep links open a specific route. On mobile, attribution collapses to a small (i) so it doesn't cover the observer list.
- Accurate live animation. The live map flow now follows the same source → hops → destination chain, so packets animate from where they originated instead of the first relay.
📊 Analytics
- Talkers tab. Top advertisers with a flood/direct split, per-day rate, and node type and IATA per row, beside a top-talkers leaderboard grouped by decrypted sender name.
- Clock Drift tab. Repeaters and room servers whose advert-derived clock has drifted past the server threshold, worst first, with anything 1h or more off flagged red. It isn't time-windowed, so there's no range selector.
- Clock drift on node detail. The node detail panel now shows a node's clock drift (+42s ahead, -1h 1m behind, or in sync).
- Overview sparklines match their number. Overview KPI sparklines are pinned to a fixed 24h window instead of following the selected range, so the figure and its sparkline agree.
📡 Nodes
- Search by public-key prefix. The Nodes table now searches by public-key prefix as well as name. Switching field clears the box, and non-hex characters are ignored rather than sent, which previously errored the whole table.
🗺️ Map
- IATA border overlay. Toggleable region outlines with a themed legend, remembered like your other map settings and shareable via ?borders=. Borders load only while the layer is on, and IATAs with no configured border are skipped.
🐛 Fixes
- Multi-select packet filters now apply server-side. Previously a filter only took effect server-side when exactly one value was picked, so paging through multi-select results pulled unfiltered history.
- ?hash is no longer stripped on load, so deep links to older packets work again.
- Live re-observations now widen a packet's heard window instead of replacing it, so an expanded row's spread no longer reads 0 for re-heard packets.
- ?path deep links restore correctly when ?analyze is absent.
- Message bodies keep their line breaks in channel messages and in TEXT, RESPONSE and GROUP_TEXT payloads.
- TRACE paths now resolve like every other path, showing real hop names instead of raw hex.
- From/To/Dest hashes in encrypted-envelope and anonymous-request payloads now resolve to clickable node blocks, like path hops.
- The analyzer closes on a mobile tab change, and expanded rows now have a copy-link button.
- The region picker can be filtered by IATA code, airport name or region name.
- Row-height estimates match the new one-line desktop rows, so the list no longer jumps while scrolling.
Beacon Web - v1.2.0
Beacon v1.2.0
A big release for the mesh packet analyzer: the map now animates live traffic and shares as a link, "Stats" grows into an interactive Analytics tab with a whole-mesh neighbour graph, traces tell route-traces apart from pings, and self-hosters get a set of new customization switches.
✨ Highlights
- Watch the mesh live. A new Live button on the map animates each packet as a glowing dot travelling hop-by-hop along its real route, with a fading trail and a per-node flash.
- See the whole topology. The renamed Analytics tab adds an interactive Neighbour Graph, every node as a dot linked to the neighbours it has heard, colour-coded and clickable.
- Share the exact view. A Copy map link button captures your camera, basemap, filters and live state in a URL. Paste it and the recipient lands on precisely what you were looking at.
🗺️ Map
- Live packet flow. Press Live (bottom-center) to animate real-time traffic; nodes dim to the background and flash as a packet crosses them. Off by default; a shared link can open with it running.
- Neighbour links on selection. Clicking a node now draws its neighbour lines immediately (new "Selected" default), spotlighting that node and dimming the rest of the map.
- Links coloured by strength and freshness. Neighbour lines run red → yellow → green by how often a link was heard, and fade as the last contact gets older. A colour legend sits in Map Settings.
- Copy map link. Share your exact view (center, zoom, basemap, clustering, node-type filter, neighbour-lines mode, live on/off). Following a link never overwrites your own saved preferences.
- Remembered map settings. Clustering and the node-type filter now persist between visits.
📊 Analytics (formerly "Stats")
- Renamed to Analytics. Old bookmarks and links to the Stats tab still work.
- Interactive Neighbour Graph. Every node in a region is a dot joined to its heard neighbours, coloured by device type, sized by connectivity, with labels on the busiest hubs. Pan, zoom, drag.
- Search the graph by name. Type a node name and matches stay bright while the rest of the mesh fades far back, so one station pops out of a crowded web.
- Click to focus a node. Drill into a single node's neighbourhood, with links coloured by observation count and staleness. Click empty space to return to the full mesh.
- Node Types donut. The old "Coming soon" card now shows a live device-type breakdown with the total in the middle.
- Radio presets split. Each preset bar now stacks nodes vs. observers with a combined total.
- Clearer time windows. Charts are reordered and titled by their range vs. "all time". The summary tiles' window label now comes from the server instead of a fixed "24h".
- Mobile-friendly header. The section picker becomes a dropdown and the time-range buttons wrap on phones, so every control stays reachable.
🔀 Traces
- Trace vs. Ping. Each card carries a colour-coded label (amber TRACE / blue PING) and an All / Trace / Ping filter with a running count.
- Signal strength along the path. Cards preview the hop-by-hop route with per-hop SNR (dB), colour-coded good/medium/poor, from the most complete observation.
📡 Nodes & Observers
- Neighbour count. A new sortable Neighbors column in the node table, a count on mobile cards, and the neighbour's public-key prefix shown on each neighbour row in the detail panel.
- Copy public key. One-click copy beside a node's or observer's key, with a "Copied" confirmation.
- Copy Link on detail panels. Share a direct link that reopens that exact node or observer (region preserved). Shared links now reopen reliably on load.
- Minimize on mobile. The full-screen node panel can shrink to a bottom bar without deselecting, so you can peek at the map and its neighbour lines underneath.
📥 Packets
- Stable list while scrolled. New live packets no longer push or jump the rows you're reading. The live indicator becomes a "N new packets · scroll to top" button that counts what you missed and catches you up in one click. Switching regions snaps back to the top.
🛠️ For self-hosters
- Hide tabs. VITE_DISABLED_TABS removes any top-level tabs you don't want (safely ignored if it would hide everything).
- Theme allowlist. VITE_ENABLED_THEMES is now an exclusive allowlist. Two new MeshMapper themes (dark and light) ship but stay hidden unless allowed.
- Custom app name. VITE_APP_NAME rebrands the wordmark and footer (keeps your capitalization; avoid & and |).
- Skip the load splash. VITE_SKIP_SPLASH=true for kiosk/embedded/instant-load deployments.
- GitHub link. A header icon linking to the project.
- Public Docker images. Images are public on GHCR, so
docker compose upno longer needsdocker loginor a token. - :dev image tag. Pushes to dev now publish a separate :dev image for following the development build.
🐛 Fixes & maintenance
- Multi-airport regions now filter Analytics correctly (previously fell back to global totals).
- Observer airtime / receive-error charts are accurate over 7d and 30d (pair with the matching beacon-server version).
- Shared detail-panel links no longer get wiped during page load.
- Dependency bump (undici). Docker publish workflow fixed to post images publicly.
Beacon Web - v1.1.0 - Inital Release
New Features
- Traces vs pings view for comparing the two
- SNR now shown for the trace path in the list
- Known neighbour count added
- Live node-types donut chart, replacing the old "Coming soon" placeholder
Improvements
- Multi-IATA regions now filter correctly instead of falling back to showing everything
- Radio presets keep the node vs observer split with stacked bars
- Stats charts now lead with the selected range and follow with all-time, and the KPI window follows your overview setting instead of a fixed 24 hours
- Telemetry timestamps are consistent across both data paths
Bug Fixes
- Fixed the GitHub workflow
- Post images now publish publicly
Beacon Web - v1.0.0 - Inital Release
Initial Release