breat.fr

Referrer Labels

Referrer labels are stored in:

/data/referrers.json

The file is automatically created and updated as new referrers are discovered.

Automatic discovery

When a new referrer is detected, the application attempts to find a human-friendly name by checking, in order:

  1. Web App Manifest (manifest.json or manifest.webmanifest)
  2. Open Graph metadata (og:site_name) or application metadata (application-name), whichever is found first
  3. The website title (<title>)

Both domain.tld and www.domain.tld are tested when available to improve detection accuracy.

Whatever text is found goes through a bit of cleanup before being stored: marketing taglines after a |, -, or similar separator are dropped ("Brand | Tagline" becomes "Brand"), and a trailing .com/.net/.io/etc. that just repeats the domain is stripped ("Amazon.com" becomes "Amazon"). Pages that look like a bot-protection interstitial (Cloudflare's "Just a moment...", "Checking your browser...", and similar) are treated as a failed attempt rather than saved as the real label.

Examples:

{
    "github.com": {
        "auto": true,
        "category": "referrer",
        "failures": 0,
        "label": "GitHub",
        "last_try": "2026-06-21T13:23:04+02:00",
        "resolved": true,
        "updated": "2026-06-21",
        "urls": ["github.com"]
    },
    "chatgpt.com": {
        "auto": true,
        "category": "referrer",
        "failures": 0,
        "label": "ChatGPT",
        "last_try": "2026-06-21T13:23:04+02:00",
        "resolved": true,
        "updated": "2026-06-21",
        "urls": ["chatgpt.com"]
    }
}

Manual overrides

Any label can be changed manually by editing its label field.

Whether that change sticks depends on resolved and auto — see Auto mode below. As a rule of thumb: if the entry's resolved is already true, a label edit is safe on its own. If resolved is still false (a fallback/unresolved entry), also set auto to false at the same time — otherwise the next successful automatic discovery pass will silently overwrite your edit.

Example:

{
    "chatgpt.com": {
        "auto": false,
        "label": "OpenAI ChatGPT",
        "urls": ["chatgpt.com"]
    }
}

Grouping domains together (canonical entries)

Related domains are grouped under a single entry so they don't create duplicate referrer rows or duplicate cached icons.

Each entry is keyed by its canonical (root) domain, and lists every other domain that should count as the same referrer in its urls array. Subdomains of that same root domain don't need to be listedwww.google.com or news.google.com already resolve to a google.com entry automatically, since Brivacia strips www. and reduces any subdomain down to its root domain before matching. urls is only needed for domains that don't already share that root.

The most common case is a service using different top-level domains per country, where each one is a genuinely different root domain:

{
    "google.com": {
        "auto": false,
        "category": "search",
        "label": "Google",
        "urls": [
            "goo.gl",
            "google.com",
            "google.co.uk",
            "google.fr",
            "google.de"
        ]
    }
}

(Brivacia's own default referrers.json groups the full list of Google's country domains this way — dozens of entries, all rolled up into one Google row.)

The other case is a full rebrand onto a different domain name, which Brivacia has no way to guess on its own — this has to be added by hand:

{
    "x.com": {
        "auto": false,
        "category": "referrer",
        "label": "X (twitter)",
        "urls": [
            "t.co",
            "twitter.com",
            "x.com"
        ]
    }
}

Without this manual grouping, visits coming from twitter.com links (still common, since not everything has been updated to x.com yet) and t.co (Twitter/X's own link shortener) would show up as two or three separate, unrelated referrers instead of one.

If you'd rather split a subdomain out as its own referrer instead of merging it — for example, treating news.google.com as distinct from plain Google searches — give it its own top-level entry with its own urls, rather than listing it inside google.com's.

New aliases are added to urls automatically as they're seen in traffic, whether or not the entry's label is locked (auto: false) — only automatic label re-fetching checks auto, see Auto mode.

Auto mode

Automatic label discovery only touches an entry when both are true:

{
    "github.com": {
        "auto": true,
        "resolved": false,
        "label": "github.com"
    }
}

A freshly discovered referrer starts with auto: true and resolved: false, so Brivacia keeps retrying automatic discovery until it succeeds — at which point resolved flips to true and it stops being touched again, regardless of auto.

{
    "github.com": {
        "auto": false,
        "resolved": false,
        "label": "My Custom Label"
    }
}

Setting auto to false locks the label immediately, without waiting for resolved to become true on its own. This is useful when:

Categories

Every entry has a category, one of:

{
    "bing.com": {
        "auto": true,
        "category": "search",
        "label": "bing",
        "urls": ["bing.com"]
    }
}

There is currently no dashboard control to change a referrer's category — it's set either in the file Brivacia ships with (which already covers the well-known search engines) or by editing referrers.json by hand.

Blocklist

Beyond setting category: "blocked" on individual entries, referrers can also be blocked in bulk from:

/data/referrers_blocklist.json
{
    "hosts": [
        "spam-domain.example",
        "another-bad-actor.example"
    ],
    "contains": [
        "xtraffic"
    ]
}

Blocked referrers are not deleted and not excluded from tracking — they stay in the database so historical totals stay accurate. On the dashboard, they're simply grouped together under a single "Blocked" row instead of being listed individually, keeping referrer spam out of your actual traffic sources without losing the underlying numbers.

If a domain is already on the blocklist the first time it's ever seen, its referrers.json entry is created with category: "blocked" right away — no need to manually flip it after the fact. This only applies at discovery time, though: adding a domain to the blocklist later doesn't retroactively change the category of an entry that already exists with category: "referrer". It's still correctly hidden on the dashboard either way (referrerBlocked() is checked independently of category), but if you'd rather the stored category reflect that too, it needs to be edited by hand.

Failed lookups

Some websites do not expose enough metadata to determine a proper name.

In such cases, the domain name itself is used as a fallback until automatic discovery successfully resolves a proper label.

Example:

example.com

The application periodically retries automatic discovery for unresolved entries, with a cooldown that grows the more an attempt has already failed for that referrer (roughly: 1 hour after the first failure, 1 day after 3 failures, 1 week after 5 or more) — so a site that's temporarily unreachable gets retried soon, while one that consistently refuses to resolve isn't hammered with requests forever.

Do you find this project useful? You can support its development using the buttons in the page footer.