This guide walks you through building a privacy-first analytics setup that runs Plausible alongside GA4. You can complete the core configuration in under two hours. The result is a dual-layer stack that gives you cookie-free behavioural data from Plausible and deeper funnel reporting from GA4, without relying on third-party cookies or violating GDPR, CCPA, or Australia's Privacy Act 1988.
What You'll Build
- A Plausible Analytics instance configured with a custom domain proxy so ad blockers do not interfere with your data
- A GA4 property running in cookie-free mode with consent mode v2 enabled
- A lightweight consent banner that gates GA4 initialisation but keeps Plausible running unconditionally
- A single tagging architecture that avoids duplicate page-view events across both tools
- A Looker Studio report that blends Plausible export data with GA4 for a single reporting view
Prerequisites
- Access to your site's HTML or a tag manager (Google Tag Manager v2.5+ recommended)
- A Plausible Analytics account (plausible.io, from $9/month as of September 2026)
- A Google Analytics 4 property with admin access
- A Looker Studio account (free)
- Basic familiarity with DNS records if you want the custom proxy domain
Step 1: Set Up Your Plausible Property and Custom Proxy
Why does the proxy matter?
Plausible's default script loads from plausible.io. Many ad blockers flag that domain. A custom proxy routes the script through your own subdomain, which removes the block without compromising user privacy.
In your Plausible dashboard, go to Settings > Custom domain and enter a subdomain such as data.yoursite.com. Plausible will give you a CNAME record to add to your DNS.
; Add this CNAME in your DNS provider (Cloudflare, Route 53, etc.)
data.yoursite.com. CNAME custom.plausible.io.
DNS propagation takes 5 to 30 minutes. Once it resolves, Plausible marks the domain as verified in your dashboard.
Then update your tracking snippet to use the proxied URL:
<script defer data-domain="yoursite.com"
src="https://data.yoursite.com/js/script.js"></script>
Common pitfall: Do not enable Plausible's outbound-links or file-downloads extension in the script filename unless you have tested them. Each extension appends to the filename and must match what Plausible serves from the proxy.
Step 2: Configure GA4 in Cookie-Free Mode with Consent Mode v2
What is Consent Mode v2 and why does it apply to your market?
Google's Consent Mode v2 (mandatory for EEA since March 2024, now the de facto standard for AU, SG, CA, and US compliance as well) lets GA4 model conversions without storing cookies when a user declines. Without it, GA4 simply drops the event entirely. Modelled data is not perfect, but it typically recovers 60 to 80 percent of conversion signal in markets with high opt-out rates.
Add the consent mode default configuration before the GA4 snippet. This must fire on every page load before any other tag:
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
// Default all consent to denied until the user responds
gtag('consent', 'default', {
'ad_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'analytics_storage': 'denied',
'functionality_storage': 'denied',
'personalization_storage': 'denied',
'wait_for_update': 500
});
</script>
<!-- Google tag (gtag.js) -->
<script async
src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX">
</script>
<script>
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX', {
'client_storage': 'none',
'anonymize_ip': true
});
</script>
Setting client_storage: 'none' disables GA4's first-party cookie entirely. GA4 still fires session-scoped events using an in-memory client ID. Sessions are shorter and cross-session attribution is lost, but you stay compliant by default.
What if a user accepts cookies?
When the user accepts, your consent banner fires an update that re-enables storage:
// Run this after the user clicks "Accept" in your banner
function onUserAccept() {
gtag('consent', 'update', {
'ad_storage': 'granted',
'ad_user_data': 'granted',
'ad_personalization': 'granted',
'analytics_storage': 'granted',
'functionality_storage': 'granted',
'personalization_storage':'granted'
});
// Persist the choice to localStorage or a first-party cookie
localStorage.setItem('consent_status', 'accepted');
}
On subsequent page loads, read localStorage.getItem('consent_status') before the default consent block and update accordingly.
Step 3: Build a Lightweight Consent Banner
Should you use a third-party CMP?
Consent Management Platforms like Cookiebot or OneTrust are valid options for large organisations. For most SMBs in Australia, Canada, Singapore, or the US, a simple custom banner is sufficient and avoids an additional $50 to $150 per month in SaaS fees. The key requirement is that consent is explicit, unbundled, and recorded.
Here is a minimal banner pattern:
<div id="consent-banner" role="dialog" aria-label="Cookie consent">
<p>We use analytics cookies to improve this site.
Your basic visit data is always collected without cookies.
<a href="/privacy">Privacy policy</a>
</p>
<button id="btn-accept">Accept analytics cookies</button>
<button id="btn-decline">Decline</button>
</div>
<script>
const stored = localStorage.getItem('consent_status');
if (stored === 'accepted') {
onUserAccept();
document.getElementById('consent-banner').hidden = true;
} else if (stored === 'declined') {
document.getElementById('consent-banner').hidden = true;
}
document.getElementById('btn-accept').addEventListener('click', () => {
onUserAccept();
document.getElementById('consent-banner').hidden = true;
});
document.getElementById('btn-decline').addEventListener('click', () => {
localStorage.setItem('consent_status', 'declined');
document.getElementById('consent-banner').hidden = true;
});
</script>
Pro tip: Keep the banner copy plain and specific. Regulators in the EU and Australian Privacy Act guidance both flag vague language like "improve your experience" as insufficient. Name the purpose: "analytics cookies" and nothing more.
Step 4: Avoid Duplicate Page-View Events
Why do duplicate events happen in a dual-stack setup?
Both Plausible and GA4 fire page-view events independently. That is fine for counting, but if you push custom events to both tools, you may accidentally double your event totals inside a data warehouse or blended report.
The cleanest approach is to designate Plausible as your source of truth for raw traffic counts and GA4 as your source for conversion events and funnel data. Write a shared event dispatcher that routes events explicitly:
/**
* track(eventName, props, targets)
* targets: 'plausible' | 'ga4' | 'both'
*/
function track(eventName, props = {}, targets = 'both') {
if ((targets === 'plausible' || targets === 'both') && window.plausible) {
window.plausible(eventName, { props });
}
if ((targets === 'ga4' || targets === 'both') && typeof gtag === 'function') {
gtag('event', eventName, props);
}
}
// Example: track a form submission only in GA4
track('form_submit', { form_id: 'contact' }, 'ga4');
// Example: track a download in both
track('file_download', { file: 'brochure.pdf' }, 'both');
This pattern, tested in production on Next.js 15 and plain HTML sites, reduces event duplication errors by keeping routing logic in one place.
Step 5: Connect Both Sources to Looker Studio
How do you get Plausible data into Looker Studio?
Plausible does not have a native Looker Studio connector as of September 2026. Use the Plausible Stats API to export daily data into Google Sheets, then connect the sheet to Looker Studio as a data source.
A simple Apps Script that fetches yesterday's stats:
// Google Apps Script: paste into a time-triggered function
function fetchPlausibleStats() {
const API_KEY = 'your_plausible_api_key';
const SITE_ID = 'yoursite.com';
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
const dateStr = yesterday.toISOString().split('T')[0];
const url = `https://plausible.io/api/v1/stats/aggregate` +
`?site_id=${SITE_ID}&period=day&date=${dateStr}` +
`&metrics=visitors,pageviews,bounce_rate,visit_duration`;
const response = UrlFetchApp.fetch(url, {
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
const data = JSON.parse(response.getContentText()).results;
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('Plausible');
sheet.appendRow([
dateStr,
data.visitors.value,
data.pageviews.value,
data.bounce_rate.value,
data.visit_duration.value
]);
}
Set a daily trigger at 02:00 UTC. The sheet then acts as a rolling log. In Looker Studio, add it as a Google Sheets data source and blend it with your GA4 property using date as the join key.
This blended view lets you compare Plausible's cookie-free visitor count (always higher, since it counts all visitors) against GA4's consented session count. The gap tells you your opt-out rate, which is itself a useful brand health signal. If you want a broader picture of how your brand is performing across channels, the Lenka Studio brand health score assessment gives you a structured starting point.
Step 6: Validate the Setup
Open your site in a private browser window. Check three things:
- Open the Network tab. You should see a request to
data.yoursite.com/js/script.js. If you see a request toplausible.iodirectly, the proxy DNS has not propagated yet. - Decline the consent banner. Confirm that GA4 fires no
_gacookie by checking Application > Cookies in DevTools. Plausible should still log a page view in your Plausible real-time dashboard. - Accept the consent banner. Confirm GA4 sets a
_gacookie and that the GA4 DebugView in your property shows apage_viewevent.
If you manage analytics for multiple clients, the team at Lenka Studio use this same validation checklist before every analytics handoff to confirm consent mode is wired correctly end to end.
Frequently Asked Questions
Does Plausible count bots and crawlers?
Plausible filters known bot user agents automatically. It also excludes your own visits if you set the plausible-opt-out cookie in your browser from the Plausible dashboard. The visitor counts you see are generally 5 to 15 percent lower than raw server log counts for that reason.
Is this setup compliant with Australia's Privacy Act 1988?
Plausible collects no personal data and sets no cookies, so it falls outside the Privacy Act's personal information definition. GA4 in cookie-free mode with consent gating satisfies the Act's consent and collection requirements for most SMB use cases. You should still maintain a Privacy Policy that describes your analytics tools. This is not legal advice; confirm with a privacy lawyer for your specific situation.
What if GA4's modelled conversion data looks unreliable?
Consent Mode v2 modelling requires a minimum volume of consented events to build an accurate model. Google recommends at least 700 consented events per day per event type. Below that threshold, treat modelled data as directional rather than precise. Use Plausible's conversion goal tracking as a secondary check for lower-traffic sites.
Can I run this stack on a Webflow or Shopify site?
Yes. Both platforms allow custom script injection in the site header and footer. Add the consent default block and the Plausible snippet in the header. Add the consent banner script just before the closing body tag. The custom proxy DNS step is platform-agnostic since it only requires a CNAME record at your domain registrar.
How is this different from using a CMP like Cookiebot?
A CMP automates consent record-keeping and generates the consent banner UI. The approach in this guide is manual and requires you to store and read consent state yourself. CMPs also maintain a consent log that can be audited. For businesses processing data at scale or operating in the EEA, a CMP is worth the cost. For most AU, SG, CA, and US SMBs, the manual approach in this guide is proportionate.
Next Steps
Once both tools are running, spend a week comparing Plausible's visitor counts against GA4's consented sessions. The gap percentage is your baseline opt-out rate. If it exceeds 40 percent, revisit your banner copy. A clear, specific consent request consistently performs better than a generic one.
From there, consider setting up Plausible goals for your highest-value actions: contact form submissions, demo bookings, or checkout completions. Map those same actions as GA4 conversion events. You now have redundant conversion tracking that survives any single-tool failure.
If you want help configuring a compliant analytics stack for your business or integrating it with a broader reporting setup, the team at Lenka Studio works with SMBs across Australia, Singapore, Canada, and the US to build analytics infrastructure that is both clean and actionable. Get in touch and we can walk through your current setup.




