· 6 min read
Yuva 0.0.12: apps and servers in analytics, support next to traffic, and a security pass
Since 0.0.9, Yuva Analytics counts apps and backends, shows how much support each page causes, shares reports with people outside the team and remembers visitors who agree. Yuva also runs on Kubernetes, and 0.0.12 closes what our own security review found.
productdevbook
Version 0.0.9 brought analytics, newsletters and imports into the same workspace as the inbox. Three releases later, 0.0.12 is out. Most of the work went into analytics: it now counts your apps and your backend as well as your website, and it puts the support each page causes next to that page’s traffic. Yuva also has a Helm chart now, and 0.0.12 is mostly a security release.
Apps and backends in the same numbers
A website is often only half the product. The Swift and Kotlin libraries now send screens, events and revenue from iOS and Android apps to the same analytics property as your site. You choose the platforms a property counts in its settings, and the Install tab gives you code with your server already filled in.
The rules are the same as on the web. There is no device id, no advertising id and no cookie. Every launch gets a random key that lives in memory only, so a launch counts as a visit. Events wait in the app’s private storage, kept out of backups, until the server confirms it received them.
Some events only your backend sees: an account created, a payment that went through, a renewal. Server-side events send them with an API key. An event that carries the visitor’s address and browser joins that visitor’s visit on your site. The Go library has a package for this.
How much support each page causes
Link an analytics property to an inbox and every page shows its support numbers next to its views: conversations, page feedback, ratings and discussions, counted by page and day. The support rate shows which pages leave people with questions. A conversation started from the chat widget now records the page it started on, so the number reflects where the question actually came up.
The same numbers drive three features that need no checking on your part:
- Insights on the overview: short sentences about what changed and how much.
- Alerts, checked every hour: a traffic spike or drop, a goal suddenly converting at half its usual rate, a jump in conversations per page view, or a new site sending visitors. A finding goes on the chart as a note and comes to you by e-mail.
- Weekly and monthly reports by e-mail, in each member’s language.
All of them are fixed rules you can read in the guide. No model guesses on your behalf. If you use an AI assistant, the analytics tools of the MCP server can answer questions from the same data.
Newsletters are part of this too. When a broadcast goes out, Yuva adds UTM parameters to its links, so the visits it brings show up under Sources with the campaign’s name.
Showing your numbers to people outside the team
A share link opens a read-only report of one website without signing in, so you can send it to an investor or embed it on your own page. You choose which tabs it shows. You can add a password and an expiry date, and list the sites allowed to show it in an iframe. Yuva keeps only a hash of the link’s token and of its password. Revoking a link, or changing its password, ends access for everyone at once.
Exports write a website’s numbers to CSV, or its raw events to NDJSON, for your own tools.
Remembering the visitors who agree
By default Yuva Analytics cannot recognise a visitor from one day to the next, and that does not change. Consent features add more only for visitors who said yes. Your consent tool calls the script, or the app calls the library, and a random id is kept on that visitor’s device for at most 13 months. With it you get returning visitors, retention cohorts and funnels that span several days. For signed-in users, their recent visits appear on their contact page. Everyone who did not agree is counted exactly as before.
Yuva shows no banner of its own; you bring your consent tool. A browser that sends Do Not Track or Global Privacy Control never gets an id, whatever the consent tool says. Withdrawing consent removes the id from the device, and the server forgets its contact and retention data. The script with these features is a separate file, /yuva-analytics-consent.js, so sites that do not use them load nothing extra.
Kubernetes
Yuva now has a Helm chart at oci://ghcr.io/productdevbook/charts/yuva. It runs the server as a non-root user on a read-only file system, with all Linux capabilities dropped, and separates the metrics port from public traffic. The Compose quick start is still there for a single machine.
A security pass
For 0.0.12 we read the whole codebase with an eye for security, guided by Cloudflare’s open-source security audit skill, and fixed what it found:
- Go 1.27.2. The server was built on a Go version with twelve standard library advisories that our own code could reach. Two of them were in the HTML templates that render e-mail and the confirmation page; the others were in HTTP/1, HTTP/2 and TLS handling. CI now runs
govulncheckon every change, so this cannot quietly build up again. - Confirming a newsletter no longer proves who owns an address. Clicking a confirmation link shows that an address receives mail. It does not show whose address it is. A confirmation could attach the address to a signed-in app user who had only typed it, so mail from that address would then appear in that user’s conversations. Now an address joins such a contact only through its own confirmation e-mail.
- Access checked again when it is used. Push notifications re-check that the member can still see the inbox before each attempt, including retries. Only owners, admins and API keys can read workspace usage. A share link cannot sort its rows by a number it does not show.
- Deleting really deletes. Deleting a workspace removes its uploaded migration files and stops its analytics e-mails at once. Deleting a contact also removes the files of messages they wrote in other people’s conversations.
- Passkeys. A sign-in whose signature counter went backwards, a sign that the key was copied, is refused.
- Mobile session tokens stay on the device. On iOS the token’s Keychain item is no longer restored to other devices from a backup. On Android it is encrypted with a key that never leaves the device, so a copied backup cannot be read.
- Release pipeline. Every GitHub Action is pinned to a commit, and the MCP registry publisher is checked against its published checksum before it runs.
The install guide now also says to set YUVA_TRUSTED_PROXIES next to YUVA_CLIENT_IP_HEADER. Without it, anyone who can reach the server directly can choose their own address for rate limits.
We review our own code; that is not an independent audit. If you find something, please report it privately as SECURITY.md describes, not in a public issue.
Smaller things
- A visitor’s chat replies arrive live from their first message on, without a reload.
- The chat widget works on sites with a strict
style-srcContent Security Policy. - The home page now shows newsletters, imports and analytics, and the releases page lists every version from GitHub Releases.
- Charts fit three-digit axis labels, durations use short units, and plurals and time zones are right in insights, alerts and share links.
Try it
The release notes for 0.0.10, 0.0.11 and 0.0.12 are on GitHub.
- Hosted: create an account from the home page and start without running a server.
- Self-hosted: run
ghcr.io/productdevbook/yuva:0.0.12with Postgres using the Compose quick start, or install the Helm chart.
The native apps for your team are next, in 0.0.13. Yuva is still pre-alpha: the API and the database schema can change without migration paths. Try it with test data, and tell us what breaks in an issue.
productdevbook
Maintainer of Yuva
Try Yuva
Create an account on our service, or run it on your own server.