Modulify

Visitor analytics

Read who visits your published site, where they came from, and what they looked at.

On this page

Every project has an Analytics tab in the editor. It counts real visits to your published site, it is on by default, and it costs nothing on any plan. The tracking is cookieless, so your site needs no consent banner for it anywhere in the world.

Where to find it

Open a project and click the chart icon in the tab strip at the top of the editor. It sits between CMS and Storage, and its tooltip reads Analytics. The address is /dashboard/projects/<project>/analytics.

The tab has two sub-tabs: Data for the numbers and Settings for the collection toggle, the export, the API key and the reset.

Do not confuse this tab with the Analytics sub-tab inside Storage. That one reports CDN file usage, not visitors.

What is counted

Only the published site. Nothing in the preview is measured, including views through a read-only link. Until your first publish, a banner reads "This site needs publishing before analytics can start collecting visitors." and every card is empty.

Collection is wired into the site when it is built, so a change to the toggle only reaches visitors on your next publish. That means there are four states the banner can describe:

State What the banner says
Never published This site needs publishing before analytics can start collecting visitors.
Collection off, published site still carries the script Collection is off, but your published site keeps collecting until you publish again.
Collection off and no longer on the published site No new visitors are being collected while analytics collection is off.
Collection on but not yet shipped This site needs republishing before analytics can start collecting visitors.

When none of those apply, no banner appears.

The live counter

Next to the period picker sits a green dot and a count, reading for example 12 online. That is the number of people active on the published site in the last five minutes. It is independent of the period you picked, and the whole panel refreshes every five seconds once the site has been published at least once. Until the count loads, or when it cannot be read, it shows a dash and the dot turns grey.

The six metrics

Six stat cards run across the top. Each one is a button: click it and the chart below re-plots to that metric. Unique visitors is selected by default.

Card What it counts
Unique visitors Distinct people in the selected period
Total visits Sessions, so one person returning later counts twice
Total pageviews Every page load, including repeat views in one visit
Views / visit Pageviews divided by visits, shown to two decimals
Bounce rate Percentage of visits that left after a single page, shown as a whole number
Visit duration Average time on the site, formatted as 2m 14s

If the numbers cannot be loaded, the cards show a dash and the chart offers a Try again button under "Could not load analytics" with the line "Your visits are still being counted." A breakdown that could not be loaded reads "Could not load breakdown". A failure never shows as zeros. When a background refresh fails, the numbers already on screen stay until the next refresh succeeds.

Time ranges

The period picker sits in the top right. Last day is the default.

The presets are Today, Last day, Last week, Last month, Last 3 months, Last year, All time and Custom range, the same ones every date picker in Modulify offers. Today runs from midnight UTC up to now. Last day is the current hour and the 23 before it. Last week, Last month and Last 3 months are the last 7, 30 and 90 days counting today, and Last year is this month and the 11 before it. Picking Custom range puts two date fields next to the picker, Start date and End date, each opening its own calendar. The end field stays switched off until a start is set, no day after today can be picked, and the end calendar only offers days from the start onwards, so the range can never run backwards. A range spans at most 3,660 days, so the start calendar offers nothing earlier than 3,660 days before the end, or before today while no end is set, and the end calendar nothing later than 3,660 days after the start. A start later than the current end clears that end so you can pick a new one. The chart reloads once both fields are filled, and a single day is a valid range. Whenever you are on anything other than Last day, an X button appears next to the picker to reset back to it.

The chosen period lives in the page address, so an analytics view is a link you can send to a teammate or bookmark.

Chart granularity

The chart header reads <metric> over time, and a second picker to its right sets the bucket size. Which sizes are offered depends on the range, and the picker is hidden when there is only one sensible option.

Range Granularity options
Today, Last day Hours
Last week, Last month Hours, Days
Last 3 months Days
Last year Days, Months
All time Months
Custom, up to 1 day Hours
Custom, up to 31 days Hours, Days
Custom, up to 92 days Days
Custom, up to 366 days Days, Months
Custom, longer Months

