eodia analytics
Your audience. With or without cookies.
Page views, campaigns, events, orders: measured site by site, within the consent exemption of the CNIL, the French data protection authority — without ever storing an IP address. The analyses are built in eodia insights.
- Open source, AGPL-3.0
- No banner, no IP address
- Analyses in eodia insights
One tag. Nothing else.
Paste one line into your pages: page views, sources, campaigns, clicks, scrolling and automatic measurements follow by themselves.
Received ✓, in seconds.
The Verification tab shows what arrives, live: the events received, and those refused with their reason.
With or without cookies: site by site.
The mode is set on screen, and the server tells the script. The tag never changes.
You describe. Insights understands.
Events, properties, zones, goals: every label becomes an SQL comment, read by eodia insights and its assistant.
The analyses, in eodia insights.
The Statistics button opens an insights dashboard locked on the site — even in free SQL.
With or without cookies
Three modes. One setting per site.
Cookieless, a visitor is a daily hash whose salt is destroyed the next day. With the measurement cookie, returning visitors are recognized for 13 months at most. With consent, your platform decides. The tag itself never changes.
The server decides
The mode comes with the answer to the first page view. Changing it takes effect on the next page, without touching the site.
13 months, not a day more
The cookie’s expiry is set when it is created and never extended by a visit. optOut() deletes it.
A refusal is a refusal
optOut() and the Global Privacy Control signal stop all sending, in every mode. The IP address is never kept.
Without a line of code
What your visitors do, all the way to the order.
Outbound links, downloads, site search, forms and videos: measured out of the box. And the purchase journey, from view_item to purchase, following the GA4 convention — an order counts only once.
Measured out of the box
Outbound links, files, site search (read from the address by the server), forms, HTML videos: each can be turned on or off.
Never a typed value
A form started, a form sent: never what was typed in it. Search terms are masked when they look like an e-mail address or a phone number.
One order, once
Reloaded, sent by the browser then by the server: a transaction counts once, and the server’s amounts win.
Campaigns and attribution
Every visit in its place. Every sale to its visits.
UTMs are normalized and their aliases merged, channels follow GA4’s rules — editable, and applied to the past too —, and each order is shared among the visits that came before it, across six models.
Léa’s journey
Clean UTMs
Lowercase, aliases (fb, facebook.com → facebook), ad platforms’ click IDs reduced to their type: never their value.
GA4’s channels
Nineteen channels to start with, rules you reorder and edit. A changed rule also fixes the past months.
Six models, side by side
For tracked visitors (cookie, consent, sign-in), within an adjustable 30-day window: insights compares the models with one filter.
Metadata that travel
Described once. Understood in insights.
You declare an event, its properties, a zone: their labels become SQL comments. eodia insights reads them — in its Structure screen, and all the way into the context of its AI assistant.
SQL comments
Every view, every column, every declared property carries its label and description, in the database itself.
Generated views
A declared event becomes its own evt_<name> view, one typed column per property; a classification, its cls_<name> view.
Nothing to code in insights
It already reads PostgreSQL’s comments: they reach Structure and the context of its assistant.
Data subject rights
One request. And it is done.
Someone asks for their data, or for its erasure: by their identity or by their cookie, from the screen, the API or the site’s sending key. Their visits from before sign-in included. Only a fingerprint of the request is kept.
By identity or by cookie
A signed-in customer, by their identifier; an anonymous visitor, by the identifier of their measurement cookie.
The whole person
Linked visits from before sign-in are included. The export downloads as JSON for 7 days.
A fingerprint, not the identifier
The request keeps a fingerprint and a row count. Without cookies, there is nothing to tie to anyone.
And everything you expect from web analytics.
What makes a marketing team adopt it, and lets a data protection officer sleep at night.
IP addresses stored
Used for the daily hash and the country, then forgotten: neither in the database nor in a log.
Single-page applications
pushState, replaceState, fragments: every change of address counts, without code.
Single sign-on
OpenID Connect; groups come from your directory, access is granted per site.
data-eodia-zone="tarifs" Zones and clicks
How long your blocks are seen, and clicks placed within the element: enough to draw heatmaps.
Classifications
The product catalog, the campaign codes: imported as CSV, joined by insights.
Annotations
The newsletter sent, the release shipped, the outage: markers on the curves.
POST /collect/server Server-side collection
Confirmed orders, apps, batch jobs: with a sending key specific to the site.
Your domain
The script and the collection on stats.your-site.com, as a CNAME.
Audit log
Sign-ins, sites, secrets, sending keys, data subject requests: everything is recorded.
On your servers
Your visitors go through no third party.
One Docker image, one Compose file: PostgreSQL, the collecting API, the worker, the interface and Caddy for HTTPS. The first screen creates the administrator account.
- Automatic HTTPS with Caddy, no access log
- One image, four roles: api, web, worker, all
- A single PostgreSQL database, managed or not
Frequently asked questions
How is it different from Google Analytics?
What is measured is close — page views, campaigns, channels, events, online commerce, attribution —, and the purchase event names are GA4’s. The difference lies elsewhere: the data stays with you, IP addresses are never stored, the cookie is optional, and the analyses are built in eodia insights, on documented SQL views.
Do I still need a consent banner?
Not for audience measurement itself, as long as you stay within the conditions of the CNIL exemption: cookieless or measurement-cookie mode, no signed-in visitors, no sharing of the data, information and a right to object. Your site may need one for other trackers. Have your configuration checked by your data protection officer.
What do I lose without cookies?
Recognizing a visitor from one day to the next: a unique visitor is counted per day, and attribution is limited to the day. Page views, visits, sources, campaigns, events and orders are complete.
Where are the charts?
In eodia insights. eodia analytics administers and collects; it only shows check figures. Insights connects to its views read-only, and each site’s Statistics button opens a dashboard locked on it.
Can I use it without eodia insights?
Yes: the views of the analytics schema can be read by any tool that speaks PostgreSQL, with the read-only role eodia_analytics. But it is with insights that the comments, the per-site row rules and the Statistics button make full sense.
What about ad blockers?
Serve the script and the collection from a subdomain of your site, as a CNAME: measurement is blocked less often there. It is not a way around a refusal: optOut() and the Global Privacy Control signal are still respected.
My site is a React, Vue or Next.js application.
The script follows the address changes of the history API (and of fragments, if you ask): every page of the application counts, without code. For fine control, data-auto="false" and EodiaAnalytics.page().
Is it really free?
Yes, under the AGPL-3.0-or-later license: you install it, use it and modify it freely. If you offer a modified version as an online service, you publish your changes.
Paste a tag. Keep your data.
One command to get started, a test page to see "Received ✓", and the docs for everything else.