Track QR Codes in Google Analytics: Setup Guide

Track QR Codes in Google Analytics (GA4): Setup Guide for 2026

This is the exact setup for tracking QR codes in Google Analytics 4. It assumes you already know why you'd want this (if not, start with our overview of QR code analytics) and skips straight to the configuration.

Total setup time once you have the basics in place: about 15 minutes for the first QR campaign, 2 minutes for each one after that.

Prerequisites

Before you start, make sure:

  • You have a Google Analytics 4 (GA4) property set up. If you only have the older Universal Analytics, set up GA4 first - Universal Analytics stopped collecting data in July 2023.
  • The GA4 tag (gtag.js) is installed on every page the QR code can land on. If you're not sure, view the page source on the destination URL and search for your GA4 measurement ID (format G-XXXXXXXXXX).
  • You can access the destination URL - if it's a third-party site you don't control (a Linktree, a Calendly, an event signup page), you can still count scans using a dynamic QR's own dashboard, but GA4 attribution won't work.

Step 1: Build the UTM-Tagged Destination URL

The UTM parameters in your destination URL are what make a QR scan distinguishable from any other visit in GA4. Three are essential, two are optional:

  • utm_source - the specific physical placement. Examples: table-tent, billboard-broadway, flyer-summer, business-card. Be specific - this is what lets you compare placements.
  • utm_medium - always qr for QR code campaigns. Consistency here is more important than cleverness. It's how you'll filter all QR traffic across every campaign.
  • utm_campaign - the marketing campaign name. Use lowercase + hyphens: summer-menu-2026, product-launch-q3, winter-promo.
  • utm_term (optional) - originally for paid-search keywords. For QR campaigns, use it to track A/B variants if you're running them.
  • utm_content (optional) - useful for distinguishing two QRs in the same campaign with the same source/medium (e.g., front of business card vs. back).

You can build these by hand or use the free UTM builder on whew.cc. The builder enforces lowercase + hyphen conventions and prevents the most common typo problems.

Example finished URL for a restaurant table tent campaign:

https://yourrestaurant.com/menu?utm_source=table-tent&utm_medium=qr&utm_campaign=summer-menu-2026

Step 2: Encode the URL as a QR Code

You have two choices, and the right one depends on whether the destination URL might change:

Static QR (URL is locked in)

Use any free QR generator - including whew.cc's free static QR generator. Paste the UTM-tagged URL, download the QR as SVG (for print) or PNG (for screen). Print, post, done.

Pros: free, no signup, never expires. Cons: if the destination URL changes, you have to reprint.

Dynamic QR (URL might change, or you want scan-level data)

Use a dynamic QR generator (whew.cc's free signed-up tier covers this). The dynamic QR encodes a short whew.cc link; you set the redirect to the UTM-tagged URL. The QR can be re-pointed later if the destination URL changes.

Pros: editable destination, free scan-level analytics from the QR dashboard, layered on top of GA4. Cons: free tier expires (90 days for signed-up, 2 weeks for anonymous); paid plan removes this.

Step 3: Verify the GA4 Tag Receives the Scan

Before printing 500 of these, scan your QR with your own phone and verify GA4 sees it:

  1. Open GA4 - Reports - Realtime.
  2. Scan the QR with your phone. Open the destination page that loads.
  3. Within 30 seconds, you should see "1 user" appear in the Realtime traffic source card with your utm_source / utm_medium values (or "table-tent / qr" in our example).

If nothing shows up: (a) check the destination page source for the GA4 tag; (b) check that your UTM parameters survived any redirects (some shorteners strip query strings); (c) check that your browser isn't blocking GA4 via cookie consent or ad blocker - test in incognito mode.

Step 4: Mark a Conversion Action

A pageview is good, but a conversion is what justifies the print spend. In GA4:

  1. Open Admin (gear icon, bottom left).
  2. Under Property column, click Events.
  3. Find the event that represents your goal (form_submit, sign_up, purchase, or any custom event your site fires).
  4. Toggle Mark as conversion to on.

Standard events GA4 fires automatically that you can mark as conversions: file_download, form_submit, scroll (90% threshold), video_complete. Custom events your site fires can also be marked.

After 24-48 hours, the Conversions report shows conversion rate per traffic source - including your QR campaigns.

Step 5: Read the Right Reports

Three GA4 reports answer different questions about QR campaigns:

Traffic Acquisition (the day-to-day overview)

Reports - Acquisition - Traffic acquisition. Default dimension "Session source / medium" splits traffic by source. Filter or search for "qr" in the medium column. You'll see sessions, engaged sessions, average engagement time, and conversion rate per QR source. This is the report you'll check most often.

Campaigns (the campaign-level rollup)

Reports - Acquisition - User acquisition - First user campaign. Aggregates all QR sources under their campaign name (the utm_campaign value). Useful for asking "how is the summer-menu campaign performing across all its placements?"

Realtime (scan verification + live monitoring)

Reports - Realtime. Use this when you want to confirm a scan registered immediately (your own test scans, or watching a launch event live).

Step 6: Pair with Dynamic QR Analytics for Full Coverage

GA4 sees the destination-side session. The dynamic QR generator (if you used one) sees the redirect-side scan. Together they answer the full lifecycle question:

  • Dynamic QR dashboard shows: total scans, scans by day/hour, scans by device type, scans by country (aggregate, privacy-preserving). No GA4 needed.
  • GA4 shows: of those scans, how many resulted in engaged sessions on the destination, how many took the conversion action, and what other pages they visited.

Discrepancy is normal: scan count from the dynamic QR will typically be 10-30% higher than session count in GA4, because some scanners abandon before the page loads, some block cookies, and some are bots. The gap itself is interesting data - a large gap means scanners aren't reaching your page (or aren't accepting cookies).

