Add Umami to the BlockExplorer frontend the way the data explorer does it: the umami.arkiv.network script in frontend/index.html, a track() helper for custom events, and an events table in the README.
The BlockExplorer reports no usage numbers, so there is no way to tell which pages and filters get used once the restyle lands. The explorer's setup (app/layout.tsx, lib/analytics.ts, README Analytics section) is the reference: no PII, fixed labels or buckets only.
How the data explorer does it
app/layout.tsx loads https://umami.arkiv.network/script.js deferred, with data-website-id and data-exclude-search="true".
lib/analytics.ts exports track(name, data). It is a no-op when the script is blocked, so callers never guard.
- Plain links use
data-umami-event and data-umami-event-url attributes instead of a handler.
- The README has an Analytics section with one table row per event. Adding or renaming an event updates the table in the same PR.
- No PII. Every event value is a fixed label or a bucket. No query text, keys, or addresses.
Proposed setup for the block explorer
-
Own website in Umami. Create a second website for the block explorer so its numbers do not mix with the data explorer's.
-
Website id from the environment. Add VITE_UMAMI_WEBSITE_ID to RUNTIME_CONFIG_ENV_NAMES in frontend/server.js so it ships through /config.js like the other settings. In frontend/index.html, after the config.js script, a small inline snippet appends the Umami script only when the id is set. Local dev and forks then send nothing.
-
Manual page views. The block explorer routes with ?view= and puts block numbers, addresses, and entity keys in the query string. The explorer's data-exclude-search would fold every page into /, and sending the query would leak addresses. Set data-auto-track="false" and send a page view on every view change with the view name as the url, for example /blocks or /entity, and nothing else.
-
Helper. Copy lib/analytics.ts to frontend/src/analytics.ts unchanged.
-
First event set. Mirror the explorer's names where the meaning is the same.
| Event |
Data |
Fires when |
query-executed |
source (node, index, compare), queryType (key-lookup, owner, expression), trigger (button, keyboard, example, shared-link) |
a Data page query is submitted |
query-result |
outcome (results, empty, error), resultBucket (0, 1-10, 11-50, 51+) |
the query returns or fails |
entity-action |
action (filter, add-to-query, copy-value, copy-link, copy-payload) |
an action is taken on an entity card |
filter-applied |
view, field |
a list filter is submitted on Blocks, Address, Senders, Records, or Ranges |
copy |
kind (hash, address, block, link) |
a copy button is used |
chart-selected |
chart |
a chart is picked on the Charts page |
theme-toggled |
theme (light, dark) |
the header toggle is used |
outbound-link-click |
url |
Feedback, llms.txt, or docs links are followed |
-
README. Add an Analytics section with the table above and the same no-PII note as the explorer.
Add Umami to the BlockExplorer frontend the way the data explorer does it: the
umami.arkiv.networkscript infrontend/index.html, atrack()helper for custom events, and an events table in the README.The BlockExplorer reports no usage numbers, so there is no way to tell which pages and filters get used once the restyle lands. The explorer's setup (
app/layout.tsx,lib/analytics.ts, README Analytics section) is the reference: no PII, fixed labels or buckets only.How the data explorer does it
app/layout.tsxloadshttps://umami.arkiv.network/script.jsdeferred, withdata-website-idanddata-exclude-search="true".lib/analytics.tsexportstrack(name, data). It is a no-op when the script is blocked, so callers never guard.data-umami-eventanddata-umami-event-urlattributes instead of a handler.Proposed setup for the block explorer
Own website in Umami. Create a second website for the block explorer so its numbers do not mix with the data explorer's.
Website id from the environment. Add
VITE_UMAMI_WEBSITE_IDtoRUNTIME_CONFIG_ENV_NAMESinfrontend/server.jsso it ships through/config.jslike the other settings. Infrontend/index.html, after theconfig.jsscript, a small inline snippet appends the Umami script only when the id is set. Local dev and forks then send nothing.Manual page views. The block explorer routes with
?view=and puts block numbers, addresses, and entity keys in the query string. The explorer'sdata-exclude-searchwould fold every page into/, and sending the query would leak addresses. Setdata-auto-track="false"and send a page view on every view change with the view name as the url, for example/blocksor/entity, and nothing else.Helper. Copy
lib/analytics.tstofrontend/src/analytics.tsunchanged.First event set. Mirror the explorer's names where the meaning is the same.
query-executedsource(node,index,compare),queryType(key-lookup,owner,expression),trigger(button,keyboard,example,shared-link)query-resultoutcome(results,empty,error),resultBucket(0,1-10,11-50,51+)entity-actionaction(filter,add-to-query,copy-value,copy-link,copy-payload)filter-appliedview,fieldcopykind(hash,address,block,link)chart-selectedcharttheme-toggledtheme(light,dark)outbound-link-clickurlREADME. Add an Analytics section with the table above and the same no-PII note as the explorer.