The Clickport tracker works out of the box with just the data-domain attribute, but there are several options for customizing its behavior.
The tracker reads configuration from attributes on the <script> tag:
The primary way to associate events with your site. Set this to your registered domain without https:// or www.:
<script defer data-domain="example.com"
src="https://clickport.io/tracker.js"></script>
If data-domain is omitted, the tracker falls back to location.hostname with www. stripped. This means it works without the attribute if your registered domain matches your actual hostname, but it's better to be explicit.
Authenticate with an API key instead of domain matching. This is useful when the page's hostname differs from your registered site domain (e.g. staging environments, embedded widgets, or third-party platforms):
<script defer data-site="ck_your_api_key_here"
src="https://clickport.io/tracker.js"></script>
When data-site is present, it takes priority over data-domain. Generate API keys in your dashboard under Settings.
data-site handles authentication while data-domain is still sent for display purposes.
For more advanced configuration, define a window.cpConfig object before the tracker script loads:
<script>
window.cpConfig = {
api: 'https://your-proxy.example.com',
key: 'ck_your_api_key_here',
is_404: true
};
</script>
<script defer data-domain="example.com"
src="https://clickport.io/tracker.js"></script>
Available properties:
api - Override the API endpoint URL. Used for proxying the tracker through your own domain.key - API key for authentication. Same as data-site but set via JavaScript. The data-site attribute takes priority if both are present.is_404 - Force this page to be flagged as a 404 error page. By default, the tracker auto-detects 404s by checking if the page title contains "404" or "not found" (case-insensitive). Use this when your error page has a custom title.There are two ways to exclude yourself from being tracked:
Open the browser console on your website and run:
localStorage.setItem('clickport_ignore', 'true')
The tracker checks for this flag on every page load and silently exits if it's set. This is per-browser, so set it on each browser and device you use. To re-enable:
localStorage.removeItem('clickport_ignore')
Click the gear icon in your dashboard, then toggle "Exclude my IP" on the Dashboard tab. This blocks all traffic from your current IP address at the server level before it reaches ClickHouse. See Site Management for details.
The tracker is composed of several modules that run automatically. No configuration is needed for any of these:
Every page load sends a pageview event with the current URL, referrer, viewport width, timezone, and any UTM parameters from the query string (utm_source, utm_medium, utm_campaign, utm_content, utm_term).
The tracker intercepts history.pushState, history.replaceState, and the popstate event. When the URL changes, a new pageview is sent automatically. No extra configuration is needed for React, Vue, Next.js, Nuxt, Angular, or any other SPA framework. See SPA Tracking for edge cases.
Active time on page and scroll depth are tracked continuously. The tracker measures active time (pausing when the tab is hidden or blurred) and records the maximum scroll depth as a percentage. This data is sent on page leave via pagehide and beforeunload events. See Engagement for how these metrics work.
Clicks on links pointing to external domains are tracked automatically. The tracker captures the destination URL and the link text. It also detects /go/ affiliate redirect links on your own domain. See Outbound Links.
Clicks on links to downloadable files are tracked automatically. Detected file extensions: .pdf, .zip, .doc, .docx, .xls, .xlsx, .csv, .ppt, .pptx, .rar, .7z, .gz, .tar, .mp3, .mp4, .mov, .avi, .dmg, .exe.
When a form is submitted, the tracker sends an event with the form's id or name attribute. No form data is collected, only the identifier. See Forms.
When a visitor copies text on your page, the tracker sends an event with the first 200 characters of the copied text. This helps you understand which content visitors find most valuable.
Pages with "404" or "not found" in the title are automatically flagged as error pages and appear in the Error Pages panel on the dashboard.
Clickport uses browser-tab-based sessions. A session starts when a visitor opens your site in a new tab and ends when the tab is closed. There is no 30-minute inactivity timeout (unlike Google Analytics or Plausible). The session ID is stored in sessionStorage, which is automatically cleared when the tab closes.
Visitor identity is based on a daily-rotating anonymous ID that changes at midnight in your site's configured timezone. This means the same visitor gets a new ID each day, preserving privacy while still allowing same-day session tracking.
If ad blockers are blocking the tracker on your site, you can serve it through your own domain. This involves two steps:
/js/analytics.js)/api/event) through your own serverThen configure the tracker to use your proxy:
<script>
window.cpConfig = {
api: 'https://example.com/stats'
};
</script>
<script defer data-domain="example.com"
src="/js/analytics.js"></script>
The api setting tells the tracker to send events to https://example.com/stats/api/event instead of https://clickport.io/api/event. Your proxy should forward these requests to https://clickport.io/api/event with the original headers and body intact.
location /stats/api/event {
proxy_pass https://clickport.io/api/event;
proxy_set_header Host clickport.io;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /js/analytics.js {
proxy_pass https://clickport.io/tracker.js;
proxy_set_header Host clickport.io;
expires 5m;
}
The tracker auto-disables on localhost, 127.0.0.1, and file:// URLs. It also disables when it detects common testing and automation tools.
To force tracking during development:
<script>window.__CP_TEST__ = true;</script>
<script defer data-domain="yourdomain.com"
src="https://clickport.io/tracker.js"></script>
__CP_TEST__ flag before deploying to production. It bypasses all safety checks that prevent automated tools from generating fake traffic.
The full tracker (all modules) is under 5 KB gzipped. It loads with defer so it never blocks page rendering. There are no external dependencies, no cookies, and no localStorage usage beyond the optional self-exclusion flag.