UTM Check

Catches campaign links that split analytics: inconsistent casing, swapped source and medium, misspelled keys and tags that land as Unassigned.

StopsUTM links split analytics

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/utm-check.json

The files land in your project. They're yours to edit.

Usage

utm-check-usage.tsx
import { UtmCheck } from "@/components/ui/utm-check"

<UtmCheck
  defaultValue="https://acme.in/diwali?utm_source=Facebook&utm_medium=social ads&utm_campaign=Diwali-Sale"
  knownValues={knownValues}
  placedOn={placement === "blog" ? ["acme.in"] : []}
/>

What it catches

  • Case and spacing that split reports (Facebook vs facebook)
  • Values your reports already spell differently
  • Source and medium swapped
  • Mediums that GA4 default channel rules send to organic or Unassigned
  • Misspelled UTM keys, a second ?, or tags after #
  • UTM tags on links to your own site

Props

UtmCheck props
PropTypeDefault
value

Controlled URL.

string—
defaultValue

Initial URL when uncontrolled.

string""
onValueChange

Called with the URL on every edit and fix.

(value: string) => void—
label

Visible label of the URL field.

string"Campaign URL"
builder

Show the source, medium and campaign fields under the URL.

booleantrue
channelLabel

Label before the predicted GA4 channel.

string"GA4 channel"
internalText

Warning for UTM tags on links to your own site.

string"Internal link, no tags needed"
normaliseLabel

Label of the fix-all button.

string"Normalise all"
undoLabel

Label of the Undo button.

string"Undo"
cleanText

Shown when no issues are found.

string"Tags are consistent."

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • URL and builder fields have <label>s; issues linked via aria-describedby
  • Issues and the predicted channel in a polite live region
  • Fix and fix-all are labelled buttons with Undo

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Channel prediction follows GA4's default channel group; custom channel groups differ
  • Source lists are short built-ins; pass your own for wider coverage

Rules

Rules last verified:

Confirmed the page defines GA4 default channels (e.g. Paid Social) and that Unassigned is used when no channel rule matches. The individual rule conditions in utm.ts were not re-checked one by one. Copied components don't update themselves, so re-check after rule changes (see updating a component).

What it stops

UTM links split analytics

Also known as

utm · utm builder · campaign url · ga4 · google analytics · utm_source · marketing link · tracking

Field type

Dependencies

Pairs well with