March 12, 2026 (3mo ago)
Written by Temps Team
Last updated March 12, 2026 (3mo ago)
Yes. You can add web analytics to any website without loading a single script from an external domain. The approach is called first-party analytics: the tracking script is served from your own domain, data is sent to your own server, and nothing ever touches google-analytics.com, plausible.io, or any other external host.
This matters for three reasons. Ad blockers target external analytics domains by name — roughly 42% of internet users run one, and among developer audiences the number is higher. First-party scripts bypass this entirely. Third-party analytics cookies trigger stricter GDPR requirements and can require a consent banner in many jurisdictions — first-party analytics that use only first-party cookies or session heuristics avoid cross-site tracking concerns entirely. And third-party scripts transfer your visitors' data to an external company's servers, creating legal exposure under Schrems II and various national DPA rulings.
This guide covers how first-party analytics work under the hood, how to build a minimal system yourself, and how Temps includes analytics as a built-in platform feature — no separate service, no separate subscription.
TL;DR: Third-party analytics scripts get blocked by 42% of users, add hundreds of milliseconds to page load, and send your visitors' data to external servers. First-party analytics — served from your own domain, stored on your own server — solve all three problems. Temps includes built-in first-party analytics in every deployment, with a React SDK that routes all tracking through your own domain via
basePath="/api/_temps".
Third-party analytics break in four distinct ways. The HTTP Archive Web Almanac found that Google Analytics scripts add a median of 350ms to page interactive time. That's before you consider the privacy, accuracy, and legal problems stacking on top.
GA4's JavaScript payload weighs roughly 45KB gzipped. That doesn't sound like much, but the real cost isn't the download — it's the execution. The script parses, evaluates, sets cookies, fingerprints the browser, and fires multiple beacon requests to google-analytics.com.
On mobile devices with slower CPUs, this adds 200-500ms to time-to-interactive. Google's own Core Web Vitals punish exactly this kind of third-party JavaScript bloat. You're hurting your search ranking to track your search traffic.
When a visitor lands on your site, GA4 sends their IP address, screen resolution, browser fingerprint, referrer, and page URL to Google's servers. Google uses this data across its advertising network. Even with IP anonymization enabled, the data still travels to Google before being truncated. Multiple European DPAs ruled against Google Analytics between 2022 and 2024 for this reason.
42% of internet users worldwide use an ad blocker. Every single one of those users is invisible to Google Analytics. That's not a small margin of error — you're making business decisions based on data that's missing nearly half your audience.
The French data protection authority CNIL fined Criteo 40 million euros in 2023 for GDPR violations related to tracking without proper consent. You now need explicit, informed consent before loading GA4. That means a cookie banner — and cookie banners reduce opt-in rates to 30-50% in most implementations, making your already-incomplete data even less accurate.
| Feature | Temps | Plausible | Umami |
|---|---|---|---|
| First-party script (your domain) | Yes — basePath="/api/_temps" routes all tracking through your own domain | Requires proxy setup | Requires proxy setup |
| No third-party cookies | Yes — only first-party cookies set by your own domain | Yes — cookieless | Yes — cookieless |
| GDPR-friendly | Yes — no cross-site tracking, data stays on your server | Yes | Yes |
| Self-hostable | Yes — free, Apache 2.0 | Yes (requires separate ClickHouse + PostgreSQL) | Yes (requires separate PostgreSQL/MySQL) |
| Session replay built-in | Yes — enableSessionRecording={true} | No | No |
| Error tracking built-in | Yes | No | No |
| Uptime monitoring built-in | Yes | No | No |
| Included in deployment platform | Yes — analytics, hosting, DB, email in one binary | No — standalone service | No — standalone service |
| Pricing | ~$6/mo on Temps Cloud; self-host free | Cloud from $9/mo | Free (self-host); see pricing page for cloud |
The key structural difference: Plausible and Umami are standalone analytics tools you deploy alongside your app. Temps is a deployment platform that includes analytics natively. You're not adding another service — analytics are already running on the same server as your application.
First-party script, no third-party domain calls. Temps analytics are served from your own domain. The React SDK's basePath="/api/_temps" prop routes all tracking requests through your own server — the browser never contacts an external analytics domain. Ad blockers that target known analytics endpoints by hostname see only requests to your own origin.
No third-party cookies — data stays on your own server. Temps analytics use first-party cookies (_temps_visitor_id, _temps_sid) set by your own domain via the Temps proxy, not by any external tracker. Visitor data never leaves your infrastructure. There is no cross-border data transfer to a third-party analytics company, which eliminates the Schrems II exposure that made Google Analytics legally problematic in the EU.
Included in Temps Cloud at ~$6/mo — no separate analytics subscription. Temps Cloud runs on Hetzner infrastructure at cost plus 30% margin. That covers the deployment platform, built-in web analytics, session replay, error tracking, uptime monitoring, managed databases, and transactional email — all in a single Rust binary. There is no separate analytics tier, no per-seat fee, and no bandwidth bill.
First-party analytics flip the third-party model. Instead of loading a script from google-analytics.com, you serve it from yoursite.com/t.js. Instead of beaconing data to an external server, requests go to yoursite.com/api/collect.
Because everything stays on the same origin, ad blockers don't flag it. There are no cross-origin requests. No third-party cookies. The browser treats it like any other resource on your site.
First-party analytics consistently capture 30-40% more page views than third-party scripts on the same site — simply because nothing gets blocked.
It depends on the implementation. Some first-party analytics tools (Plausible, Umami) use no cookies at all — they use server-side session heuristics instead, combining the visitor's IP address hash, User-Agent string, and a time window to group page views into sessions.
Temps uses first-party cookies (_temps_visitor_id, _temps_sid) set by your own domain to persist visitor identity across sessions. These are first-party cookies — not cross-site tracking cookies. The key legal difference from GA4 is that the data never leaves your server; there's no third-party company receiving your visitors' data. If you need a fully cookieless setup, the DIY approach below or Plausible/Umami accomplish that.
You can build a working first-party analytics system in under 100 lines of code. The client-side snippet is about 25 lines of JavaScript. The server endpoint depends on your stack, but the logic is the same regardless of language.
// analytics.js — serve this from YOUR domain, not an external CDN
(function() {
const endpoint = '/api/collect';
function track(event, data) {
const payload = JSON.stringify({
event: event,
url: window.location.pathname,
referrer: document.referrer || null,
screen: window.innerWidth + 'x' + window.innerHeight,
...data
});
if (navigator.sendBeacon) {
navigator.sendBeacon(endpoint, payload);
} else {
fetch(endpoint, {
method: 'POST',
body: payload,
keepalive: true
});
}
}
track('pageview', {
utm_source: new URLSearchParams(location.search).get('utm_source'),
utm_medium: new URLSearchParams(location.search).get('utm_medium'),
utm_campaign: new URLSearchParams(location.search).get('utm_campaign')
});
})();
That's 25 lines. It weighs about 600 bytes minified — invisible in a network waterfall. Compare that to GA4's 45KB.
// collect.js — your server-side endpoint
const crypto = require('crypto');
const { pool } = require('./db'); // your PostgreSQL pool
function getDailySalt() {
return new Date().toISOString().split('T')[0];
}
function hashSession(ip, userAgent) {
return crypto
.createHash('sha256')
.update(ip + userAgent + getDailySalt())
.digest('hex')
.substring(0, 16);
}
app.post('/api/collect', async (req, res) => {
const { event, url, referrer, screen, utm_source,
utm_medium, utm_campaign } = req.body;
const ip = req.headers['x-forwarded-for'] || req.ip;
const userAgent = req.headers['user-agent'];
const sessionHash = hashSession(ip, userAgent);
await pool.query(`
INSERT INTO page_views
(timestamp, event, url_path, referrer, country,
device_type, browser, session_hash,
utm_source, utm_medium, utm_campaign)
VALUES
(NOW(), $1, $2, $3, geoip_country($4),
parse_device($5), parse_browser($5), $6,
$7, $8, $9)
`, [event, url, referrer, ip, userAgent,
sessionHash, utm_source, utm_medium, utm_campaign]);
res.status(202).end();
});
CREATE TABLE page_views (
id BIGSERIAL PRIMARY KEY,
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
event VARCHAR(50) NOT NULL DEFAULT 'pageview',
url_path TEXT NOT NULL,
referrer TEXT,
country VARCHAR(2),
device_type VARCHAR(20),
browser VARCHAR(50),
os VARCHAR(50),
screen VARCHAR(20),
session_hash VARCHAR(16),
utm_source VARCHAR(100),
utm_medium VARCHAR(100),
utm_campaign VARCHAR(100)
);
CREATE INDEX idx_pv_timestamp ON page_views (timestamp DESC);
CREATE INDEX idx_pv_url ON page_views (url_path, timestamp DESC);
CREATE INDEX idx_pv_session ON page_views (session_hash, timestamp);
If you're using TimescaleDB, convert this to a hypertable for automatic time-based partitioning:
SELECT create_hypertable('page_views', 'timestamp');
The hashSession function above combines IP + User-Agent + daily salt into a hash. Two requests from the same browser on the same day produce the same hash — that's your session identifier.
Users behind the same NAT with the same browser will be merged into one session. For aggregate analytics, this is more than accurate enough. You're trading individual-level precision for zero cookies and full GDPR compliance. For most sites, that's the right tradeoff.
Several mature open-source projects offer privacy-first analytics. Each requires a separate deployment alongside your app.
Plausible is the gold standard for privacy-first standalone analytics. Under 1KB script, GDPR-compliant without consent, clean dashboard. The cloud version starts at $9/month. Self-hosting is free but requires Docker Compose with ClickHouse and PostgreSQL — that's a separate server to maintain.
Best for: Teams who want a dedicated analytics product and don't mind managing another service.
Umami is fully open-source and free. It needs PostgreSQL or MySQL and runs as a Node.js application. The dashboard is clean and focused. But it's another deployment to manage, another database to back up, another service to keep updated.
Best for: Developers comfortable with self-hosting who want zero cost and full control over a standalone analytics tool.
PostHog goes far beyond basic analytics — it includes session replay, feature flags, A/B testing, and surveys. PostHog Community Edition is MIT-licensed (core); enterprise features are proprietary. Expect 1GB+ RAM minimum, and the ClickHouse dependency means serious infrastructure overhead.
Best for: Product teams who need the full analytics suite and have the infrastructure budget.
But what if analytics came built into your deployment platform? What if you didn't need a separate service at all?
Temps includes first-party web analytics as a built-in platform feature — no separate service, no extra database, no additional deployment. Every application you deploy through Temps gets analytics running on the same infrastructure, using the same TimescaleDB instance that powers the rest of the platform.
Analytics and hosting share the same infrastructure needs: a database, a server, an HTTP endpoint. Combining them eliminates an entire category of operational overhead that developers normally accept as unavoidable.
// app/layout.tsx
import { TempsAnalyticsProvider } from '@temps-sdk/react-analytics';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<TempsAnalyticsProvider
basePath="/api/_temps"
enableSessionRecording={true}
>
{children}
</TempsAnalyticsProvider>
</body>
</html>
);
}
basePath="/api/_temps" routes all tracking requests through your own server — the browser never contacts an external analytics domain. enableSessionRecording={true} activates session replay, which records user interactions for debugging and UX analysis, also stored on your own infrastructure.
import { useTrackEvent } from '@temps-sdk/react-analytics';
export function SignupButton() {
const trackEvent = useTrackEvent();
return (
<button
onClick={async () => {
await trackEvent('signup_clicked', { plan: 'free' });
}}
>
Get started
</button>
);
}
import { useTempsAnalytics } from '@temps-sdk/react-analytics';
export function TrackOnMount({ pageName }: { pageName: string }) {
const { trackEvent } = useTempsAnalytics();
useEffect(() => {
trackEvent('page_viewed', { name: pageName });
}, [pageName]);
return null;
}
<script
defer
src="https://your-temps-domain.com/t.js"
data-domain="yoursite.com"
></script>
That's it. No API keys to configure, no separate dashboard to log into. Analytics appear in the same Temps dashboard where you manage deployments.
The Temps analytics dashboard includes:
Temps analytics use first-party cookies set by your own domain — not third-party tracking cookies set by an external analytics company. Visitor data (IP addresses, session identifiers) stays on your server and is never transferred to a third-party analytics vendor.
No cross-site data transfer means no Schrems II complications with EU-US data flows — the problem that made Google Analytics legally contested in Austria, France, and Italy. Because you own the infrastructure, you can implement data retention policies, deletion requests, and data minimization on your own terms.
It depends on whether you use cookies. Fully cookieless first-party analytics (like the DIY heuristic approach, Plausible, or Umami) don't trigger the ePrivacy Directive's consent requirement, because that rule specifically targets "storage of information on a user's device." The French CNIL and other European DPAs have confirmed that cookie-free analytics can operate without consent.
Temps uses first-party cookies (_temps_visitor_id, _temps_sid) set by your own domain, which puts it in a different legal category than third-party trackers. Whether first-party analytics cookies require consent depends on their purpose and your jurisdiction — consult your legal counsel for a definitive answer. The key advantage over Google Analytics is that visitor data never leaves your infrastructure, eliminating cross-border data transfer concerns entirely.
First-party analytics typically capture 30-40% more traffic than Google Analytics because they aren't blocked by ad blockers. A study by Plausible found that sites running both GA4 and Plausible simultaneously saw 26-40% higher page view counts in Plausible. The tradeoff is slightly less precise session tracking, since heuristic-based sessions aren't as exact as cookie-based ones.
Yes. First-party analytics work with any website — static HTML, Next.js, Astro, Hugo, or anything else that serves web pages. The tracking snippet is plain JavaScript that sends a beacon to your server endpoint. For static sites hosted on Temps, analytics work automatically with the <script> tag approach shown above.
Minimal. A well-built first-party analytics snippet weighs under 2KB and uses the non-blocking Beacon API. That adds roughly 1-5ms to page load — compared to GA4's 200-500ms impact measured by the HTTP Archive Web Almanac. The difference is significant enough to measurably improve Core Web Vitals scores.
Both are self-hostable and free. The difference is what you're deploying. Plausible requires a dedicated server running ClickHouse, PostgreSQL, and the Plausible application — a separate operational surface to maintain, update, and back up. Temps includes analytics as part of the deployment platform you're already running. If you're hosting an application on Temps, analytics are already running at no additional infrastructure cost.
Third-party analytics made sense when there were no alternatives. That's no longer the case. You can track everything you need — page views, referrers, campaigns, devices — without sending a single byte of user data to an external server.
Whether you build it yourself with the code examples above, use an open-source tool like Plausible or Umami, or go with a platform that includes analytics natively — the important thing is to stop accepting the performance hit, the data loss, and the legal risk that come with third-party scripts.
If you want analytics built into your deployment platform with zero extra infrastructure, Temps handles it out of the box. Deploy your app, add one component, and you've got privacy-first analytics running on your own server — included in the same ~$6/mo you'd pay for the hosting.
curl -fsSL https://temps.sh/install.sh | bash