How to Track File Downloads in GTM

Track PDF, CSV, image, and zip file downloads in Google Tag Manager. Covers link click triggers, GA4 events, and handling downloads that don't use standard links.

GTMGoogle Tag Managerfile downloadstrackingGA4click tracking

Someone downloads your pricing PDF, your product catalog, or your whitepaper. Without tracking, you have no idea it happened — no conversion count, no attribution, no way to retarget that person who just showed high purchase intent by grabbing your spec sheet.

GA4 has a built-in “file_download” enhanced measurement event, but it’s limited. It only fires on standard <a href> links to files, and it misses plenty of real-world download patterns. This guide covers how to track all types of file downloads reliably using GTM.

What GA4’s Enhanced Measurement Already Tracks

Before building custom tracking, check if enhanced measurement is handling it:

  1. GA4 → Admin → Data Streams → [your stream] → Enhanced Measurement
  2. Look for File downloads — it should be toggled ON by default

Enhanced measurement automatically tracks clicks on links that point to files with these extensions:

pdf, xls, xlsx, doc, docx, txt, rtf, csv, exe, key, pps, ppt, pptx, 
7z, pkg, rar, gz, zip, avi, mov, mp4, mpeg, wmv, midi, mp3, wav, wma

How it works: When a user clicks an <a> tag where the href ends in one of those extensions, GA4 fires a file_download event with these parameters:

  • file_name: The filename
  • file_extension: The extension
  • link_url: The full URL
  • link_text: The anchor text

When enhanced measurement fails:

ScenarioTracked?
Standard <a href="/files/report.pdf">Yes
JavaScript-triggered download (no <a> tag)No
Download behind a form gate (submit form, then download)No
Dynamic download links (blob URLs, data URIs)No
Cloud storage links (Google Drive, Dropbox)Maybe (depends on URL format)
CDN links with query strings (report.pdf?token=abc)Yes (enhanced measurement strips query params)
Button that programmatically triggers downloadNo

If enhanced measurement covers your use case, you’re done. If not, read on.

This handles the 80% case — users click a link that points to a downloadable file.

Step 1: Enable Click Variables

  1. GTM → Variables → Configure Built-In Variables
  2. Enable: Click URL, Click Text, Click Element, Click Classes

Step 2: Create the Trigger

  1. GTM → Triggers → New
  2. Trigger type: Click - Just Links
  3. This trigger fires on: Some Link Clicks
  4. Condition: Click URL → matches RegEx → \.(pdf|csv|xlsx|xls|docx|doc|zip|pptx|ppt)(\?.*)?$

This regex matches any link URL ending in common file extensions, with or without query parameters.

Make it case-insensitive: Select “matches RegEx (ignore case)” to catch .PDF and .Pdf variants.

Step 3: Create the GA4 Event Tag

  1. GTM → Tags → New
  2. Tag type: Google Analytics: GA4 Event
  3. Configuration tag: Your GA4 configuration
  4. Event name: file_download
  5. Event parameters:
ParameterValue
file_name{{Click URL}} — or create a custom variable to extract just the filename
file_extensionCreate a Custom JavaScript variable (see below)
link_text{{Click Text}}
link_url{{Click URL}}
  1. Trigger: The link click trigger from Step 2

Extract File Extension (Custom Variable)

Create a Custom JavaScript variable called “File Extension from Click URL”:

function() {
  var url = {{Click URL}};
  if (!url) return '';
  var match = url.match(/\.([a-zA-Z0-9]+)(\?.*)?$/);
  return match ? match[1].toLowerCase() : '';
}

Extract Filename (Custom Variable)

Create a Custom JavaScript variable called “Filename from Click URL”:

function() {
  var url = {{Click URL}};
  if (!url) return '';
  // Remove query string and hash
  var clean = url.split('?')[0].split('#')[0];
  // Get last path segment
  var parts = clean.split('/');
  return parts[parts.length - 1] || '';
}

Method 2: JavaScript-Triggered Downloads

Some sites generate downloads via JavaScript — no <a href> link exists. Common patterns:

  • “Export to CSV” buttons in web apps
  • “Generate Report” buttons that create PDFs on the fly
  • Download buttons that fetch from an API and trigger a browser download

Option A: Data Layer Push

If you control the download code, push a data layer event when the download triggers:

function downloadReport(reportId) {
  // Your existing download logic
  fetch(`/api/reports/${reportId}/download`)
    .then(response => response.blob())
    .then(blob => {
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `report-${reportId}.pdf`;
      a.click();
      
      // Track the download
      window.dataLayer = window.dataLayer || [];
      window.dataLayer.push({
        event: 'file_download',
        file_name: `report-${reportId}.pdf`,
        file_extension: 'pdf',
        download_method: 'generated'
      });
    });
}

In GTM, create a Custom Event trigger for file_download and a tag that sends the parameters to GA4.

Option B: Click Listener on Download Buttons

If the download buttons have identifiable classes or IDs:

  1. Create a trigger: Click - All Elements
  2. Condition: Click Classes → contains → download-btn (or whatever class identifies download buttons)
  3. Fire your GA4 event tag

