Skip to content

Clicktag download tracking

Track file downloads on your website: PDF, ZIP and more, free

Clicktag tracks file downloads on your website for free, with no credit card and no cookies. Install one 4 KB script, fire a custom event when someone clicks a PDF, ZIP or installer link, and set up to 50 goals per site to see which sources drive downloads.

A pageview script does not see file downloads, because clicking a link to a .pdf, .zip or .dmg file does not load an HTML page where the script can run. To track downloads in Clicktag, you call window.tt_event when a visitor clicks a download link. A short delegated listener handles every file link on the page at once, and you can turn any download event into a goal to see which traffic sources and entry pages bring people who download.

How download tracking works in Clicktag

Clicktag's latest.js script is about 4 KB compressed and tracks pageviews automatically, including single-page app navigation through pushState and popstate. It does not record clicks, outbound links, file downloads or form submissions on its own. Clicktag also does not serve /auto.js or /auto-events.js, so you control which actions send data by calling window.tt_event(name, metadata, callback).

When a visitor clicks a link to a file, your click handler calls tt_event before the browser follows the link. You can check the setup on your own site or browse the live demo (its numbers are synthetic sample data) to see how custom events appear in the reports.

Track PDF, ZIP, DMG and EXE clicks with one listener

Instead of attaching an onclick attribute to every link on your site, add one delegated listener on document. It checks whether a click happened inside an <a> tag whose path ends with .pdf, .zip, .dmg or .exe, and fires a custom event with the file name baked into the event name.

First, put the queue snippet and the main script tag in your HTML so calls made before latest.js finishes loading are buffered and replayed in order:

<script>
  window.tt_event =
    window.tt_event ||
    function () {
      window.tt_event.q.push(Array.from(arguments));
    };
  window.tt_event.q = window.tt_event.q || [];
</script>
<script
  async
  src="https://clicktag.io/latest.js"
  data-hostname="example.com"
></script>

Keep standard function () syntax in the queue snippet so arguments is captured properly. When you copy the script tag from Site settings > Installation, it also carries your data-verify attribute.

Next, add the delegated click listener:

document.addEventListener("click", function (event) {
  var link = event.target.closest("a[href]");
  if (!link) return;

  var url;
  try {
    url = new URL(link.href, window.location.origin);
  } catch (e) {
    return;
  }

  var match = url.pathname.match(/\.(pdf|zip|dmg|exe)$/i);
  if (!match) return;

  var file = url.pathname.split("/").pop().toLowerCase();
  if (typeof window.tt_event === "function") {
    window.tt_event("download_" + file, {
      ext: match[1].toLowerCase(),
      path: url.pathname
    });
  }
});

Why the file name belongs in the event name

Clicktag stores event metadata (up to 4,096 characters of serialized JSON), but metadata cannot be grouped or filtered in dashboard reports or the Stats API. Clicktag aggregates event counts by the event name itself.

Put the file name or asset type directly in the event name so each file gets its own row in your reports and can be selected as a goal.

Incoming event names are cut at 256 characters before normalization. The collector converts any sequence of non-alphanumeric characters into a single underscore and strips leading and trailing underscores. So when your listener sends download_q3-report.pdf, Clicktag normalizes and stores it as download_q3_report_pdf.

File type Example link href Raw string passed to tt_event Normalized event name in reports
PDF document /files/pricing-2026.pdf download_pricing-2026.pdf download_pricing_2026_pdf
ZIP archive /releases/sdk-v2.4.zip download_sdk-v2.4.zip download_sdk_v2_4_zip
macOS disk image /dl/Acme-App.dmg download_acme-app.dmg download_acme_app_dmg
Windows installer /dl/setup-x64.exe download_setup-x64.exe download_setup_x64_exe
Any PDF (grouped) /docs/whitepaper.pdf download_pdf download_pdf

If you have hundreds of PDFs and only care about the total across all of them, pass "download_pdf" as the event name instead of appending the file name. More details on naming rules and normalization are in the custom event docs.

Turn a download into a goal to see which sources convert

Counting total clicks tells you how popular a file is, but turning that event into a goal shows where the people who download it came from and which page they landed on first. Each site in Clicktag can have up to 50 goals and funnels combined, and because goals are computed at query time from data you already collect, creating a new goal includes your past data right away.

  1. Open your site in Clicktag, go to the Goals tab and click New goal.
  2. Choose Event as the match type and enter the normalized event name, such as download_pricing_2026_pdf.
  3. Optionally add up to 6 step filters (by page, source, country, device, browser, OS, or UTM source, medium and campaign) and save.

In the Goals tab you get three numbers for every download goal: Conversions (every matching download event), Converted visitors (distinct daily visitors who triggered the download at least once that day), and Conversion rate (converted visitors divided by total visitors, never above 100%).

Click a goal in the dashboard to break it down by referrer, entry page, country, device, browser, OS or UTM parameter. Every converted visitor is credited to the referrer and entry page of their first pageview that UTC day.

That lets you compare whether visitors arriving on your articles from google.com or chatgpt.com actually download your PDF guide, or build a 2 to 6 step funnel in goal tracking from a page view to the final .dmg click. See the goals and funnels docs for the full API and filter rules.

What about server-side downloads?

Clicktag supports sending events from a backend with a JSON POST to https://clicktag.io/events (with "type": "event", the site hostname, the event name and the visitor's real ua string). If you serve files through a backend download route, you can log downloads there.

There is one trade-off to know before picking server-side events over browser click tracking: events sent from your server get a visitor identity built from your server's IP address, not the visitor's. Because of that, server-sent events cannot follow a visitor's pageviews in a funnel or inherit their referrer and entry page in goal breakdowns. If you want to see which traffic source or blog post drove the download, fire window.tt_event in the browser when the link is clicked.

FAQ

Does Clicktag track PDF and ZIP downloads automatically?

No. latest.js records pageviews on its own but does not track link clicks, file downloads or form submissions. You add a window.tt_event call on the links you want to measure, or use one delegated click listener for file extensions like .pdf and .zip.

Can I pass the file name in event metadata and break reports down by it?

No. Clicktag stores up to 4,096 characters of JSON metadata per event, but metadata cannot be grouped or filtered in the dashboard or API. Put the file name or file type in the event name itself (up to 256 characters) so each file shows up as its own row.

Will a download goal include downloads that happened before I created the goal?

Yes, as long as your listener was already sending those download events. Goals in Clicktag are computed at query time over the events and pageviews you have already collected, so a new or edited goal applies to past data immediately. A site can have up to 50 goals and funnels combined.

What if a visitor opens a PDF link directly from an email or another site?

When someone opens a .pdf URL directly in their browser without visiting an HTML page on your site first, latest.js never runs because a PDF file cannot execute your site's JavaScript tag. To count direct requests to raw file URLs that bypass your web pages, send a POST /events request from the backend server that delivers the file.

Does download tracking use cookies or store IP addresses?

No. Clicktag sets no cookies, uses no local storage, and never stores IP addresses. Visitors are counted with a daily salted SHA-256 hash whose salt is deleted shortly after each UTC day ends, so downloads and pageviews are tied together within a single UTC day without tracking individuals across days.

Updated October 30, 2026