- A lookup table in Google Tag Manager returns a fixed value depending on the value of another variable.
- The lookup table checks for an exact match. For patterns, parts of a URL and several values per output, use the RegEx table.
- With GA4 you use them for content groups, campaigns via URL fragments, readable names for clicks and one measurement ID per domain, often with a single tag.
Lookup tables are among the most useful variables in Google Tag Manager. They turn values that Tag Manager already knows into the values you need in Google Analytics 4. Eoghan Henn first published this guide on rebelytics.com in 2015 and updated it on searchviu.com in 2018. This version is rewritten for GA4 and today's Tag Manager interface and covers all the original use cases.
What is a lookup table?
In Tag Manager, variables are placeholders whose value is only set when the page loads. Built-in variables such as {{Page URL}}, {{Page Hostname}} and {{Page Path}} return parts of the current address. On https://www.example.com/en/guides/, {{Page Hostname}} is www.example.com and {{Page Path}} is /en/guides/. Preview mode shows the values of all variables on your website under “Variables”.
A lookup table is a user-defined variable that takes the value of another variable as its input. For each row you define which output belongs to which input. If the input is /en/guides/, it returns “Guides”, for example, and for /en/pricing/ it returns “Pricing”. You use the output in tags, for instance as a GA4 parameter, or as a condition in triggers.
Google's help calls the variable type “Lookup Table”. Next to it sits the RegEx table, which checks regular expressions instead of fixed values.
Lookup table or RegEx table?
| Property | Lookup table | RegEx table |
|---|---|---|
| Check | Input equals the row's value | Input matches the row's pattern |
| Order | Each value stands on its own | Top to bottom, the first match wins |
| Default value | Optional via “Set Default Value” | Optional via “Set Default Value” |
| Upper and lower case | Must match exactly | Adjustable via “Ignore Case” |
| Reuse parts of the input | Not possible | With capture groups and $1, $2 |
| Good for | Fixed lists such as hostnames, fragments or link URLs | Directories, IDs in URLs, several values per output |
If no row matches and no default value is set, the table returns undefined. Decide deliberately what should happen in that case. For content groups a default such as “Other” makes sense, for campaigns usually none.
The RegEx table has advanced settings for case, full matches and capture groups. Check that they are set the way you need when you create the variable. At the bottom of every user-defined variable you also find “Format Value”. It lets you convert the output to lowercase, for example, or replace undefined with a text. Several options take effect in the order shown, from top to bottom.
How to set up a lookup table step by step
The first example assigns every page to a content group. GA4 has the parameter content_group for this and shows it in the “Content group” dimension. For Tag Manager, Google describes a RegEx table with {{Page Path}} as input, because site sections usually sit in directories. For a few fixed pages a lookup table is enough, and the steps are the same.
| Step | Where in Tag Manager | What you set |
|---|---|---|
| 1 | Variables › User-Defined Variables › New | Give it a name, such as “Content Group” |
| 2 | Variable Configuration | Choose “RegEx Table”, or “Lookup Table” for fixed values |
| 3 | Input Variable | {{Page Path}} |
| 4 | Table | Enter a pattern and an output per row, see the next table |
| 5 | Set Default Value | Enable it and enter “Other” |
| 6 | Advanced Settings | Check the case and full match options |
| 7 | Save, then Preview | Use Tag Assistant on several pages to check that the variable shows the right value |
| Pattern | Output |
|---|---|
^/en/guides/.* | Guides |
^/en/products/.* | Products |
^/en/help/.* | Help |
| Default value | Other |
With “Full Matches Only” enabled, the pattern has to cover the whole input. That is why every pattern ends in .*. Then open the Google tag, add the configuration parameter content_group with the value {{Content Group}} under “Configuration settings” and publish the container. If several Google tags share the same settings, create them once in a variable of the type “Google Tag: Configuration Settings” and reference it from each tag.
Tracking campaigns with URL fragments instead of UTM parameters
UTM parameters are long and stand out in shared links, for example ?utm_source=linkedin.com&utm_medium=social&utm_campaign=linkedin-posts. In 2014 Jim Gianoglio showed on the LunaMetrics blog how short URL fragments such as #linkedin can do the same job. The fragment is the part of the URL after the hash sign. Eoghan Henn refined the method together with web analyst Sascha Schau and used it on client websites. With GA4 it works in three steps.
Step 1. Read the fragment
Create a user-defined variable of the type “URL”, choose “Fragment” as the component type and name it “URL Fragment”. On https://www.example.com/offer/#linkedin it returns the value linkedin.
Step 2. Three lookup tables for source, medium and campaign
The fragment alone does not go to GA4, because fragments also serve as jump links on the page. The tables act as a filter and only translate the fragments you defined for campaigns. Each table returns exactly one value, so each dimension gets its own. Create three lookup tables, all with {{URL Fragment}} as input and without a default value. The overview below shows them side by side, and each column is a separate variable in Tag Manager.
| Input (URL fragment) | Campaign source | Campaign medium | Campaign name |
|---|---|---|---|
| linkedin.com | social | linkedin-posts | |
| facebook.com | social | facebook-posts | |
| newsletter | newsletter | newsletter-november |
Step 3. Set the values in the Google tag
GA4 has the fields campaign_source, campaign_medium and campaign_name. According to Google's reference they override the matching UTM parameters. Add them to the Google tag under “Configuration settings” as configuration parameters, with the three variables from step 2 as values. Always set source and medium together, because GA4 assigns traffic to the default channels with rules based on source and medium.
The fragments then match these UTM parameters.
Check the setup in Tag Assistant. Open a URL with a fragment and see whether the three variables have values and the Google tag sends the parameters. The acquisition reports in GA4 show the data with a delay.
The method has limits.
- A URL has only one fragment. Combinations such as #linkedin#winter do not work, so create a separate fragment such as #linkedin-winter.
- Tag Manager does not run inside PDF files. A fragment on a PDF URL cannot be measured this way.
- The browser does not send the fragment to the server. Server logs and many other tools therefore miss it, while they do see UTM parameters.
- If your website uses fragments for jump links or as part of a single-page app, pick campaign fragments that do not occur there.
- For ads and partner links, UTM parameters remain the method Google documents. The fragment method suits links you share yourself.
Tracking clicks on social profiles with readable names
With enhanced measurement, GA4 already records clicks on links to other domains as the click event with parameters such as link_url and link_domain. Long URLs are awkward when you want to report by profile, though. A lookup table gives every profile link a short name and also serves as the trigger condition. One tag then covers all profiles.
| Input (Click URL) | Output (social profile) |
|---|---|
| https://www.linkedin.com/company/example/ | |
| https://www.youtube.com/@example | youtube |
| https://www.instagram.com/example/ |
| Step | Where | What you set |
|---|---|---|
| 1 | Variables › Built-In Variables › Configure | Enable “Click URL” |
| 2 | Variables › New | Type “Lookup Table”, name “Social Profile”, input variable {{Click URL}}, rows as above, no default value |
| 3 | Triggers › New | Type “Click - Just Links”, “Some Link Clicks”, condition “Social Profile” matches RegEx linkedin|youtube|instagram |
| 4 | Tags › New | Type “Google Analytics: GA4 Event”, enter the measurement ID, event name social_profile_click |
| 5 | Event Parameters | Parameter profile with the value {{Social Profile}} |
| 6 | Triggering | Select the trigger from step 3 |
| 7 | GA4 › Admin › Custom definitions | Create a dimension for the parameter profile with the scope “Event” |
According to Google, you can use the new dimension in reports after 24 to 48 hours. Without a lookup table you would need a separate trigger and tag for every profile. Make sure the link URLs on the website match the values in the table exactly, including the trailing slash.
Fewer tags thanks to lookup tables
Many containers grow because every domain, country or campaign gets its own tag. Lookup tables combine such variants. If one container serves several domains, a lookup table with {{Page Hostname}} as input returns the matching tag ID for the Google tag. The same works for the Google Ads conversion ID and conversion label, each with its own table.
| Input (Page Hostname) | Table “GA4 tag ID” | Table “Ads conversion label” |
|---|---|---|
| www.example.de | G-AAAA111111 | AbC-dEfGh1 |
| www.example.at | G-BBBB222222 | IjK-lMnOp2 |
| www.example.ch | G-CCCC333333 | QrS-tUvWx3 |
With a few tables, one Google tag, one event tag per event and one conversion tag cover all domains. The container stays tidy and you make changes in one place. The guide hreflang with Google Tag Manager shows how the same principle returns the hreflang code per domain.
Patterns and URL parts with the RegEx table
A lookup table needs a separate row for every value. If the values 1, 4 and 7 should all return “Mastercard”, that means three rows. The RegEx table does it in one row and can also copy parts of the input into the output. To do so, enable “Enable Capture Groups and Replace Functionality” in the advanced settings and keep “Full Matches Only” switched on. Without full matches, Google warns of unexpected results.
| Input | Pattern | Output | Purpose |
|---|---|---|---|
| Data layer variable “cardType” | ^(1|4|7)$ | Mastercard | Several values, one output |
{{Page Path}} | ^/product/(\d+)/.* | $1 | Product ID from the URL |
{{Page Path}} | ^/(de|en|fr)/.* | $1 | Language directory as a parameter |
{{Page Path}} | .*5346.* | Deal | A string anywhere in the path |
Some tasks are beyond tables alone, for example when the canonical contains the full URL and you only need the path. In that case you write a variable of the type “Custom JavaScript” and use its output as the input of a table. According to Google, it has to be an anonymous function that returns a value.
This way variants such as /dog/food and /food/dog with the same canonical end up in the same row of the table.
Common mistakes
- Case or a trailing slash differs, and the lookup table finds no row.
- In the RegEx table a general pattern sits above a specific one and catches every match.
- With full matches enabled, a pattern without
.*at the end only matches exactly that value. - A default value fills fields that should stay empty, such as the campaign source on every page.
- Campaign fragments clash with jump links on the page.
- The built-in variable “Click URL” is not enabled, so the trigger never fires.
Frequently asked questions
What is a lookup table in Google Tag Manager?
A user-defined variable that returns a fixed value depending on the value of another variable. In Google Tag Manager the type is called “Lookup Table”.
What is the difference between a lookup table and a RegEx table?
The lookup table checks for an exact match. The RegEx table checks regular expressions from top to bottom, takes the first match and can copy parts of the input with capture groups.
Do lookup tables work with GA4?
Yes. You use the output as a parameter in the Google tag or in GA4 event tags, for example for content_group or campaign_source.
What does the table return if no row matches?
The default value if you set one, otherwise undefined. “Format Value” lets you replace undefined with a text.
How do I add many rows at once?
Export the container under “Admin” as a JSON file, add the rows in the file and import it into a new workspace. Choose “Merge” on import and rename conflicting items so that nothing is overwritten.
Do URL fragments replace UTM parameters?
For links you share yourself, often yes. For ads, partner links and tools outside GA4, UTM parameters remain the method Google documents.
Sources
Retrieved on November 3, 2026. If something is out of date or missing, let us know.
- Tag Manager Help, User-defined variable types for web: https://support.google.com/tagmanager/answer/7683362
- Tag Manager Help, Format values in user-defined web variables: https://support.google.com/tagmanager/answer/9121006
- Tag Manager Help, Set up the Google tag: https://support.google.com/tagmanager/answer/9442095
- Tag Manager Help, Set up Google Analytics events in Tag Manager: https://support.google.com/tagmanager/answer/13034206
- Tag Manager Help, Import and export containers: https://support.google.com/tagmanager/answer/6106997
- Tag Manager Help, Preview and debug containers: https://support.google.com/tagmanager/answer/6107056
- Google for Developers, GA4 configuration fields for gtag.js: https://developers.google.com/analytics/devguides/collection/ga4/reference/config
- Analytics Help, Content groups: https://support.google.com/analytics/answer/11523339
- Analytics Help, Enhanced event measurement: https://support.google.com/analytics/answer/9216061
- Analytics Help, Custom dimensions and metrics: https://support.google.com/analytics/answer/10075209
- Analytics Help, Default channel group: https://support.google.com/analytics/answer/9756891
- Analytics Help, Collect campaign data with custom URLs: https://support.google.com/analytics/answer/10917952