Option C: MutationObserver (Last Resort)

For sites where downloads happen through complex UI frameworks and you can’t modify the code:

<script>
  // Watch for dynamically created download links
  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      mutation.addedNodes.forEach(function(node) {
        if (node.tagName === 'A' && node.download) {
          window.dataLayer.push({
            event: 'file_download',
            file_name: node.download || node.href,
            download_method: 'dynamic_link'
          });
        }
      });
    });
  });
  observer.observe(document.body, { childList: true, subtree: true });
</script>

Use this sparingly — it adds overhead to every DOM change.

Method 3: Cloud Storage Downloads

Downloads hosted on Google Drive, Dropbox, S3, or other cloud storage have URLs that don’t end in file extensions:

https://drive.google.com/file/d/1abc.../view
https://www.dropbox.com/s/abc123/report.pdf?dl=1
https://s3.amazonaws.com/bucket/reports/q4-2026.pdf

Modify the trigger regex to include cloud storage domains:

(\.(pdf|csv|xlsx|zip)(\?.*)?$)|(drive\.google\.com/file)|(dropbox\.com/s/)|(s3\.amazonaws\.com)

Or create a separate trigger specifically for cloud links:

Click URL → matches RegEx → (drive\.google\.com|dropbox\.com|s3\.amazonaws\.com)

Then extract the link text or filename from surrounding context:

function() {
  var url = {{Click URL}};
  // Try to extract filename from URL
  var match = url.match(/\/([^\/\?]+\.[a-zA-Z]{2,4})(\?.*)?$/);
  if (match) return match[1];
  // Fall back to click text
  return {{Click Text}} || 'unknown-file';
}

Sending Download Data to GA4

Standard Event Parameters

Send these with every file_download event:

ParameterValuePurpose
file_nameFilenameIdentify which file
file_extensionExtension (pdf, csv, etc.)Filter by file type
link_urlFull URLDebug and verify
link_textAnchor textContext

Custom Parameters for Business Context

Add parameters that help you understand download intent:

ParameterExample ValueWhy
file_category”pricing”, “case-study”, “spec-sheet”Segment by content type
page_section”resources”, “product-page”, “blog”Where on the site
gated”true” / “false”Was it behind a form?

Mark Downloads as Conversions

If file downloads represent meaningful business actions (pricing PDF, demo request):

  1. GA4 → Admin → Events
  2. Find file_download
  3. Toggle Mark as conversion

Or create a more specific event (like pricing_pdf_download) and mark only that as a conversion.

Tracking Gated Downloads

Gated downloads (fill a form to get the PDF) are a two-step process:

  1. Track the form submission — see our GTM form tracking guide
  2. Track the actual download — using the methods above
  3. Connect them — pass the lead’s email/ID as a parameter in both events
// After form submission, when download link is revealed
window.dataLayer.push({
  event: 'gated_download',
  file_name: 'industry-report-2026.pdf',
  file_extension: 'pdf',
  lead_source: 'resource-center',
  form_id: 'whitepaper-gate'
});

Testing

GTM Preview Mode

  1. Enable Preview Mode
  2. Click a download link on your site
  3. Check the Tags panel — your download tracking tag should show as “Fired”
  4. Check the Variables tab — verify Click URL, Click Text, and your custom variables show correct values

GA4 DebugView

  1. Enable GA4 Debug Mode (via GTM Preview or browser extension)
  2. GA4 → Admin → DebugView
  3. Click a download link
  4. Watch for the file_download event
  5. Click on it to verify parameters

GA4 Realtime Report

After clicking a download link, check GA4 → Realtime → Event count for file_download.

Common Issues

ProblemCauseFix
Downloads not trackingEnhanced measurement disabled, no GTM triggerEnable enhanced measurement OR create click trigger
Wrong file extension capturedQuery string confusing the regexUse (\?.*)?$ in your regex to strip query params
(not set) as filename{{Click URL}} is empty for JS-triggered downloadsUse data layer push instead
Duplicate download eventsBoth enhanced measurement AND GTM tracking the same clickDisable enhanced measurement file downloads if using custom GTM tracking
Cloud storage downloads not trackingURL doesn’t match file extension regexAdd cloud storage domain patterns to trigger

Checklist

  • Enhanced measurement file downloads reviewed (on or off, but not duplicating custom tracking)
  • Link click trigger created with file extension regex
  • GA4 event tag configured with file_name, file_extension, link_url
  • JavaScript-triggered downloads tracked via data layer push
  • Cloud storage links handled (if applicable)
  • Custom variables for filename and extension extraction working
  • Download events visible in GA4 DebugView
  • Key downloads marked as conversions (if business-relevant)

File downloads are one of the clearest intent signals on your site. Someone downloading your pricing PDF is further along the funnel than someone reading your blog. Track it, attribute it, and retarget based on it.

Want to know if your download tracking is working correctly? Run a free scan — we check your GTM configuration, event tracking, and GA4 integration.