← All resources Guide

The best GA4 setup for multilingual websites

A website in three languages raises the same question every time: one GA4 property per language, or one for all of them? The answer is almost always one property, with the language added as a dimension. Separate properties triple the setup and maintenance (every key event, audience, link to Google Ads and custom dimension three times over) and make the most common question, "how does the whole site do?", impossible to answer without adding up reports by hand.

This guide covers the three ways multilingual sites are built, the GA4 setup for each, and how to add a page_language dimension in Google Tag Manager so you can still filter and compare per language.

Three ways to build a multilingual site

All three end in the same place: one GA4 property, one web data stream, one Google tag, and a language dimension. What differs is how the visitor's identity survives a move between languages.

Subfolders and subdomains: one property, nothing extra

With subfolders everything runs on one domain, so one Tag Manager container loading one Google tag is the whole setup. Subdomains are just as simple: GA4 sets its cookie on the root domain, so a visitor moving from nl.example.com to fr.example.com keeps the same client ID without any configuration. (Universal Analytics needed cross-domain settings for this; GA4 does not.)

You can use one container across all subdomains or one per subdomain, as long as each loads the same measurement ID. One container is easier to keep consistent.

Separate domains: one property plus cross-domain tracking

Cookies are tied to a domain, so a visitor who goes from example.nl to example.fr would start a new session as a new user, with the first domain as referrer. Using the same measurement ID on both is necessary but not enough. Add both domains to the data stream:

  1. In GA4, go to Admin › Data collection and modification › Data streams and open your web stream.
  2. Click Configure tag settings, then Configure your domains.
  3. Add a condition for each domain, match type Contains: example.nl, example.fr, and so on. Save.

The Google tag now adds a _gl parameter to links between those domains, carrying the client ID across, and GA4 stops treating them as referrals to each other. The full background, including redirects and forms that drop the parameter, is in cross-domain tracking between two different root domains.

Why GA4's own Language dimension is not enough

GA4 already has a dimension called Language, and it is tempting to use it. It holds the visitor's browser language, not the language of the page they read. A Dutch speaker with an English browser reading your Dutch pages counts as English, and an expat browsing your French site from a German laptop counts as German. For "how do my language versions perform" you need the page's language, which you add yourself as page_language.

Building page_language in Tag Manager

Pick the most reliable source on your site:

Use language codes (nl, fr, en) rather than names. They are shorter, never get translated by accident, and match what most CMSs, feeds and ad platforms use.

Sending it with every event and registering it

  1. Add a row to your Google Tag: Event Settings variable: parameter page_language, value {{Page language}}. If you set up content groups, this is the same variable.
  2. Make sure that variable is selected under Shared event settings in the Google tag and under Event Settings Variable in every GA4 event tag.
  3. In GA4, go to Admin › Data display › Custom definitions › Create custom dimension: name Page language, scope Event, event parameter page_language. Spell it exactly as in Tag Manager.

Register the dimension before you publish the container: custom dimensions only fill from the moment they exist. Then test in Tag Manager Preview and GA4 DebugView on a page in each language.

Content groups that work across languages

With the language in its own dimension, your content groups should leave it out. Group /nl/blog/, /fr/blog/ and /blog/ all as Blog (a pattern such as /blog/ without an anchor matches all three), and you can compare the blog across languages, or every section within one language, with two dimensions instead of a long list of combined groups. Translated slugs need one row per language: /blog/|/blogue/.

Ecommerce, currencies and Google Ads

When you run GA4 through a server container

The setup above is the same: page_language and content_group are set in the browser and reach GA4 through the server container unchanged. Two things to align. With separate domains, every domain needs its own first-party tagging host, and the cross-domain settings above still apply in the data stream. And with one server container behind all languages, you can use page_language in server-side triggers, for example to send Dutch and French purchases to different Meta pixels. In Measurebase, one domain covers its subdomains; separate country domains are separate domains on the same account, see running multiple domains on one account.

Frequently asked questions

Should I ever use a separate GA4 property per language?

Only when the language versions are really separate businesses: different owners, teams that must not see each other's data, or legal reasons. For one company with one site in several languages, one property is easier to run and gives you totals without extra work.

Do I need a separate data stream per language?

No. One web data stream handles every domain, subdomain and subfolder. Multiple web streams in one property split your configuration (enhanced measurement, domains, internal traffic) without adding anything you cannot get from page_language.

What about a site where the default language has no prefix?

Then the RegEx Table needs the default value to be that language, since its pages match no pattern. The lang attribute avoids this entirely, which is one more reason to prefer it.

Can I see which language a visitor switched to?

Yes. Track clicks on your language switcher as an event (for example language_switch with from and to parameters), or compare page_language of the landing page with later pages in an exploration.

Does hreflang matter for GA4?

No. hreflang tells search engines which page serves which language; GA4 ignores it. It is a good sign that your lang attributes are set correctly too, which the recommended variable relies on.

Continue reading

Ready to improve your tracking setup?

Start free, no credit card required. Live in about 15 minutes.

Start free