@geo-analytics/tag
v1.6.0
Published
First-party website analytics client for GEO/AEO — attributes visitors to the AI engine that referred them (Doubao, DeepSeek, Qwen, Kimi, ChatGPT, Perplexity, Gemini…). Zero dependencies, ~6KB.
Maintainers
Readme
@geo-analytics/tag
First-party website analytics client built for GEO / AEO — it tells you which AI engines are actually sending you traffic, not just that "some referral" arrived.
Detects and attributes referrals from Doubao, DeepSeek, ERNIE, Qwen, Yuanbao, Kimi, ChatGPT, Perplexity and Gemini. Zero dependencies, ~6 KB minified, and it never throws into the host page.
Why this exists
Conventional analytics loses AI-engine referrals. Some engines strip the referrer entirely, so the visit lands in "Direct". This client handles both signals:
- Referrer host matching for engines that pass a referrer
- Injected-parameter fingerprints for engines that do not — Qwen, for example, appends
spm=5176.*to outbound links and sends no referrer at all
Install
Paste one line into your site's <head> and replace VG-XXXX with your Tag ID.
<!-- Recommended: first-party hosting -->
<script async src="https://geo-analytics.info/vtag.js?id=VG-XXXX"></script><!-- CDN: global edge delivery, follows the latest 1.x -->
<script async src="https://cdn.jsdelivr.net/npm/@geo-analytics/tag@1/dist/vtag.js?id=VG-XXXX"></script>Both serve an identical build. First-party hosting is the default we ship to customers for two reasons: it is the hot-fix channel (CDN copies are cached 12–24 h), and it keeps the number of third parties your visitors depend on at zero.
Pinning and Subresource Integrity
If you would rather not auto-receive updates, pin an exact version and add an SRI hash:
<script async
src="https://cdn.jsdelivr.net/npm/@geo-analytics/[email protected]/dist/vtag.js?id=VG-XXXX"
integrity="sha384-REPLACE_WITH_HASH_OF_THAT_EXACT_VERSION"
crossorigin="anonymous"></script>SRI and floating versions are mutually exclusive — @1 changes its hash on every release, so the browser would reject it. Pinning also means you must upgrade manually to receive fixes; that trade is yours to make.
What it collects automatically
first_visit · session_start · page_view (including SPA route changes) · scroll (90 %) · click (outbound links) · user_engagement (visible-state duration, comparable to GA4).
Attribution is recorded twice, deliberately: once as first touch (sticky for the visitor's lifetime) and once per session. A visitor who arrives via DeepSeek today is therefore not overwritten by their Doubao first touch from last week.
A new session starts after 30 minutes of inactivity, at the day boundary, when utm_source changes, or when the entry engine changes — the last one matters, because otherwise a Qwen visit arriving inside a still-live Doubao session would lose its source entirely.
Custom events
<button onclick="geotag('event', 'conversion', { conversion_name: 'signup' })">Sign up</button>Consent
The default is granted. On the first page view the client writes a persistent
anonymous ID to localStorage before any consent signal is given — an opt-out model.
If your visitors are covered by the GDPR/ePrivacy regime, or any other regime requiring prior consent, call this before the script runs, or gate the script behind your consent banner:
geotag('consent', 'denied'); // anonymous counts only, no persistent ID storedYou are responsible for the lawful basis on which you deploy this on your site.
Self-hosted / private deployments
Point the client at your own collector. Three ways, no source changes:
<script async data-endpoint="https://collect.example.com/v/collect"
src="https://cdn.jsdelivr.net/npm/@geo-analytics/tag@1/dist/vtag.js?id=VG-XXXX"></script>geotag('config', 'VG-XXXX', { endpoint: 'https://collect.example.com/v/collect' });# or bake a different default into your own build
VTAG_DEFAULT_ENDPOINT=https://collect.example.com/v/collect npm run buildResolution order: config({endpoint}) → data-endpoint attribute → compile-time default.
Privacy
A first-party anonymous ID in localStorage. No cross-site tracking, no third-party cookies, no device fingerprinting. The visitor's IP is used server-side to derive coarse geography (country / region / city) and is not stored in raw form.
License
MIT © geo-analytics