Common Mistakes Specific to GA4 + QR Codes

  • Case sensitivity. GA4 treats QR, qr, and Qr as different mediums. Pick qr and never deviate.
  • Spaces and special characters in UTM values. URL-encode them, or use only lowercase letters, numbers, and hyphens. utm_source=Table Tent becomes utm_source=Table%20Tent, which then shows up as Table Tent in reports - usable but ugly. Stick to table-tent.
  • Forgetting that GA4 reports are sampled at high volumes. Below a few thousand sessions per day per source, you'll see exact numbers. Above that, GA4 may show estimates with confidence intervals. For most QR campaigns this isn't an issue.
  • Not linking Search Console. Admin - Property Settings - Search Console links. Free to set up, unlocks the Search Console report inside GA4 which shows organic search performance alongside the QR data.

Quick Reference: GA4 + QR Tracking Cheat Sheet

  • UTM medium for QR codes: always qr
  • UTM source: the specific physical placement (be specific)
  • UTM campaign: lowercase, hyphens, include year if recurring
  • Verification: Realtime report, within 30 seconds of a test scan
  • Day-to-day report: Traffic acquisition, filter by medium = qr
  • Conversion setup: Admin - Events - Mark as conversion on the goal action
  • Patience: Standard reports take 24-48h to populate

Build the QR (and UTM URL) for free

whew.cc's free tools cover both ends of this setup: a UTM builder that enforces the conventions above, and a free QR generator (static or dynamic) that encodes the resulting URL. No signup required for static.

UTM builder QR generator

FAQ

Five steps: (1) Install GA4 on the destination site. (2) For each QR placement, build a UTM-tagged URL with utm_source (the placement), utm_medium (always 'qr'), and utm_campaign (the campaign name). (3) Encode that URL as a QR code (static or dynamic). (4) In GA4 Admin, mark your conversion action. (5) Read Reports - Acquisition - Traffic acquisition, filtering by source/medium to see per-QR performance.

Reports - Acquisition - Traffic acquisition. Use the 'Session source / medium' dimension and filter by the values you set in your UTM tags (for example, 'table-tent / qr'). Each unique QR placement shows as its own row. For real-time scan verification, use Reports - Realtime - Traffic by source.

Five common causes: (1) GA4 tag missing on the destination page. (2) UTM parameters not present in the QR's destination URL. (3) UTM parameters stripped by a redirect. (4) Looking at the wrong report - default reports group small sources as 'direct' until they have enough volume. (5) Browser blocking GA4 via cookie consent or ad blocker. Use GA4's DebugView to verify the page hit is being recorded.

Realtime reports show events within 30 seconds. Standard reports (Traffic acquisition, Engagement) take 24-48 hours to populate, and conversion reports update overnight. Use the Realtime tab during testing, then check Traffic acquisition the next day for the actual attribution data.

No - GA4's standard gtag.js install captures pageviews with UTM parameters automatically. Google Tag Manager is useful if you want to fire custom events on specific actions (form submits, button clicks, scroll depth) without changing site code, but it's not required for basic QR code tracking.

Yes, by giving each physical placement its own unique utm_source value. Example: a restaurant with 10 table tents could use utm_source=table-tent-1, table-tent-2, etc., or group them as utm_source=table-tent and rely on the dynamic-QR dashboard for table-level granularity.
Related reading