How to Add a Tracking Tag to a Plain HTML Website (Every Page, Step by Step)
Most analytics, heatmap and pop-up tools ask for the same thing: paste a short script into the <head> of every page. On Shopify, Wix or Squarespace there is a settings screen for that. On a plain HTML website, the kind you or a developer wrote by hand and upload by FTP or Git, there is no screen. You edit the files yourself. This guide shows exactly where the tag goes, how to get it onto every page without missing any, how shared includes and templates make that a one-time job, and how to confirm the tag is really loading.
Updated

What you need before you start
You don't need to be a developer, but you do need access to the files that make up your site and a way to publish changes. Run through this list first:
| What | Why | Typical examples |
|---|---|---|
| The site's source files | You will edit the HTML (or the shared header file) directly. | A folder of .html files on your computer, a Git repository, or files on your hosting account |
| A text editor | Word processors add hidden formatting that breaks code. | VS Code, Sublime Text, Notepad++, or your host's built-in file editor |
| A way to upload | Edits on your computer do nothing until they reach the server. | FTP/SFTP client, your host's file manager, or a Git push that deploys the site |
| The exact snippet from your tool | You paste it as given. Retyping it invites typos. | Copied from the tool's dashboard with its copy button |
| A backup | If something goes wrong, you can put the old file back in seconds. | A copy of the folder, or a Git commit before you start |
In marketingLABO, for example, the dashboard walks you through three steps: register your site with its name and URL, copy the tracking tag with the Copy tag button, and then check that data is arriving. The instruction on that screen is the one this whole guide is built around: paste the tag right before </head> on every page of your site.
<script src="https://...your tag..."></script>. Always paste the exact snippet from your own tool, not this example.Why the tag goes in the head
Every HTML page has two main parts: the head and the body. MDN Web Docs describes the head element as the part that "contains machine-readable information (metadata) about the document, like its title, scripts, and style sheets." The body holds what visitors actually see. A tracking tag isn't content; it is a script the browser should load as part of the page's setup, so it belongs with the other scripts in the head.
MDN also notes that "there can be only one <head> element in an HTML document." That matters for hand-edited sites: if you find two head sections in a file, something was pasted in twice at some point, and it is worth cleaning up before you add anything new.
Placing the tag high in the page also helps it run early. A tag that sits at the very bottom of a long page, or inside a section that only loads in some cases, may miss visitors who leave quickly. Those quick exits are often exactly the visits you want to understand, such as people who land on a pricing page and bounce.
Step 1: Find the closing </head> tag
Open one of your pages, start with index.html, in your text editor. Near the top you will see something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Your Shop – Handmade Ceramics</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
...Use your editor's search (Ctrl+F or Cmd+F) and look for </head>. On almost every page there will be exactly one. Everything between <head> and </head> is the head section; the line right above </head> is where your tag goes.
If you can't find a </head> at all, look for a <body> tag instead. Some older or minimal pages leave the closing head tag out, which MDN notes is allowed in some cases. In that situation, place your tag just before <body>. If there is neither, the page is probably being generated from other files, which we cover under "Shared headers and templates" below.
Step 2: Paste the tag right before </head>
Put your cursor at the start of the </head> line, press Enter to make an empty line above it, and paste the snippet there:
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Your Shop – Handmade Ceramics</title>
<link rel="stylesheet" href="/css/style.css">
<script src="https://...your tag..."></script>
</head>A few rules that prevent most problems:
- Paste it exactly as given. Don't change quotes, remove characters or reformat it. If the snippet spans several lines, keep all of them together.
- Don't add or remove
asyncordefer. MDN explains that anasyncscript "will be fetched in parallel to parsing and evaluated as soon as it is available," while adeferscript is executed "after the document has been parsed, but before firing DOMContentLoaded." Your vendor chose one (or neither) for a reason, so leave the attribute as it is. - Don't paste it inside another tag. It should sit on its own line, not inside a
<style>block, an HTML comment (<!-- ... -->) or another<script>. - Add it once per page. Two copies of the same tag can double-count page views. If you are replacing an old tag, remove the old one.
Save the file. If you edited it on your computer, upload it to the server, overwriting the old version. A quick way to confirm that the upload worked: open the live page in your browser, right-click and choose View Page Source, then search for part of your tag's address. If it isn't there, the server is still serving the old file, or your browser is showing a cached copy; reload with a hard refresh and look again.
Step 3: Repeat on every page (and don't miss any)
Here is where plain HTML sites differ from website builders. Each .html file is its own page with its own head. If your site has 12 pages, you need 12 edits. A tag on the home page only tells you what happens on the home page; a visitor who arrives from Google directly on a product page and leaves from the contact page won't be recorded at all if those pages lack the tag.
Pages that are easy to forget:
| Page type | Why it gets missed | Why it matters |
|---|---|---|
| Thank-you / confirmation pages | They aren't linked from the menu. | They are often the page that proves a sign-up or purchase happened. |
| Landing pages for ads or campaigns | They live in a separate folder or were made later. | Paid traffic lands here first. Without the tag you lose the start of every ad visit. |
| Old blog posts or news pages | Copied from an older template that predates your header changes. | Search traffic often lands on them. |
| Error pages (404.html) | Configured on the server rather than linked anywhere. | They show you broken links people actually hit. |
| Pages in subfolders | Easy to overlook if you only edit the root folder. | Everything under /products/ or /blog/ counts. |
To make sure you got them all, most code editors can search across a whole folder. In VS Code, for example, "Find in Files" lets you search for </head> across the project to list every page, then search for part of your tag's URL to list the pages that already have it. The two lists should match. If your site has more than a handful of pages, consider moving to a shared header first (next section) so you never have to do this again.
</head>. Replacing </head> with your tag followed by </head> works, but run it once. Running it twice adds the tag twice. Back up first.Shared headers and templates: paste once, cover every page
Many "plain" sites aren't quite as plain as they look. If your pages share a common header file, you only need to edit that one file. The marketingLABO setup screen says the same: "If your pages share a common header, pasting it once there adds it to every page." Here are the common ways sites share a header and where to look for each.
PHP includes
If your page files end in .php, there is a good chance the top of each page is pulled in from a shared file. The PHP manual describes it this way: "The include expression includes and evaluates the specified file." Open a page and look near the top for a line like this:
<?php include 'header.php'; ?>
<!-- or -->
<?php require_once __DIR__ . '/includes/head.php'; ?>Open the file it points to. If that file contains the </head> tag, add your snippet right above it there, and every page that includes the file gets the tag. If the shared file only contains the visible header (logo and menu) and the head section is still written out in each page, you will need to edit the pages themselves or move the head section into the shared file.
One detail from the PHP manual worth knowing: include "will emit an E_WARNING if it cannot find a file," while require stops with a fatal error. Either way, keep the file name and path unchanged when you edit; you are only adding one line inside the file.
Server Side Includes (.shtml)
Some older sites on Apache use Server Side Includes. The Apache documentation shows the syntax as an HTML-style comment:
<!--#include virtual="/includes/head.html" -->If you see lines like that, open the referenced file and add your tag before </head> in it. Apache's guide explains that SSI is switched on with Options +Includes and is commonly applied to files ending in .shtml, or to files with their execute bit set via the XBitHack directive. You don't have to change any of that to add a tag; just know that if the include comment shows up as plain text in View Page Source, SSI isn't being processed on that server, and editing the include file won't have any effect.
Static site generators and templates
If your site is built by a tool that turns templates into HTML files before uploading, the .html files on your server are output, not source. Editing them works until the next build overwrites them. Instead, look in the project for a layout, base or partial template that contains the <head> section, often in a folder named something like layouts, templates, partials or includes. Add your tag there, rebuild and deploy.
The test is simple: after rebuilding, open two or three different generated pages and check that the tag appears in each. If it appears in only one, that page has its own head and needs its own edit.
How to tell which kind of site you have
| What you see | What it means | Where to paste |
|---|---|---|
| Each .html file has a full <head>…</head> | Fully hand-coded pages | Every file, before </head> |
| <?php include …?> or require near the top | PHP includes | The included file that contains </head> |
| <!--#include virtual="…" --> | Server Side Includes | The included file that contains </head> |
| A folder of templates plus a build command | Static site generator | The base layout template, then rebuild |
| You edit pages in a browser-based editor | Not a plain HTML site | Use that platform's custom code setting |
If your site turns out to run on a platform, use its own setting instead. We have step-by-step guides for Shopify, WooCommerce, Wix and Squarespace.
Step 4: Check that the tag is loading
Pasting the tag is half the job. The other half is confirming that browsers actually load it on the live site. There are two good checks: your tool's own status check, and your browser's developer tools.
Check in your tool's dashboard
Most tools tell you when they start receiving data. In marketingLABO, the third onboarding step is Check tracking: after adding the tag, open any page on your site, then click the Check tracking button. When data is arriving, the dashboard confirms that setup is complete and tracking is working. If nothing has come in yet, it asks you to make sure the tag is right before </head> on every page and that your changes are saved (published), then reload your site and try again.
Remember that a successful check proves the tag works on the page you opened. It doesn't prove every page has it. That is what the folder search in Step 3 is for.
Check in Chrome DevTools
The Network panel shows every file the browser downloads for a page, including your tag. Chrome's documentation explains how to open it and read it; in short:
- Open your live page in Chrome (not the local file on your computer).
- Open DevTools. Chrome's guide lists Control+Shift+J on Windows and Linux or Command+Option+J on Mac, then click the Network tab.
- Tick Disable cache. Chrome's reference says that with it on, "DevTools disables the browser cache," which lets you see the page the way a first-time visitor does.
- Reload the page. The list fills with requests.
- Type part of your tag's address (for example, its domain) into the Filter box to narrow the list. Chrome also supports property filters such as
domain:. - Check the Status column. Chrome describes it as the HTTP response code for each resource. A 200 means the script downloaded. Click the row to see Headers, Preview, Response, Initiator and Timing tabs.
If you want to follow a visit across several pages, tick Preserve log. Chrome notes that "DevTools saves all requests until you disable Preserve log," so requests from earlier pages stay in the list as you click around.
Repeat the check on a few different page types: the home page, a product or service page, a blog post and the thank-you page. If the tag shows up on all of them, you are done.
Troubleshooting: the tag isn't showing up
| Symptom | Likely cause | Fix |
|---|---|---|
| Tag isn't in View Page Source | The edited file wasn't uploaded, went to the wrong folder, or a build overwrote it | Re-upload to the right folder; for generated sites, edit the template and rebuild |
| Tag is in the source but not in the Network panel | It is inside an HTML comment, inside another tag, or the quotes were changed | Compare it character by character with the original snippet; paste again from the dashboard |
| Network shows the request with status 404 | The script address was altered or cut off | Copy the snippet again with the copy button rather than selecting by hand |
| Network shows the request as blocked | An ad or tracker blocker in your browser | Test in a private window with extensions off, or another browser |
| Tag works on some pages but not others | Those pages have their own head, or come from a different template | Use folder search to find pages without the tag |
| Page views look doubled | The tag was pasted twice (page plus include, or replace run twice) | Search each page for the tag and keep one copy |
| Old version still shows after upload | Browser or server cache | Hard refresh, or check with Disable cache ticked in DevTools |
Keeping the tag on new pages
The most common way tracking quietly breaks on hand-coded sites isn't a bad edit. It is a new page created months later from an old file that never had the tag. A few habits prevent that:
- Keep a starter file. Make one page with the correct head, including the tag, and copy it whenever you add a page.
- Move to a shared header if your host supports PHP or SSI. One file to edit beats dozens.
- Write it down. Note in a README or your site notes which tags are installed, where they live and when they were added. Whoever edits the site next will thank you.
- Re-check after redesigns. A new theme or template often replaces the head section. Run the DevTools check on a few pages after any big change.
What happens after the tag is in
Once the tag is on every page, data starts building up from the next visit onward; nothing is collected retroactively. In marketingLABO, the same tag feeds per-page heatmaps (time on page, scroll depth and clicks), reports by traffic source, page and conversion, and a timeline of each visitor's actions, and pop-up banners are shown through that same tag, with no further changes to your HTML.
If you are new to these reports, our guides on reading website heatmaps and micro-conversions are good next reads, and UTM parameters help you tell your campaigns apart in traffic-source reports.
FAQ
Can I put the tag at the end of the body instead?
Only if your tool says so. Follow the vendor's placement instruction. For marketingLABO, the instruction is right before </head> on every page.
Do I need to add the tag to pages in an iframe?
A page shown inside an iframe is a separate document with its own head. If that embedded page is yours and you want to track it, it needs the tag too. If it belongs to another service, you usually can't add it.
Will the tag slow down my site?
Any extra script adds a download. Keep only the tags you actually use, remove tags from tools you've stopped using, and don't install the same tag twice. You can see how long the file takes in the Timing tab in DevTools.
Does the tag work on a local file I open from my computer?
Test on the live site. Opening a file from your disk (a file:// address) isn't the same as a visit to your domain, and your tool is set up for your registered site URL.
My site is a single-page app. Does this guide apply?
Not really. Apps built with frameworks that change pages without a full reload need a different setup, and this guide doesn't cover them. It is written for sites where each page is a separate HTML document.
marketingLABO's Free plan includes one site with analytics, heatmaps and visitor history, plus one form and one pop-up banner, with no credit card required. Compare plans on the pricing section, or sign up free to get your tag.
Sources
- MDN Web Docs: <head>: The Document Metadata (Header) element
- MDN Web Docs: <script>: The Script element (async, defer, src)
- Chrome for Developers: Inspect network activity
- Chrome for Developers: Network features reference (Disable cache, Preserve log, filters)
- PHP Manual: include
- Apache HTTP Server 2.4: Introduction to Server Side Includes
Start free — no credit card needed
Sign up freeMore articles

Form UX Best Practices: Validation, Progress Bars and Autofill
Form UX best practices from web.dev and W3C: when to validate, how to word errors, progress for long forms, and autocomplete values that make autofill work.
Read the article →
How to Read a Single Visitor's Journey Through Your Site
Use a per-visitor timeline to spot loops, hesitation and return visits, tell anonymous from known contacts, and avoid reading too much into one journey.
Read the article →
How to Target Returning Visitors with Different Messages Than First-Timers
Show first-time and returning visitors different messages using visit frequency and days since the last visit, with recipes and the limits of tracking.
Read the article →
UTM Parameters Explained (and How to Match Landing Messages to Your Ads)
What each UTM parameter means, a naming convention that keeps reports clean, common tagging mistakes, and how to show visitors a message that matches the ad.
Read the article →
Micro-Conversions: The Small Signals That Predict a Sale
What micro-conversions are, four practical ones to track (pages viewed, key URLs, time on site, return visits), how to set thresholds and how to act on them.
Read the article →
Are Email Open Rates Still Reliable After Apple Mail Privacy Protection?
How Apple Mail Privacy Protection inflates email open rates, what opens can still tell you, and why clicks and site returns make better signals.
Read the article →