Web Analytics Dashboard Template

A traffic layout that builds itself from your own analytics export. Bring rows carrying a date, a source, a landing page, a device, a session count, a pageview count, a bounce rate and a conversion rate, all at one consistent grain. Drop the file and the trend, the source mix, the device split and the page panels appear. The columns are the template.

Load the template with sample data

The sample is the fastest way to see whether this layout fits before you go and find your own export. Daily rows by source, page and device, already at one grain.

Download the sample CSV

The column contract

Eight columns: four dimensions and four metrics. The four dimensions together define the grain of a row, and the four metrics describe that bucket. Get the grain consistent and everything else follows.

Column What it holds Role Required What breaks without it
date The day the traffic arrived Date Required Every trend line goes, and a traffic report with no trend is a set of totals you could have read in the analytics tool.
source organic, direct, social, referral, paid Category Required You cannot attribute anything. A traffic spike with no source is a mystery rather than a result.
landing_page The entry path, like /csv-to-chart Category Optional The page-level panels disappear, so you lose the fastest way to see which content is doing the work.
device desktop, mobile, tablet Category Optional Desktop and mobile behavior gets averaged together, which reliably hides a mobile conversion problem.
sessions Visits in that bucket Count Required The primary volume measure is gone and every rate loses its weighting, so a two-session row shouts as loudly as a two-thousand-session row.
pageviews Page loads in that bucket Count Optional Pages per session cannot be computed, which is the cheapest available proxy for depth of engagement.
bounce_rate Percent of single-page visits, like 36.3 Percent Optional Traffic quality drops out entirely, and a source sending volume that leaves immediately looks like a success.
conversion_rate Percent of sessions that converted, like 2.61 Percent Optional The dashboard becomes a traffic report rather than a performance one. Volume without outcome is the most flattering chart in marketing.

What you get

  • A KPI strip. Total sessions, total pageviews, pages per session, average bounce rate and average conversion rate across the period covered by the file.
  • Sessions over time. The headline trend, bucketed by day for short spans and by week or month for longer ones. Weekly buckets are usually the honest choice, since daily traffic mostly draws your weekend.
  • Sessions by source. Channels ranked by volume. The first panel anyone looks at, and the one most likely to prompt an argument about attribution.
  • Sessions by device. Three bars, and the split moves slowly enough that a sudden change is nearly always a tracking problem rather than an audience one.
  • Top landing pages. Entry paths by session count, with a long tail folded into Other. The tail is real: most sites get a third of their traffic from pages nobody has looked at in a year.
  • Bounce rate by source. Where the quality difference between channels shows up. Social usually bounces hard and that is normal, not a failure.
  • Conversion rate by device. The panel that has justified more mobile work than any other chart I have made.
  • Conversion rate by landing page. Which entry points actually produce something, ranked, so content effort has somewhere to go.
  • Sessions against conversion rate. A scatter with the correlation reported. High-volume, low-conversion pages sit in the bottom right and are the clearest optimization list you will get for free.

i. Bring these columns

Build one report in your analytics tool that returns all four dimensions and all four metrics together, then export that. One report, not four. Every metric in the file has to have come from the same query, or the ratios between them are fiction.

Clean the landing page paths before exporting if you can, and filter out internal and bot traffic at the source. Then rename the headers to match the contract, which takes a minute.

ii. Drop the file

Open the dashboard view and drop the CSV. Roles are read from the values. sessions and pageviews are counts, so they sum. bounce_rate and conversion_rate read as percentages, so they average rather than sum and render with a percent sign on every axis, which stops the most embarrassing chart in analytics: a bar showing four thousand percent bounce because rates got added up.

Nothing leaves the tab. A landing page export is a fairly complete map of your site, including whatever you have published but not announced yet.

iii. Adjust what you need

The first thing I change on a traffic dashboard is always the time grain. Daily sessions on a business-audience site is a sawtooth with a weekend trough, and weekly buckets turn it into a line you can actually read. After that, raise the top-N on landing pages if the folded Other bar is bigger than your second page, and sort sources by sessions rather than alphabetically.

Then export. PNG for the monthly review, and the aggregated CSV whenever the number is going into a document, so the chart in the deck and the table in the appendix cannot drift.

Getting your export into this shape

Analytics exports are the easiest data on this site to obtain and the easiest to ruin. GA4's explorations let you pick dimensions and metrics and export CSV directly, which is exactly what you want, though the file arrives with several header lines of report metadata above the actual header row. Delete those lines first or the parser will read # Start date as a column name. Plausible and Fathom export clean per-page and per-source CSVs but as separate files, which is where the trouble starts. Matomo's flat export is close to this contract already. Search Console gives you clicks and impressions rather than sessions, which is a different measurement entirely and should not be stacked into the same column.

The rule worth repeating is that sessions and pageviews must come from one query at one grain. Here is how it goes wrong. You export sessions by source and date, then export pageviews by page and date, then paste them into one file because both have a date column. Now some rows have a source and no page, some have a page and no source, and the pageviews on a row belong to a different slice of traffic than the sessions beside them. Pages per session comes out at 0.4, which is impossible, and if it happens to come out at 2.1 instead nobody notices at all. Build one report with all four dimensions on it and take whatever metrics that report will give you.

The second rule is that rates do not stack. A bounce rate is already a ratio, and adding ratios has no meaning. This is why the two rate columns are named with _rate and hold values like 36.3: the role inference sees a percentage and averages it. If your tool exports bounces as a raw count instead, keep it as a count, name it bounces, and let the dashboard divide. A count that sums correctly is always better than a rate that does not.

