Why you might see Encited in your analytics
Encited loads your pages in a real headless browser — when we prerender a page for crawlers and when the SEO Spider audits your site. Your JavaScript runs exactly as it would for a human visitor, which means analytics and tracking snippets fire too. Left unguarded, these visits can inflate pageviews, distort bounce rates, and register conversions on ad pixels.
None of these visits are humans, so the fix is simple: detect them and skip your tracking code.
How to identify Encited visits
Every Encited visit that executes JavaScript sets a global marker before any of your scripts run:
window.__ENCITED__ = { visit: "render" }; // or "audit"
visit value |
What it is |
|---|---|
"render" |
Prerendering — capturing an HTML snapshot of your page |
"audit" |
SEO Spider — crawling your site for an audit report |
Because the marker is injected before the document is parsed, a synchronous check at the top of your <head> is reliable — there is no race with your tracking snippets.
Audit visits additionally identify themselves by user agent:
Encited-SEOAuditBot/1.0 (+https://encited.com/bot)
Render visits deliberately use a normal Chrome user agent so that firewalls and bot walls don't block snapshot rendering — for those, window.__ENCITED__ is the reliable signal.
Render visits also set the legacy window.__TO_HTML = true flag. It still
works, but prefer window.__ENCITED__ — it covers audit visits too.
The generic guard
Wrap your analytics loader so it only runs for real visitors:
if (!window.__ENCITED__) {// load analytics, pixels, chat widgets, session recording…}
If you only want to exclude one kind of visit:
if (window.__ENCITED__?.visit !== "audit") {// runs for humans and renders, skipped during audits}
Google Analytics (gtag.js)
Guard the entire snippet:
<script>if (!window.__ENCITED__) {var s = document.createElement("script");s.async = true;s.src = "https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX";document.head.appendChild(s);window.dataLayer = window.dataLayer || [];function gtag() { dataLayer.push(arguments); }gtag("js", new Date());gtag("config", "G-XXXXXXX");}</script>
Google Tag Manager
The simplest approach is to guard the container snippet itself, so no tags load at all:
<script>if (!window.__ENCITED__) {(function (w, d, s, l, i) {w[l] = w[l] || [];w[l].push({ "gtm.start": new Date().getTime(), event: "gtm.js" });var f = d.getElementsByTagName(s)[0],j = d.createElement(s);j.async = true;j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + "&l=" + l;f.parentNode.insertBefore(j, f);})(window, document, "script", "dataLayer", "GTM-XXXXXXX");}</script>
If you'd rather keep GTM loading and block individual tags, create a Custom JavaScript variable in GTM:
function () {return Boolean(window.__ENCITED__);}
Then add a trigger exception on your tags that fires when this variable equals true.
PostHog
Guard the init call:
if (!window.__ENCITED__) {posthog.init("phc_your_key", { api_host: "https://us.i.posthog.com" });}
Or, if PostHog must load anyway, opt the visit out of capturing:
posthog.init("phc_your_key", {api_host: "https://us.i.posthog.com",loaded: function (ph) {if (window.__ENCITED__) ph.opt_out_capturing();},});
The same pattern works for most other tools — Plausible, Mixpanel, Meta Pixel, Hotjar, Clarity: wrap the loader in the if (!window.__ENCITED__) guard.
TypeScript support
declare global {interface Window {__ENCITED__?: { visit: "render" | "audit" };}}
Server-side filtering
Audit visits can also be excluded server-side by matching the user agent token Encited-SEOAuditBot (older audit reports may show LvHTML-SEOAuditBot — match either). Render visits can't be filtered by user agent by design; use the window.__ENCITED__ guard for those.
Encited never blocks your analytics requests during rendering — what runs is entirely under your control. The marker just gives you a reliable way to decide.
