How to Embed Analytics Dashboards in Your SaaS Product

Customer-facing analytics without building a charting stack: how to embed dashboards in your SaaS with per-user filtering, iframes, and caching.

JR3 min read

Your users expect analytics inside your product now. They want to see their usage, their activity, their numbers - and "export a CSV and open Excel" stopped being acceptable years ago. Customer-facing analytics has quietly become table stakes for B2B SaaS, and products that offer it charge more and churn less.

The good news: you no longer have to build a charting stack to offer it.

Your three options#

Build it in-house. Pick a chart library, write the aggregation API, handle auth, and maintain it forever. This is the flexible route and the expensive one - realistically weeks to months of engineering time before your first customer sees a chart. We wrote an honest build vs buy breakdown if you're weighing this seriously.

Embed a generic BI tool. Most BI platforms offer iframe embeds, but they're designed for internal analysts: per-viewer pricing that explodes with your customer count, clunky theming, and awkward per-tenant filtering.

Use an event analytics platform with embeds built in. This is the route we built GraphJSON for: your product events are already stored there, and any dashboard becomes an embeddable iframe.

The requirement that kills most DIY attempts#

Every customer must see only their own data. Always. That sounds trivial, but it's where most homemade implementations go wrong: the filter gets applied in the browser, and one tweaked request exposes another customer's numbers.

The filter has to be enforced server-side, on every request, from parameters your backend controls. Treat "customer A can never receive customer B's rows" as a hard security property, not a UI nicety.

How embedding works in GraphJSON#

You build a dashboard from your events, copy the iframe embed URL, and drop it into your app. The key piece is dynamic filters: your backend passes per-request filter values, so the same embedded dashboard renders each customer's slice of the data - one dashboard definition, infinite per-tenant views.

Embed responses are cached (15-minute TTL), so a page full of charts loads fast and a burst of users doesn't translate into a burst of database queries. The full setup is in the embedding graphs guide, and per-user versions are covered in personalized dashboards.

Get the data model right first#

Per-customer filtering only works if every event carries the identifier you'll filter on. Log a stable user_id or account_id with every event from day one - retrofitting identity into historical events is painful. Our event tracking best practices covers naming, payload shape, and what never to log.

What to embed first#

Start with the three charts every customer wants: their usage over time, their recent activity, and their headline totals. That alone puts you ahead of most competitors, and you can expand from there. For inspiration, see how we built personalized user dashboards in an afternoon.

JR

Written by JR

Founder and builder of GraphJSON.