Custom Tracking Domains
Deze inhoud is nog niet vertaald.
Ad blockers and restrictive network filters are more likely to block shared analytics hostnames than a first-party subdomain controlled by the site owner.
HitKeep custom tracking domains let team admins verify multiple tracker hostnames for a team. Every active team domain can serve tracker assets and browser ingest for every site in that team. When users generate tracking code for a site, Site Settings lets them choose the instance URL or any active team domain for the hk.js snippet. Cloud and self-hosted deployments use the same database model, dashboard flow, API, and tracker behavior. The difference is TLS operations: HitKeep Cloud issues certificates on demand with Caddy, while self-hosted operators either use the optional Caddy profile or terminate TLS in their own reverse proxy.
HITKEEP_CUSTOM_TRACKING_TLS_MODE=caddy-on-demandHITKEEP_CADDY_TLS_ASK_TOKEN=$(openssl rand -hex 32)HITKEEP_PUBLIC_URL=https://hitkeep.example.comSee the configuration reference for all custom-domain runtime switches.
Domain model
Section titled “Domain model”- Domains belong to a team, not an individual site.
- A team can verify multiple domains.
- Every active team domain works for every site in that team.
- Site Settings does not assign domains to the site. It only chooses which available host to use in the generated snippet.
- The instance URL always remains available as a tracker endpoint.
- Hostnames are normalized as lowercase ASCII fully qualified domain names.
- Hostnames cannot conflict with the configured
HITKEEP_PUBLIC_URLhost, existing site domains, or another team’s custom tracking domain.
Custom tracking hosts are tracking-only. HitKeep serves only:
GET /hk.jsGET /hk-vitals.jsPOST /ingestPOST /ingest/eventPOST /ingest/web-vitals- matching
OPTIONSpreflight requests for ingest
Dashboard, API, auth, share links, MCP, QR redirects, and SPA fallback routes return 404 on a custom tracking host.
Verification records
Section titled “Verification records”Add the domain in Team Settings -> Tracking domains. HitKeep shows the exact DNS records to create.
TXT _hitkeep-tracking.analytics.example.comValue hitkeep-domain-verification=<token>
CNAME analytics.example.comValue <target shown in HitKeep>HitKeep checks three things before a domain can be used as a tracker endpoint:
- DNS ownership TXT record exists and matches the generated token.
- DNS routing target matches the deployment target. By default this is the host from
HITKEEP_PUBLIC_URL; managed cloud uses the regional origin target shown in the dashboard. https://analytics.example.com/hk.jsreturns the tracker asset with valid TLS.
The HTTPS probe is what turns a DNS-verified domain into an active tracker endpoint. Until then, the domain can exist in Team Settings, but Site Settings does not offer it as a snippet host.
HitKeep Cloud flow
Section titled “HitKeep Cloud flow”- Open Team Settings -> Tracking domains.
- Add a subdomain such as
analytics.example.com. - Create the TXT ownership record.
- Point the subdomain to the cloud target shown in the dashboard.
- Click Verify.
- Wait for TLS to become ready.
- Open the site’s tracking settings and choose the instance URL or any active team tracker domain for the generated snippet.
The generated snippet changes from the regional cloud host to the selected domain:
<script async src="https://analytics.example.com/hk.js"></script>Cloud uses Caddy on-demand TLS behind the same HitKeep allow endpoint described below. Teams do not need to configure Caddy themselves in the managed product.
Self-hosted flow
Section titled “Self-hosted flow”Self-hosted HitKeep uses the same dashboard flow and verification checks, but the operator controls DNS, TLS, and the reverse proxy.
For a normal externally terminated proxy, set:
HITKEEP_CUSTOM_TRACKING_TLS_MODE=externalThen point each tracker hostname at the same host as HITKEEP_PUBLIC_URL, and configure your proxy to:
- terminate TLS for each verified tracking hostname
- forward requests to the HitKeep process
- preserve the original
Hostheader - publish
/hk.js,/hk-vitals.js, and the ingest routes
HitKeep still enforces the tracking-only host boundary, so an accidentally proxied dashboard route on a custom tracking host returns 404.
The HitKeep repository includes external-TLS examples for operators who manage certificates outside Caddy:
examples/nginx.custom-tracking.confandexamples/compose.nginx-custom-tracking.ymlexamples/traefik.custom-tracking.ymlandexamples/compose.traefik-custom-tracking.yml
Kubernetes installs can use the official Helm chart’s customTrackingDomains values to set the HitKeep runtime mode and optionally create a tracking-only Ingress for static tracker hostnames. See the Kubernetes guide.
In external mode, add each tracking hostname to the proxy before clicking Verify. The proxy must already present a valid certificate for https://<hostname>/hk.js; otherwise HitKeep keeps the domain inactive.
Optional Caddy on-demand TLS
Section titled “Optional Caddy on-demand TLS”Use Caddy on-demand TLS when self-hosted teams should be able to add tracker domains from the dashboard without the operator editing a Caddyfile for every hostname.
Generate an ask token:
export HITKEEP_CADDY_TLS_ASK_TOKEN="$(openssl rand -hex 32)"Enable Caddy mode on HitKeep:
HITKEEP_CUSTOM_TRACKING_TLS_MODE=caddy-on-demandHITKEEP_CADDY_TLS_ASK_TOKEN=$HITKEEP_CADDY_TLS_ASK_TOKENConfigure Caddy with a restricted ask endpoint:
{ email ops@example.com on_demand_tls { ask http://hitkeep:8080/internal/caddy/on-demand-tls/{$HITKEEP_CADDY_TLS_ASK_TOKEN} }}
https:// { tls { on_demand }
reverse_proxy hitkeep:8080 { header_up Host {host} header_up X-Forwarded-Host {host} header_up X-Forwarded-Proto {scheme} }}Caddy calls the ask URL with ?domain=<hostname> before issuing a certificate. HitKeep returns 204 only when the token matches and the hostname is an enabled, DNS-verified custom tracking domain. Unknown, disabled, malformed, or wrong-token requests are denied.
Do not enable Caddy on-demand TLS without ask. Caddy treats any 2xx ask response as allowed, and the ask gate is the control that prevents arbitrary certificate issuance. See Caddy’s official on-demand TLS overview, Automatic HTTPS, and global options documentation.
The HitKeep repository includes example files:
Security notes
Section titled “Security notes”Browser ingest still resolves the tracked site from the page Origin, not from the tracker host. When the request host is a custom tracking domain, HitKeep additionally checks that the custom tracking domain and the resolved site belong to the same team. That prevents another team from reusing someone else’s verified tracker host.
The Go binary does not embed Caddy and does not require Caddy. The optional profile is an operational convenience for TLS automation; HitKeep remains a single-binary application when you terminate TLS elsewhere.