Then the paths. GA4 gives you /csv-to-chart?utm_source=newsletter&gclid=abc123 as a distinct landing page from /csv-to-chart, and a campaign with four creatives becomes four rows for one page. Strip everything from the question mark onward. Decide about trailing slashes, decide about case, and decide about language prefixes, then apply each decision to every row. Ten minutes of path cleaning changes the top-pages panel from a list of query strings into a list of pages.

Watch the source vocabulary too. GA4 will give you both a source and a medium, and google / organic against google / cpc are very different things wearing the same name. Either concatenate them into one value or map down to the five or six channel groups you actually make decisions about. A source panel with sixty values in it is a scroll bar.

Finally, know where your data thins out. Sampling kicks in on large GA4 date ranges and the export will not shout about it. Consent banners mean a variable and unknown share of visits is never recorded at all, and that share changes when the banner changes. None of this makes the dashboard wrong; it makes the baseline soft, and it is worth writing that on the slide before somebody builds a quarterly target on it.

What this template will not do

  • No user journeys. Aggregated rows have no path through the site in them. Flow analysis needs event-level data, which is a much bigger file and a different tool.
  • No attribution modeling. The source column is whatever your analytics tool already decided. Last click, first click and data-driven models all produce a different file, and this dashboard cannot re-derive any of them.
  • No revenue. Conversion rate is a percentage with no value attached. For money, join the ecommerce export on a key both systems share, which most setups do not have by default.
  • No unique users. Sessions are visits. A person visiting nine times is nine sessions here, and a CSV of aggregates cannot dedupe them.
  • No statistical significance. A conversion rate that moved from 2.4 to 2.9 might be a result or might be Tuesday. The dashboard draws both and judges neither.
  • It will not fix a mixed-grain file. If daily and monthly rows are both present, the sums double count and every panel is confidently wrong. Only you can catch that, before you drop the file.

Frequently Asked Questions

There is no file to download. So what am I getting?

A column contract. The traffic layout is already built and it waits for rows carrying date, source, landing_page, device, sessions, pageviews, bounce_rate and conversion_rate. Bring those and the panels appear around your numbers. This works better than a downloadable workbook for analytics data specifically, because the volume of rows in a ninety-day export by source and page is more than anyone wants to paste into a template grid.

What grain should the rows be at?

One row per date per source per landing page per device. Every row is a bucket, and the metric columns hold the totals for that bucket. Pick a grain and keep it identical down the whole file. The failure that ruins this dashboard is a file that mixes grains, for example daily rows by source plus a set of monthly totals appended at the bottom, because summing them double counts everything in the overlap and nothing on screen will look wrong.

Why can sessions and pageviews not be mixed at different grains?

Because they are counted over different scopes and only agree when they come from the same query. Sessions are per visit and pageviews are per page load, so a single session contributes one session and several pageviews. Export them together, in the same rows, from the same report. If you pull sessions by source and pageviews by page and stack them into one file, pages per session becomes a ratio of two unrelated denominators, and it will produce a plausible number that means nothing.

How should bounce rate and conversion rate be formatted?

As numbers out of a hundred, like 36.3 and 2.61, matching the sample. Not as 0.363 and not as the string 36.3%. Trailing percent signs are read as numbers so a percent sign will not break anything, but a mix of 0.363 and 36.3 in one column absolutely will, and that mix is common when two reports are joined. Pick one scale, apply it to both rate columns, and check the minimum and maximum before you drop the file.

Can I average a bounce rate across rows?

Only carefully. A plain average of per-row rates treats a row with nine sessions the same as one with nine thousand. For a headline you want a session-weighted average: multiply each rate by that row's sessions, sum, then divide by total sessions. The panels here show unweighted averages by default because that is what the raw column supports, and they are honest for comparing sources of similar size. Add a weighted column in the app when the sizes are wildly different.

Should I include internal and bot traffic?

No, filter it out at the source before exporting. Bot traffic inflates sessions and drives bounce rate toward a hundred, which makes every trend look worse than it is and makes a genuine spike impossible to spot. Office IP traffic does the opposite, since your own team browses deeply and converts strangely. Both belong outside the file rather than inside it with a flag, because a flag column has to be filtered every single time somebody looks.

Do landing page paths need cleaning?

Usually yes, and this is where most analytics files fall apart. A path carrying query strings and tracking parameters splits one page into forty distinct values, so the page panel shows a tail of near-duplicates instead of your top pages. Strip everything after the question mark. Decide whether trailing slashes are kept or removed and apply it uniformly. If your site is multilingual, decide whether the language prefix is part of the page identity before you export, not afterwards.

How far back should the export go?

Ninety days is a good default and thirteen months is the useful maximum. Traffic is weekly-seasonal, so anything under three weeks gives you a line dominated by weekends rather than a trend. Thirteen months lets you compare a month against the same month last year. Beyond that you are usually comparing against a different site, since redesigns, tracking changes and consent banner rollouts all move the baseline more than any campaign does.

Is my traffic data uploaded anywhere?

No. The file is parsed and aggregated inside your browser tab, with no upload endpoint behind this page. Aggregated analytics exports are less sensitive than most files here, but a landing page list is still a fairly complete map of your site, including the pages you have not linked publicly yet. Once the page is loaded it works offline.

See the layout on sample traffic

Daily rows by source, page and device, all from one query. Judge the fit before you wrestle with your own export.

Load the template with sample data