Free tool URL parser: every part and parameter, decoded
Paste a landing-page link, a redirect URL or a whole list of them. Each one is split into its parts, every query parameter is decoded in a table, and campaign tags and ad click IDs are labelled with the platform they belong to, along with the mistakes that stop analytics from reading them.
- One URL or 200 at once
- UTM and 18 click IDs
- Runs locally
Parse URLs
One URL per line. The sample has a newsletter link, a Google Ads click and a single-page-app link with its tags after the #. Try the other samples for ad macros and developer URLs.
Full URLs, URLs without https://, app deep links (myapp://…) or relative paths such as mini-program pages. Up to 200 lines.
URLs
3
Parameters
12
In the query and in the fragment.
Tracking parameters
10
UTM, click IDs and other known tracking tags.
URLs with problems
2
Errors or warnings below.
Checks
- WarningLine 1utm_source=Newsletter has capitals. UTM values are case-sensitive in reports, so Newsletter and newsletter become two rows.
- WarningLine 1color appears 2 times. URLSearchParams.get() and the TapCub script read the first value; PHP's $_GET keeps the last. Keep one.
- NoteLine 2TapCub's default channel rules assign a visit with gclid to Paid search, ahead of any UTM tags.
- ErrorLine 3UTM tags after # (utm_source, utm_medium). The fragment is never sent to the server, and analytics scripts read the query string, so these tags are lost. Move them before the #.
Parts
| Line | Part | Value |
|---|---|---|
| 1 | Protocol | https |
| 1 | Host | shop.example.com |
| 1 | Port | 443 (default) |
| 1 | Path | /products/trail-shoes |
| 1 | Query | ?utm_source=Newsletter&utm_medium=email&utm_campaign=spring_sale&color=blue&color=red |
| 1 | Fragment | — |
| 2 | Protocol | https |
| 2 | Host | www.example.com |
| 2 | Port | 443 (default) |
| 2 | Path | /pricing |
| 2 | Query | ?gclid=Cj0KCQiA5rGuBhCnARIsAN11vgR&utm_source=google&utm_medium=cpc&utm_campaign=brand |
| 2 | Fragment | — |
| 3 | Protocol | https |
| 3 | Host | app.example.com |
| 3 | Port | 443 (default) |
| 3 | Path | / |
| 3 | Query | — |
| 3 | Fragment | #/signup?utm_source=linkedin&utm_medium=social&li_fat_id=8f2c1e |
Parameters
Decoded values. Raw text is shown only when it differs.
| Line | Name | Value (decoded) | Raw | Type | Where |
|---|---|---|---|---|---|
| 1 | utm_source | Newsletter | — | UTM | Query |
| 1 | utm_medium | email | — | UTM | Query |
| 1 | utm_campaign | spring_sale | — | UTM | Query |
| 1 | color | blue | — | Parameter | Query |
| 1 | color | red | — | Parameter | Query |
| 2 | gclid | Cj0KCQiA5rGuBhCnARIsAN11vgR | — | Click ID · Google Ads | Query |
| 2 | utm_source | google | — | UTM | Query |
| 2 | utm_medium | cpc | — | UTM | Query |
| 2 | utm_campaign | brand | — | UTM | Query |
| 3 | utm_source | linkedin | — | UTM | After # |
| 3 | utm_medium | social | — | UTM | After # |
| 3 | li_fat_id | 8f2c1e | — | Click ID · LinkedIn | After # |
https://shop.example.com/products/trail-shoes?color=blue&color=red
https://www.example.com/pricing
https://app.example.com/#/signupUTM tags, click IDs and other tracking tags removed; everything else kept as written.
[
{
"url": "https://shop.example.com/products/trail-shoes?utm_source=Newsletter&utm_medium=email&utm_campaign=spring_sale&color=blue&color=red",
"scheme": "https",
"host": "shop.example.com",
"port": null,
"path": "/products/trail-shoes",
"query": {
"utm_source": "Newsletter",
"utm_medium": "email",
"utm_campaign": "spring_sale",
"color": [
"blue",
"red"
]
},
"fragment": null
},
{
"url": "https://www.example.com/pricing?gclid=Cj0KCQiA5rGuBhCnARIsAN11vgR&utm_source=google&utm_medium=cpc&utm_campaign=brand",
"scheme": "https",
"host": "www.example.com",
"port": null,
"path": "/pricing",
"query": {
"gclid": "Cj0KCQiA5rGuBhCnARIsAN11vgR",
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "brand"
},
"fragment": null
},
{
"url": "https://app.example.com/#/signup?utm_source=linkedin&utm_medium=social&li_fat_id=8f2c1e",
"scheme": "https",
"host": "app.example.com",
"port": null,
"path": "/",
"query": {},
"fragment": "/signup?utm_source=linkedin&utm_medium=social&li_fat_id=8f2c1e"
}
]Repeated parameters become arrays.
Version v1.0Updated Update history
What each table tells you
Four counts on top, then the checks, the parts of each URL, every parameter and two ready-to-copy outputs.
Parts
Protocol, host, port, path, query and fragment as the browser sees them. Internationalised domains are shown both ways (xn--mnchen-3ya.de → münchen.de), and an encoded path is decoded next to the raw form.
Parameters
Each name and value, decoded. The Type column labels UTM tags, the 18 click IDs TapCub reads, other known tracking tags, and names that are one letter-case away from a UTM tag or click ID. Parameters after # are marked in red because analytics does not read them.
Checks
Errors break attribution (tags after #, broken encoding). Warnings split or lose data in reports (capital letters, duplicates, unfilled macros). Notes explain how TapCub will treat a click ID.
Clean URL and JSON
The clean version drops tracking parameters but keeps everything else as written, which is handy for canonical tags and sharing. The JSON gives the parts and a parameter object for code, with repeats as arrays.
The parser follows the WHATWG URL standard that browsers implement, and reads the raw text separately, so problems the browser silently "fixes" (such as a ? after the #) are still reported.
Three steps
Nothing to install and nothing to click to run.
-
1
Paste URLs
Copy them from an ad preview, an email, a server log or the address bar. One per line; a column copied from a spreadsheet works too.
-
2
Read the checks
Fix errors first: tags after #, broken escapes, unreadable URLs. Then look at warnings such as capital letters or a parameter sent twice.
-
3
Copy what you need
Copy a single decoded value from the table, the clean URLs for a canonical tag, or the JSON for a test.
Anatomy of a URL
RFC 3986 defines the generic parts; browsers parse by the WHATWG URL standard. A query parameter is decoded by the form-encoding rules: split on &, then on the first =, turn + into a space and undo %XX escapes.
- The fragment (after #) stays in the browser and is never sent in the HTTP request
- Parameter names and values are case-sensitive:
utm_Sourceis notutm_source - The same parameter can appear more than once; which value wins depends on the reader
- Non-ASCII hosts are sent in Punycode (
xn--); non-ASCII paths and values are sent as UTF-8 %XX escapes
| Part | Value | Sent to the server? |
|---|---|---|
| Protocol | https | Decides how to connect |
| Host | shop.example.com | Yes (Host header) |
| Port | 8443 (443 if omitted) | Decides where to connect |
| Path | /products/shoes | Yes |
| Query | utm_source=newsletter&color=red | Yes; analytics reads tags here |
| Fragment | reviews | No; stays in the browser |
Three sample links, three kinds of problem
What the parser reports for the default sample.
| URL | Recognised | Finding | Fix |
|---|---|---|---|
| shop…/trail-shoes | 3 UTM tags | Newsletter has a capital; color appears twice | Lowercase UTM values; keep one color |
| www…/pricing | gclid (Google Ads) + 3 UTM tags | TapCub assigns Paid search because of gclid | Nothing to fix |
| app…/#/signup | li_fat_id (LinkedIn) + 2 UTM tags | All three are after #, so none reach analytics | Put the query before #: /?utm_source=…#/signup |
The third case is common with single-page apps that use hash routing. The router reads its route from the fragment, but analytics scripts read location.search, which is empty here.
Why parameters go missing in reports
The link works, the page loads, and the campaign still shows as Direct or Other.
Tags after the #
Anything after # is fragment. Put UTM tags and click IDs in the query, before the #, even on single-page apps.
Mixed letter case
utm_Source is ignored, and Facebook and facebook are two rows. Pick lowercase and keep to it.
A parameter added twice
Link builders and redirects often append a second utm_source. Readers disagree on which one counts.
Placeholders left in
{campaignid} or __CLICKID__ in a live URL means the ad platform did not fill the macro, or you opened the template link directly.
Sources and campaigns, read from the landing URL
The TapCub script reads the same things this tool shows: the five UTM tags and the click IDs of 14 ad platforms, straight from the landing-page query string.
Sources and UTM
Channels, AI assistants, UTM source, medium and campaign, and landing-page conversion side by side.
Learn moreAd click IDs and attribution
Click IDs from 14 ad platforms, first and last touch, and imported costs for return on ad spend by channel.
Learn moreYour own channel rules
Rules you add are checked before the defaults, and history can be recomputed after a change.
Learn moreURL parser questions
Still have a question?
Chat with the team behind TapCub — we usually reply within a few hours on business days.
What does a URL parser do?
It splits a URL into protocol, host, port, path, query string and fragment, and decodes each query parameter into a name and a value. This one also labels campaign tags and ad click IDs and checks for problems that stop analytics from reading them.
How do I get the parameters out of a URL?
Paste the URL; the Parameters table lists every name and decoded value. In code, new URL(link).searchParams does the same in a browser or Node.js. The JSON output gives you the result as an object to copy.
Why are my UTM parameters not showing in analytics?
The usual causes: the tags sit after # where scripts cannot read them, the name has a capital letter (utm_Source), a redirect stripped the query, or the page loads before the analytics script runs. The checks flag the first two.
What is the difference between the query and the fragment?
The query (after ?) is sent to the server and read by analytics. The fragment (after #) stays in the browser; it jumps to a section or drives a single-page app router. Tags placed in the fragment are invisible to the server and, by default, to analytics.
Which click IDs does it recognise?
The 18 parameters TapCub reads: gclid, wbraid, gbraid, dclid, fbclid, ttclid, msclkid, twclid, li_fat_id, ScCid, epik, rdt_cid, yclid, plus clickid (Ocean Engine), bd_vid (Baidu), gdt_vid and qz_gdt (Tencent Ads) and callback (Kuaishou). It also labels a few other tracking tags, such as srsltid and gad_source from Google, as not being click IDs.
Should + in a URL be a space?
In a query string, by the form-encoding rules browsers use, yes: q=caf%C3%A9+cr%C3%A8me is "café crème". In the path, + is a literal plus. Untick the option if your server treats + literally.
Is it safe to paste URLs with tokens or emails?
Parsing happens in your browser and nothing is uploaded or put in a share link. The checks will still warn you: a token or email in a query string ends up in logs and in the Referer sent to other sites.
Update history
New features, fixes and data refreshes for this tool, newest first.
-
· v1.0
LaunchedFirst release.
Data this tool relies on
- Ad platform click ID parameters — checked 2026-11-10, reviewed every 6 months (next review by 2027-05-10)
Missing something or found an error? Tell us — requests that come up often go into the next update. All tool updates
See which links actually bring visitors
Add TapCub to your site and every tagged link and ad click is grouped into channels and campaigns automatically.