The chart is a filled area chart. Hover any point for a small tooltip with the bucket label and the value in that metric's own units. The bucket that is still in progress is drawn as a dashed line, so a half-finished hour or month never looks like a real drop. Times are shown in your own timezone.

When the range holds no traffic yet, the chart is replaced by an empty state reading "No visits" with the line "Trends appear here once traffic starts arriving."

Breakdowns

Six cards sit under the chart, each listing the top eight rows for the selected period, ranked by unique visitors. A pale bar behind each row shows its share of the top row.

  • Top pages, by path on your site
  • Top sources, where the visit came from, with the referrer's favicon
  • Countries, with the country flag and full country name
  • Browsers
  • Operating systems, with the platform logo
  • Devices, split into desktop, mobile and tablet

A row with no recorded value shows as (none). A card with nothing in it yet reads "No data" with the line "Breakdowns appear here once visits arrive."

Settings

The Settings sub-tab holds four sections.

Collection

One switch, Collect visitor analytics, described as injecting the privacy-friendly tracking script on your published site. Turning it off writes the change immediately, but the live site keeps collecting until you publish again. Existing data is always kept.

Export

Export .csv downloads all-time stats for every page, source, country, browser, operating system and device, with a visitors and a pageviews column per row. The file is named after your project slug, for example my-site-analytics.csv.

This one is paid only. On a free workspace the button is disabled and its tooltip reads "Exporting your analytics requires a paid plan."

API access

Analytics API Key shows the key masked, as mak_ followed by dots. The copy button next to it puts the real key on your clipboard and clears it again after a minute. The key is read-only: it reads every number on this tab but never changes or clears them. Your site receives it as MODULIFY_ANALYTICS_KEY, with the address in MODULIFY_ANALYTICS_URL, and both are for server code only.

The rotate button next to copy asks "Rotate analytics API key?" and warns that the current key stops working immediately, that your published site keeps the old key until you republish it, and that anything outside the site that reads your analytics with the key, such as a script or another service, needs the new key pasted in. On success: "Key rotated", with the reminder to republish the site to apply it. Rotating needs project delete permission in the workspace, and members without it see the rotate button disabled.

Below the key, Using the analytics API expands into two tabs. Modulify explains that describing what you want in chat is enough, and its Add it with AI button drops a ready made prompt into the composer for you to review and send. External holds a curl example for every endpoint with your own address filled in, and Copy guide copies the whole reference as plain text. The full reference is Analytics HTTP API.

Danger zone

Clear data permanently resets every visitor stat for the site back to zero. Tracking keeps working for new visits. A confirmation asks "Clear analytics data?" before anything happens, and the action button reads Clear data.

Clearing needs project delete permission in the workspace. Members without it see the button disabled.

Asking the AI about your traffic

You can ask about traffic in chat rather than reading the tab. The AI can pull totals for any of the six metrics, a ranked breakdown by page, source, country, browser, operating system or device, a custom date range, or the live count. It can also turn collection off or back on, check whether the live site carries the tracking script, and clear the data, which needs the same project delete permission and which it asks you to confirm first. A change to collection reaches the live site with your next publish, so chat says so and offers to publish. Exporting the CSV and the API key stay yours.

It can also build pages that read these numbers, such as a list of your most read posts, through the analytics API.

From an AI client over MCP

get_site_analytics returns the headline numbers, get_site_analytics_overview everything the Data sub-tab shows in one call, get_site_realtime_visitors the live count, get_analytics_status the collection and publish state, and check_analytics_installation whether the script is in place on the live site. query_site_analytics answers anything else: top pages, sources, countries, browsers, operating systems, devices, or a series over time. export_site_analytics returns the all-time export on a paid plan. All seven need analytics:read, which is ticked by default. The AI clients reading a site share 1,200 analytics lookups an hour, counted apart from the site's own API key, see Rate limits and result size.

set_analytics_enabled turns collection on and off, and clear_site_analytics erases the whole history. get_analytics_key and rotate_analytics_key read and replace the analytics API key, and need credentials:reveal, which is unticked by default. See MCP tools.

Next