The short answer
A GA4 setup for a marketing site is done when four things are true: every lead is counted once, as a key event sent after your form actually succeeds; data is kept for 14 months instead of 2; your own team's visits are filtered out; and consent mode matches what your banner promises. Everything else on this list (UTMs, Search Console, Google Ads, cross-domain) makes the reports easier to read, but those four decide whether the numbers can be trusted at all.
The settings below come from Google's own Analytics Help and developer documentation, read on 21 October 2026. Work through them in order: the first section takes about an hour, the rest can wait until launch week.
The checklist
| Step | Where in GA4 | What to set | Why |
|---|---|---|---|
| Property time zone and currency | Admin, Property details | Your business's time zone and billing currency | Changing time zone later only affects data going forward |
| One web data stream | Admin, Data streams | One stream for the site, its "G-" ID installed once | Two tags on a page double-count everything |
| Enhanced measurement | Data stream settings | Keep page views, scrolls, outbound clicks, downloads; turn off form interactions if you send your own lead event | Form interactions record attempts, not leads |
| Key events | Admin, Key events | Your lead event, plus at most a few secondary actions | 30 key events per standard property |
| Consent mode | Your banner or tag manager | Basic or advanced, with all four consent types | Google's EU consent policy covers EEA, UK and Swiss visitors |
| Data retention | Admin, Data collection, Data retention | 14 months | Explorations and funnels only reach back as far as retention |
| Internal traffic | Data stream, Configure tag settings | IP rules, then a filter tested before you activate it | Active filters delete data permanently |
| Unwanted referrals | Data stream, Configure tag settings | Payment, booking and login domains | Otherwise leads are credited to those tools |
| Cross-domain | Data stream, Configure tag settings | Every domain a visitor crosses before converting | Keeps one user and one session |
| Search Console | Admin, Product links | One web stream to one Search Console property | Adds query and landing page reports |
| Google Ads | Admin, Product links | Link, auto-tagging on, import the lead key event | Ads bids on the leads GA4 counts |
| Data sharing | Admin, Account settings | Off unless you need it | One setting makes Google an independent controller |
| Verification | DebugView | A test lead, seen with its parameters | Proves the setup before you report on it |
Start with one property and one stream
A property holds the reports; a web data stream is the site sending data into it. Most marketing sites need exactly one of each, including sites in several languages on one domain. Create them following Set up Analytics for a website, choose the reporting time zone and currency carefully (Google notes that changing the time zone later only affects data going forward and can leave a flat spot or spike in reports), and make sure the account belongs to the company, not to the agency or freelancer who builds the site.
Install the Google tag once. The most common duplication we see is a theme or site builder that already injects the tag plus a Google Tag Manager container that fires it again: every page view and event is counted twice, and nothing in the reports looks broken.
Enhanced measurement: keep most of it, switch off form interactions
Enhanced measurement collects events without code. Google documents each one, and on a marketing site we treat them like this:
- Page views are always on; Google says you can't turn off collection. Leave the history-change option on if your site changes pages without full reloads.
- Scrolls fire once per page, when 90% of the page's height becomes visible. Useful on long articles, meaningless on short pages.
- Outbound clicks fire for links leaving your domain, except to domains you list for cross-domain measurement. Keep them.
- Site search fires when the URL carries
q,s,search,queryorkeyword. If your search uses another parameter, add it in the settings; if you have no search, it simply never fires. - Video engagement only covers embedded YouTube videos.
- File downloads fire for links to common file types such as PDFs and spreadsheets. Keep them if you publish brochures or price lists.
- Form interactions send
form_startandform_submit. Google definesform_submitas "when the user submits a form", which is an attempt: the browser can't know whether your server accepted the lead or returned an error. Turn this option off once you send your own lead event, or you'll have two numbers that never match.
Key events: count leads, not page views
A key event is an event you mark as important; GA4 uses key events in acquisition reports, and Google Ads can import them as conversions. Google lets you mark up to 30 events as key events on a standard property. A lead-generation site needs one primary key event and perhaps two or three secondary ones (a booked call, a newsletter sign-up, a pricing-page visit you've decided matters). Thirty key events is a symptom, not a strategy.
These are the ways to count a lead, from most to least reliable:
| Method | What it counts | Use it when |
|---|---|---|
generate_lead sent after your server confirms the submission | Leads your system actually received | You control the site's code, or your form tool offers a success callback |
An event created from the confirmation page's page_view | Visits to the thank-you page | The page only loads after a successful submission and is excluded from search |
Enhanced measurement form_submit | Submit attempts, including failed ones | Never as a key event |
| Every page view | Nothing useful | Never |
Google names generate_lead as the recommended event for "when a lead has been generated (for example, through a form)". Send it from the code that handles the response, not from the button's click:
// Runs only after your form endpoint confirms the lead was stored
const response = await fetch('/api/contact', { method: 'POST', body: formData });
if (response.ok) {
gtag('event', 'generate_lead', {
form_name: 'contact', // which form, never the visitor's details
value: 150, // optional: what a lead is worth to you
currency: 'USD' // required whenever you send value
});
}If you can't touch the code, Google's own help shows how to create a new event from the confirmation page's page view and mark that as the key event. It works if the thank-you page can't be reached any other way: no links to it, excluded from your sitemap and search, and no reload loop that counts the same person twice.
Two settings finish the job. Keep the counting method on "Once per event", which Google recommends. And if you send extra parameters such as form_name, register them as custom dimensions, or they won't appear in reports.
Never send the visitor's name, email or phone in an event or URL. Google's policy on personally identifiable information forbids sending anything Google could use to identify a person, and the page URL is the usual leak: a form that redirects to /thanks/?email=... breaks the policy on every lead. GA4's data redaction can strip email addresses and listed query parameters on a best-effort basis; fix the URL anyway.
Consent mode v2: basic or advanced
Consent mode passes your banner's answer to Google's tags. Version 2 added two consent types to the original two, so a complete setup sends four: ad_storage, analytics_storage, ad_user_data and ad_personalization. Google's EU user consent policy requires legally valid consent from visitors in the European Economic Area, the UK and Switzerland, and the consent mode guide tells advertisers to send the two new types for that traffic.
The choice is between two implementations, as Google's setup guide describes them:
| Basic | Advanced | |
|---|---|---|
| Before the visitor answers | Google tags don't load at all | Tags load with consent set to denied |
| If the visitor declines | Nothing is sent to Google, not even the choice | Cookieless pings are sent |
| Modeling of declined visitors | General model only | Advertiser-specific model |
| Fits | A strict reading of consent, small sites | Sites with enough traffic to be modeled |
The modeling argument for advanced mode rarely applies to a small site. Behavioral modeling needs advanced consent mode, at least 1,000 events a day with analytics storage denied for 7 days, and at least 1,000 daily users who granted consent on 7 of the previous 28 days. A B2B site with a few hundred visitors a day won't qualify, so for it advanced mode mostly means sending pings about people who said no. Pick the mode your privacy policy and your counsel support; this article isn't legal advice.
For advanced mode, the defaults go before the Google tag, and the update runs when the visitor chooses:
gtag('consent', 'default', {
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
analytics_storage: 'denied'
});
// Visitor accepts analytics but not advertising
gtag('consent', 'update', { analytics_storage: 'granted' });Data retention: switch to 14 months on day one
A standard property keeps user-level and event-level data for 2 or 14 months; 26, 38 and 50 months are for Analytics 360 only. The setting doesn't touch standard aggregated reports, but it limits explorations and funnel reports, which are where you answer questions like "how many leads came from organic search last spring". At 2 months, year-on-year comparisons in explorations are impossible.
Change it to 14 months the day you create the property. Age, gender and interest data stay at 2 months whatever you choose. If you need raw history beyond 14 months, the BigQuery export is free to start in the BigQuery sandbox and capped at 1 million events a day on standard properties, far above what a marketing site sends.
Filter your own traffic, and test the filter first
Internal traffic rules tag events from IP addresses you list with traffic_type=internal; a data filter then excludes them. Two warnings from Google's documentation matter more than the steps:
- An active filter is permanent. Excluded data is never processed and never reaches GA4 or BigQuery, and filters don't apply to data collected before they existed.
- Filters have three states: Testing, Active and Inactive. Leave a new filter in Testing, check the "Test data filter name" dimension in an exploration, and activate it only once it matches what you expect. Google says a filter can take 24 to 36 hours to apply.
You can create up to 10 data filters per property. Add the developer traffic filter too, so test hits sent in debug mode stay out of reports. IP rules don't help a remote team on home connections; for them, the practical fix is to do testing in debug mode and accept a little noise.
Unwanted referrals and cross-domain measurement
When a visitor leaves for another domain and comes back, GA4 may credit the session to that domain. Unwanted referrals fix this for tools in the middle of your funnel: payment processors, booking or scheduling pages, and login or password-reset flows. You can list up to 50 per data stream.
Cross-domain measurement is the stronger fix when you own both sides, for example a marketing site on one domain and an app or shop on another. GA4 passes its IDs in a _gl URL parameter when visitors click between the domains you list (up to 100 conditions), so one person stays one user and one session.
UTM conventions that keep channels clean
GA4 sorts traffic into channels with fixed rules, and the default channel group definitions can't be edited. Your UTM tags decide which channel a click lands in, so write them for those rules:
| Parameter | Convention | Example |
|---|---|---|
utm_source | The platform, one fixed value each | linkedin, newsletter, partner-name |
utm_medium | The channel, using a value GA4 recognises | email, social, paid_social, cpc, referral |
utm_campaign | The exact campaign name, lowercase, hyphens | q4-webinar-2026 |
utm_content | The creative or link within the campaign | header-button, video-a |
utm_term | Paid search keyword, if you set it manually | website-migration |
utm_id | Your campaign ID, if you import cost data | cmp-0142 |
Some details from Google's rules: a medium of email lands in Email, and social in Organic Social; Paid Social needs a social source plus a medium matching cp, ppc, retargeting or anything starting with paid. Values are case-sensitive, so LinkedIn and linkedin become two rows; Google's UTM best practices recommend lowercase. Build links with Google's Campaign URL Builder and keep the agreed values in one shared sheet.
Don't tag internal links on your own site, and don't add UTMs to Google Ads when auto-tagging is on. The channel list also includes an AI Assistant channel, which GA4 assigns when the referrer matches its list of AI assistants or the medium is ai-assistant. If you're working on being cited by ChatGPT or Perplexity, that's where the visits show up, and our AI visibility checker shows whether those assistants' crawlers can read your site.
Link Search Console and Google Ads
Linking Search Console adds two reports: organic queries and organic landing pages. One web stream links to one Search Console property, the data arrives about 48 hours late and covers at most 16 months, and the report collection is unpublished by default: find it under Library and publish it, or you won't see it in the navigation.
Linking Google Ads needs Editor access in GA4 and admin access in Google Ads. Keep auto-tagging on, then import your lead key event into Google Ads as a conversion so bidding optimizes for the leads GA4 counts, not for clicks.
Data sharing, signals and reporting identity
Three account-level settings deserve a deliberate choice:
- Data sharing. When "Google products & services" is on, Google says it is an independent controller of the shared data under its controller terms. For a company that wants Google to act only as its processor, as Google's list of processor services describes Analytics, turn it off unless you have a reason.
- Google signals enriches reports with demographic and interest data from signed-in Google users who turned on Ads Personalization. A lead-generation site rarely needs it; turn it on only if you'll use those reports or audiences.
- Reporting identity. Google notes that the Blended and Observed options can make reports subject to data thresholds, which hide small numbers; Device-based uses only the device ID. On a low-traffic site, Device-based shows more of your data, and Google says you can switch between options at any time without a permanent effect.
Verify in DebugView before you trust a number
DebugView shows the events from a device in debug mode as they arrive. Turn debug mode on with Google Tag Assistant's preview mode, then:
- Load the home page once and check there's one
page_view, not two. - Accept and decline the consent banner in separate sessions, and check the consent state on the events.
- Submit a real test lead. Check that
generate_leadarrives once, withform_name, and that noform_submitkey event fires beside it. - Submit the form with an error and check that no lead event fires.
- Click a link to your booking or payment domain and back, and check that the session's source doesn't change.
Then delete the test lead from your CRM, and write down what you tested and when. The next person who changes the form will need it.
The mistakes we see most often
| Mistake | What it looks like | Fix |
|---|---|---|
| Tag installed twice | Every page view and event counted twice | Remove one installation |
form_submit or a page view as the key event | More "leads" in GA4 than in the CRM | Send generate_lead after success |
| Retention left at 2 months | Explorations stop two months back | Set 14 months now; history already deleted is gone |
| Filter activated untested | A sudden, permanent drop in traffic | Test first; you can't recover filtered data |
| Mixed-case UTMs | The same campaign in several rows | Lowercase, one shared naming sheet |
| Payment or booking domain not excluded | Leads credited to "referral" | List it in unwanted referrals |
| Email address in a URL | A policy breach on every submission | Remove it from the redirect |
| Consent banner that loads tags before the choice | Basic mode that isn't basic | Block the tag until consent, or switch to advanced deliberately |
If you're about to redesign or replatform, add analytics to the launch list: tags and key events are among the things a site migration quietly breaks.
When GA4 isn't the right tool
GA4 earns its place when your growth runs through Google: Search Console and Google Ads link to it at no cost. It's a weaker fit when you need to see what logged-in users do inside a product, when your consent policy makes most visitors invisible anyway, or when you'd rather keep visitor data out of an advertising company. Our comparison of PostHog vs Google Analytics covers when a privacy-first or product analytics tool fits better, and when to run both without counting a lead twice.
What to do next
Work through the checklist table above in one sitting, then run the five DebugView tests before you report a single number to anyone. If you'd like Dardo to set it up or audit an existing property, that's our analytics setup service; once the numbers are trustworthy, conversion rate optimization is the work of improving them.
Common questions
How many key events should a marketing site have in GA4?
Usually one primary key event for leads and two or three secondary ones, such as a booked call or a newsletter sign-up. Google allows up to 30 key events on a standard property, but every extra one makes acquisition reports harder to read and can mislead Google Ads bidding if you import it.
Can I use GA4's form_submit event as my lead conversion?
It's better not to. Google defines form_submit as the moment a visitor submits a form, so it also counts submissions your server rejected. Send generate_lead from the code that handles a successful response, or create an event from a confirmation page that only loads after success.
Should a small business use basic or advanced consent mode?
Basic mode is the simpler, stricter choice: Google tags don't load until the visitor accepts. Advanced mode sends cookieless pings when visitors decline, which mainly helps sites big enough to qualify for behavioral modeling, at least 1,000 daily events with analytics storage denied. Choose the mode your privacy policy and legal adviser support.
If I change GA4 data retention to 14 months, do I get old data back?
No. Increasing retention applies to data GA4 still holds, so events already deleted under the 2-month setting are gone. That's why the setting belongs in the first hour of a new property, not after the first quarterly report.
Do I need Google Tag Manager to set up GA4?
No. You can install the Google tag directly or through Tag Manager, but use one method. Installing both is the most common reason a site counts every page view twice. Tag Manager helps when marketers need to add or change tags without a developer.
How do I exclude my own team's visits if we work remotely?
GA4's internal traffic rules work by IP address, so they only help with fixed office or VPN addresses. For remote teams, test in debug mode with Tag Assistant, add the developer traffic filter so debug hits are excluded, and accept a small amount of noise from everyday browsing.
Sources & further reading
Sources behind this page, with further detail from the original publishers.
- Google Analytics Help: Set up Analytics for a website and/or appsupport.google.com
- Google Analytics Help: Enhanced measurement eventssupport.google.com
- Google Analytics Help: Mark events as key eventssupport.google.com
- Google Analytics Help: Create or modify key eventssupport.google.com
- Google Analytics Help: Change the counting method of key eventssupport.google.com
- Google for Developers: Recommended events (generate_lead)developers.google.com
- Google Analytics Help: Best practices to avoid sending personally identifiable informationsupport.google.com
- Google for Developers: Consent mode overviewdevelopers.google.com
- Google for Developers: Set up consent mode on websitesdevelopers.google.com
- Google: EU user consent policygoogle.com
- Google Analytics Help: Behavioral modeling for consent modesupport.google.com
- Google Analytics Help: Data retentionsupport.google.com
- Google Analytics Help: BigQuery Exportsupport.google.com
- Google Analytics Help: Filter out internal trafficsupport.google.com
- Google Analytics Help: Data filterssupport.google.com
- Google Analytics Help: Identify unwanted referralssupport.google.com
- Google Analytics Help: Set up cross-domain measurementsupport.google.com
- Google Analytics Help: Default channel groupsupport.google.com
- Google Analytics Help: URL builders and campaign datasupport.google.com
- Google Analytics: Campaign URL Builderga-dev-tools.google
- Google Analytics Help: Connect Search Console to Google Analyticssupport.google.com
- Google Analytics Help: Connect Google Ads to Google Analyticssupport.google.com
- Google Analytics Help: Data sharing settingssupport.google.com
- Google Business Data Responsibility: Processor services under the Google Ads Data Processing Termsbusiness.safety.google
- Google Analytics Help: Activate Google signalssupport.google.com
- Google Analytics Help: Reporting identitysupport.google.com
- Google Analytics Help: Monitor events in DebugViewsupport.google.com
