843 lines
No EOL
32 KiB
Markdown
843 lines
No EOL
32 KiB
Markdown
|
|
## Your internet traffic is being tracked
|
|
|
|
When you open up your phone and click on or share links though websites and applications websites are secretly injecting tracking information into the pages.
|
|
|
|
explain why that is a bad thing for privacy, and personal life
|
|
- you didn't consent to being tracked you just wanted to open a webpage
|
|
- can be used to make targeted ads work better and influence people behavers and beliefs
|
|
- can be used to track what you specifically are looking at on the internet and who you know
|
|
- it can be used to track and build profiles of who knows who
|
|
- makes links harder for people to read
|
|
- saves screen space
|
|
|
|
|
|
## How do Links/URLs work
|
|
|
|
<style>
|
|
.url-container {
|
|
margin: 1em 0;
|
|
}
|
|
|
|
.url-example {
|
|
font-family: monospace;
|
|
font-size: 1.2em;
|
|
padding: 1em;
|
|
background: var(--code-background, #f5f5f5);
|
|
border: 1px solid var(--border-color, #ddd);
|
|
border-radius: 8px;
|
|
margin-bottom: 1em;
|
|
overflow-x: auto;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.url-example span,
|
|
.url-legend-item {
|
|
transition: opacity 0.2s;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.url-legend {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.75em;
|
|
padding: 1em;
|
|
background: var(--code-background, #f5f5f5);
|
|
border: 1px solid var(--border-color, #ddd);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.url-legend-item {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 0.5em;
|
|
}
|
|
|
|
.url-legend-item .url-legend-label {
|
|
font-weight: 600;
|
|
min-width: 8em;
|
|
}
|
|
|
|
.url-legend-item .url-legend-desc {
|
|
color: #666;
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
.url-required {
|
|
color: #dc2626;
|
|
font-size: 0.7em;
|
|
vertical-align: super;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.url-legend-color {
|
|
width: 1em;
|
|
height: 1em;
|
|
border-radius: 3px;
|
|
flex-shrink: 0;
|
|
margin-top: 0.2em;
|
|
}
|
|
|
|
.url-part-protocol { color: #db2777; }
|
|
.url-legend-protocol { background: #db2777; }
|
|
|
|
.url-part-hostname { color: #2563eb; }
|
|
.url-legend-hostname { background: #2563eb; }
|
|
|
|
.url-part-port { color: #0891b2; }
|
|
.url-legend-port { background: #0891b2; }
|
|
|
|
.url-part-path { color: #16a34a; }
|
|
.url-legend-path { background: #16a34a; }
|
|
|
|
.url-part-query { color: #dc2626; }
|
|
.url-legend-query { background: #dc2626; }
|
|
|
|
.url-part-fragment { color: #9333ea; }
|
|
.url-legend-fragment { background: #9333ea; }
|
|
|
|
/* Cross-highlighting using :has() - no JavaScript needed */
|
|
.url-container:has([data-part]:hover) [data-part] { opacity: 0.4; }
|
|
|
|
/* Keep hovered element visible but without glow */
|
|
.url-container [data-part]:hover { opacity: 1 !important; }
|
|
|
|
/* Highlight style with neutral glow */
|
|
.url-highlight {
|
|
opacity: 1 !important;
|
|
background: rgba(0, 0, 0, 0.08);
|
|
box-shadow: 0 0 8px 4px rgba(0, 0, 0, 0.12);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* When hovering URL parts, highlight matching legend items */
|
|
.url-container:has(.url-example [data-part="protocol"]:hover) .url-legend [data-part="protocol"],
|
|
.url-container:has(.url-example [data-part="hostname"]:hover) .url-legend [data-part="hostname"],
|
|
.url-container:has(.url-example [data-part="port"]:hover) .url-legend [data-part="port"],
|
|
.url-container:has(.url-example [data-part="path"]:hover) .url-legend [data-part="path"],
|
|
.url-container:has(.url-example [data-part="query"]:hover) .url-legend [data-part="query"],
|
|
.url-container:has(.url-example [data-part="fragment"]:hover) .url-legend [data-part="fragment"] {
|
|
opacity: 1 !important;
|
|
padding: 0.5em 0.75em;
|
|
margin: -0.5em -0.75em;
|
|
border-radius: 0.5em;
|
|
box-shadow:
|
|
inset 0 0 0.5em 0.25em rgba(0, 0, 0, 0.06),
|
|
0 0 0.75rem 0.5rem rgba(0, 0, 0, 0.06),
|
|
0 0 1.25rem 1rem rgba(0, 0, 0, 0.04),
|
|
0 0 2rem 1.5rem rgba(0, 0, 0, 0.02);
|
|
}
|
|
|
|
/* When hovering legend items, highlight matching URL parts */
|
|
.url-container:has(.url-legend [data-part="protocol"]:hover) .url-example [data-part="protocol"],
|
|
.url-container:has(.url-legend [data-part="hostname"]:hover) .url-example [data-part="hostname"],
|
|
.url-container:has(.url-legend [data-part="port"]:hover) .url-example [data-part="port"],
|
|
.url-container:has(.url-legend [data-part="path"]:hover) .url-example [data-part="path"],
|
|
.url-container:has(.url-legend [data-part="query"]:hover) .url-example [data-part="query"],
|
|
.url-container:has(.url-legend [data-part="fragment"]:hover) .url-example [data-part="fragment"] {
|
|
opacity: 1 !important;
|
|
border-radius: 0.25em;
|
|
box-shadow:
|
|
inset 0 0 0.5em 0.25em rgba(0, 0, 0, 0.06),
|
|
0 0 0.75rem 0.5rem rgba(0, 0, 0, 0.06),
|
|
0 0 1.25rem 1rem rgba(0, 0, 0, 0.04),
|
|
0 0 2rem 1.5rem rgba(0, 0, 0, 0.02);
|
|
}
|
|
</style>
|
|
|
|
<div class="url-container">
|
|
<div class="url-example" role="figure" aria-labelledby="url-example-caption">
|
|
<span class="url-part-protocol" aria-describedby="legend-protocol" data-part="protocol">https://</span><span class="url-part-hostname" aria-describedby="legend-hostname" data-part="hostname">www.example.com</span><span class="url-part-port" aria-describedby="legend-port" data-part="port">:443</span><span class="url-part-path" aria-describedby="legend-path" data-part="path">/products/shoes</span><span class="url-part-query" aria-describedby="legend-query" data-part="query">?utm_source=facebook&utm_campaign=summer_sale&fbclid=abc123</span><span class="url-part-fragment" aria-describedby="legend-fragment" data-part="fragment">#reviews</span>
|
|
</div>
|
|
|
|
<div class="url-legend" role="list" aria-label="URL component legend">
|
|
<div class="url-legend-item" role="listitem" id="legend-protocol" data-part="protocol">
|
|
<span class="url-legend-color url-legend-protocol" aria-hidden="true"></span>
|
|
<span class="url-legend-label">Protocol<span class="url-required">*</span></span>
|
|
<span class="url-legend-desc">What protocol to use to communicate with the server. (https, ftp, etc...)</span>
|
|
</div>
|
|
<div class="url-legend-item" role="listitem" id="legend-hostname" data-part="hostname">
|
|
<span class="url-legend-color url-legend-hostname" aria-hidden="true"></span>
|
|
<span class="url-legend-label">Hostname<span class="url-required">*</span></span>
|
|
<span class="url-legend-desc">Name of the website used to look up the IP address of the server</span>
|
|
</div>
|
|
<div class="url-legend-item" role="listitem" id="legend-port" data-part="port">
|
|
<span class="url-legend-color url-legend-port" aria-hidden="true"></span>
|
|
<span class="url-legend-label">Port</span>
|
|
<span class="url-legend-desc">Network port to connect to (default to 443 for https, and 80 for http)</span>
|
|
</div>
|
|
<div class="url-legend-item" role="listitem" id="legend-path" data-part="path">
|
|
<span class="url-legend-color url-legend-path" aria-hidden="true"></span>
|
|
<span class="url-legend-label">Path</span>
|
|
<span class="url-legend-desc">The specific page or resource location on the server</span>
|
|
</div>
|
|
<div class="url-legend-item" role="listitem" id="legend-query" data-part="query">
|
|
<span class="url-legend-color url-legend-query" aria-hidden="true"></span>
|
|
<span class="url-legend-label">Query Params</span>
|
|
<span class="url-legend-desc">Key-value pairs that pass data to the page</span>
|
|
</div>
|
|
<div class="url-legend-item" role="listitem" id="legend-fragment" data-part="fragment">
|
|
<span class="url-legend-color url-legend-fragment" aria-hidden="true"></span>
|
|
<span class="url-legend-label">Fragment</span>
|
|
<span class="url-legend-desc">Links to a specific section within the page (not sent to server)</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
(function() {
|
|
const urlExample = document.querySelector('.url-example');
|
|
const legendItems = document.querySelectorAll('.url-legend-item[data-part]');
|
|
|
|
legendItems.forEach(item => {
|
|
item.addEventListener('mouseenter', () => {
|
|
const part = item.dataset.part;
|
|
const urlPart = document.querySelector(`.url-example [data-part="${part}"]`);
|
|
if (urlPart && urlExample) {
|
|
const containerRect = urlExample.getBoundingClientRect();
|
|
const partRect = urlPart.getBoundingClientRect();
|
|
const partCenter = partRect.left - containerRect.left + urlExample.scrollLeft + (partRect.width / 2);
|
|
const scrollTarget = partCenter - (containerRect.width / 2);
|
|
urlExample.scrollTo({ left: scrollTarget, behavior: 'smooth' });
|
|
}
|
|
});
|
|
});
|
|
})();
|
|
</script>
|
|
|
|
## Query Parameters
|
|
|
|
Query parameters are a part of a URL that are used to encode some data about a page in its url. They are intended to be optional values but *sometimes* ~~most of the time~~ developers don't actually read or remember technical documentation and RFC's that outline how technologies are supposed to be used and put mandatory data in the optional parameters. [^1]
|
|
|
|
[^1]: While the query parameters are not directly defined as optional they are not a part of the main path which should on its own define a unique stable path to any given element. If a query parameter is needed to fetch a specific resource then the path is by definition not uniquely identifying that resource. Youtube is an example of developers not using these value like they should be. Links like this [`https://www.youtube.com/watch?v=dQw4w9WgXcQ`](https://www.youtube.com/watch?v=dQw4w9WgXcQ) should instead be designed to look something like this `https://www.youtube.com/watch/video/dQw4w9WgXcQ`
|
|
|
|
<style>
|
|
.query-container {
|
|
margin: 1em 0;
|
|
}
|
|
|
|
.query-example {
|
|
font-family: monospace;
|
|
font-size: 1.2em;
|
|
padding: 1em;
|
|
background: var(--code-background, #f5f5f5);
|
|
border: 1px solid var(--border-color, #ddd);
|
|
border-radius: 8px;
|
|
margin-bottom: 1em;
|
|
overflow-x: auto;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.query-example span,
|
|
.query-legend-item {
|
|
transition: opacity 0.2s, box-shadow 0.2s;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.query-legend {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.75em;
|
|
padding: 1em;
|
|
background: var(--code-background, #f5f5f5);
|
|
border: 1px solid var(--border-color, #ddd);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.query-legend-item {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 0.5em;
|
|
}
|
|
|
|
.query-legend-item .query-legend-label {
|
|
font-weight: 600;
|
|
min-width: 8em;
|
|
}
|
|
|
|
.query-legend-item[data-qparam] .query-legend-label {
|
|
min-width: auto;
|
|
}
|
|
|
|
.query-legend-item .query-legend-desc {
|
|
color: #666;
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
.query-legend-color {
|
|
width: 1em;
|
|
height: 1em;
|
|
border-radius: 3px;
|
|
flex-shrink: 0;
|
|
margin-top: 0.2em;
|
|
}
|
|
|
|
/* Structure colors - each UNIQUE */
|
|
.query-part-delimiter { color: #db2777; }
|
|
.query-legend-delimiter { background: #db2777; }
|
|
|
|
.query-part-key { color: #2563eb; }
|
|
.query-legend-key { background: #2563eb; }
|
|
|
|
.query-part-equals { color: #ca8a04; }
|
|
.query-legend-equals { background: #ca8a04; }
|
|
|
|
.query-part-value { color: #16a34a; }
|
|
.query-legend-value { background: #16a34a; }
|
|
|
|
.query-part-separator { color: #9333ea; }
|
|
.query-legend-separator { background: #9333ea; }
|
|
|
|
/* Parameter group highlighting in URL */
|
|
.query-param-group {
|
|
display: inline;
|
|
border-radius: 0.25em;
|
|
transition: box-shadow 0.2s, background 0.2s;
|
|
}
|
|
|
|
/* Cross-highlighting using :has() - no JavaScript needed */
|
|
/* Base: dim everything when hovering any interactive element */
|
|
.query-container:has([data-qpart]:hover) [data-qpart],
|
|
.query-container:has([data-qparam]:hover) [data-qpart],
|
|
.query-container:has([data-qpart]:hover) .query-legend-item,
|
|
.query-container:has([data-qparam]:hover) .query-legend-item {
|
|
opacity: 0.3;
|
|
}
|
|
|
|
/* Keep hovered element visible */
|
|
.query-container [data-qpart]:hover,
|
|
.query-container [data-qparam]:hover {
|
|
opacity: 1 !important;
|
|
}
|
|
|
|
/* When hovering URL structure parts, highlight matching legend items */
|
|
.query-container:has(.query-example [data-qpart="delimiter"]:hover) .query-legend [data-qpart="delimiter"],
|
|
.query-container:has(.query-example [data-qpart="key"]:hover) .query-legend [data-qpart="key"],
|
|
.query-container:has(.query-example [data-qpart="equals"]:hover) .query-legend [data-qpart="equals"],
|
|
.query-container:has(.query-example [data-qpart="value"]:hover) .query-legend [data-qpart="value"],
|
|
.query-container:has(.query-example [data-qpart="separator"]:hover) .query-legend [data-qpart="separator"] {
|
|
opacity: 1 !important;
|
|
padding: 0.5em 0.75em;
|
|
margin: -0.5em -0.75em;
|
|
border-radius: 0.5em;
|
|
box-shadow:
|
|
inset 0 0 0.5em 0.25em rgba(0, 0, 0, 0.06),
|
|
0 0 0.75rem 0.5rem rgba(0, 0, 0, 0.06),
|
|
0 0 1.25rem 1rem rgba(0, 0, 0, 0.04),
|
|
0 0 2rem 1.5rem rgba(0, 0, 0, 0.02);
|
|
}
|
|
|
|
/* When hovering URL parameter groups/spans, highlight matching parameter legend items */
|
|
.query-container:has(.query-example [data-qparam="size"]:hover) .query-legend [data-qparam="size"],
|
|
.query-container:has(.query-example [data-qparam="color"]:hover) .query-legend [data-qparam="color"],
|
|
.query-container:has(.query-example [data-qparam="utm"]:hover) .query-legend [data-qparam="utm"] {
|
|
opacity: 1 !important;
|
|
padding: 0.5em 0.75em;
|
|
margin: -0.5em -0.75em;
|
|
border-radius: 0.5em;
|
|
box-shadow:
|
|
inset 0 0 0.5em 0.25em rgba(0, 0, 0, 0.06),
|
|
0 0 0.75rem 0.5rem rgba(0, 0, 0, 0.06),
|
|
0 0 1.25rem 1rem rgba(0, 0, 0, 0.04),
|
|
0 0 2rem 1.5rem rgba(0, 0, 0, 0.02);
|
|
}
|
|
|
|
/* When hovering legend structure items, highlight matching URL parts */
|
|
.query-container:has(.query-legend [data-qpart="delimiter"]:hover) .query-example [data-qpart="delimiter"],
|
|
.query-container:has(.query-legend [data-qpart="key"]:hover) .query-example [data-qpart="key"],
|
|
.query-container:has(.query-legend [data-qpart="equals"]:hover) .query-example [data-qpart="equals"],
|
|
.query-container:has(.query-legend [data-qpart="value"]:hover) .query-example [data-qpart="value"],
|
|
.query-container:has(.query-legend [data-qpart="separator"]:hover) .query-example [data-qpart="separator"] {
|
|
opacity: 1 !important;
|
|
border-radius: 0.25em;
|
|
box-shadow:
|
|
inset 0 0 0.5em 0.25em rgba(0, 0, 0, 0.06),
|
|
0 0 0.75rem 0.5rem rgba(0, 0, 0, 0.06),
|
|
0 0 1.25rem 1rem rgba(0, 0, 0, 0.04),
|
|
0 0 2rem 1.5rem rgba(0, 0, 0, 0.02);
|
|
}
|
|
|
|
/* When hovering legend parameter items, highlight matching param groups AND their children */
|
|
.query-container:has(.query-legend [data-qparam="size"]:hover) .query-example .query-param-group[data-qparam="size"],
|
|
.query-container:has(.query-legend [data-qparam="color"]:hover) .query-example .query-param-group[data-qparam="color"],
|
|
.query-container:has(.query-legend [data-qparam="utm"]:hover) .query-example .query-param-group[data-qparam="utm"] {
|
|
border-radius: 0.25em;
|
|
box-shadow:
|
|
inset 0 0 0.5em 0.25em rgba(0, 0, 0, 0.06),
|
|
0 0 0.75rem 0.5rem rgba(0, 0, 0, 0.06),
|
|
0 0 1.25rem 1rem rgba(0, 0, 0, 0.04),
|
|
0 0 2rem 1.5rem rgba(0, 0, 0, 0.02);
|
|
}
|
|
|
|
/* Ensure children of highlighted param groups are visible */
|
|
.query-container:has(.query-legend [data-qparam="size"]:hover) .query-example .query-param-group[data-qparam="size"] > span,
|
|
.query-container:has(.query-legend [data-qparam="color"]:hover) .query-example .query-param-group[data-qparam="color"] > span,
|
|
.query-container:has(.query-legend [data-qparam="utm"]:hover) .query-example .query-param-group[data-qparam="utm"] > span {
|
|
opacity: 1 !important;
|
|
}
|
|
|
|
.query-legend-section {
|
|
margin-top: 1em;
|
|
padding-top: 0.75em;
|
|
border-top: 1px solid var(--border-color, #ddd);
|
|
}
|
|
|
|
.query-legend-section-title {
|
|
font-weight: 600;
|
|
font-size: 0.85em;
|
|
color: #666;
|
|
margin-bottom: 0.5em;
|
|
}
|
|
|
|
/* Parameter legend labels - styled as code blocks */
|
|
.query-param-label {
|
|
font-family: monospace;
|
|
font-size: 0.9em;
|
|
background: var(--inline-code-background, rgba(0, 0, 0, 0.06));
|
|
padding: 0.15em 0.4em;
|
|
border-radius: 4px;
|
|
border: 1px solid var(--border-color, rgba(0, 0, 0, 0.1));
|
|
min-width: auto;
|
|
}
|
|
</style>
|
|
|
|
<div class="query-container" id="query-container">
|
|
<div class="query-example" role="figure" aria-label="Query parameter example">
|
|
<span class="query-part-delimiter" data-qpart="delimiter">?</span><span class="query-param-group" data-qparam="size"><span class="query-part-key" data-qpart="key" data-qparam="size">size</span><span class="query-part-equals" data-qpart="equals" data-qparam="size">=</span><span class="query-part-value" data-qpart="value" data-qparam="size">medium</span></span><span class="query-part-separator" data-qpart="separator">&</span><span class="query-param-group" data-qparam="color"><span class="query-part-key" data-qpart="key" data-qparam="color">color</span><span class="query-part-equals" data-qpart="equals" data-qparam="color">=</span><span class="query-part-value" data-qpart="value" data-qparam="color">light%20blue</span></span><span class="query-part-separator" data-qpart="separator">&</span><span class="query-param-group" data-qparam="utm"><span class="query-part-key" data-qpart="key" data-qparam="utm">utm_source</span><span class="query-part-equals" data-qpart="equals" data-qparam="utm">=</span><span class="query-part-value" data-qpart="value" data-qparam="utm">facebook</span></span>
|
|
</div>
|
|
|
|
<div class="query-legend" role="list" aria-label="Query parameter legend">
|
|
<div class="query-legend-section-title">Structure</div>
|
|
<div class="query-legend-item" role="listitem" data-qpart="delimiter">
|
|
<span class="query-legend-color query-legend-delimiter" aria-hidden="true"></span>
|
|
<span class="query-legend-label query-label-delimiter">? Delimiter</span>
|
|
<span class="query-legend-desc">Marks the start of query parameters in a URL</span>
|
|
</div>
|
|
<div class="query-legend-item" role="listitem" data-qpart="key">
|
|
<span class="query-legend-color query-legend-key" aria-hidden="true"></span>
|
|
<span class="query-legend-label query-label-key">Key</span>
|
|
<span class="query-legend-desc">The name of the data being passed</span>
|
|
</div>
|
|
<div class="query-legend-item" role="listitem" data-qpart="equals">
|
|
<span class="query-legend-color query-legend-equals" aria-hidden="true"></span>
|
|
<span class="query-legend-label query-label-equals">= Assignment</span>
|
|
<span class="query-legend-desc">Connects each key to its value</span>
|
|
</div>
|
|
<div class="query-legend-item" role="listitem" data-qpart="value">
|
|
<span class="query-legend-color query-legend-value" aria-hidden="true"></span>
|
|
<span class="query-legend-label query-label-value">Value</span>
|
|
<span class="query-legend-desc">The actual data being passed</span>
|
|
</div>
|
|
<div class="query-legend-item" role="listitem" data-qpart="separator">
|
|
<span class="query-legend-color query-legend-separator" aria-hidden="true"></span>
|
|
<span class="query-legend-label query-label-separator">& Separator</span>
|
|
<span class="query-legend-desc">Separates multiple key-value pairs</span>
|
|
</div>
|
|
|
|
<div class="query-legend-section">
|
|
<div class="query-legend-section-title">Parameters in this example</div>
|
|
</div>
|
|
<div class="query-legend-item" role="listitem" data-qparam="size">
|
|
<span class="query-legend-label query-param-label">size=medium</span>
|
|
<span class="query-legend-desc">tells the page which size use a medium size</span>
|
|
</div>
|
|
<div class="query-legend-item" role="listitem" data-qparam="color">
|
|
<span class="query-legend-label query-param-label">color=light%20blue</span>
|
|
<span class="query-legend-desc">special characters are encoded with a % then a number</span>
|
|
</div>
|
|
<div class="query-legend-item" role="listitem" data-qparam="utm">
|
|
<span class="query-legend-label query-param-label">utm_source=facebook</span>
|
|
<span class="query-legend-desc">this param was secretly added to the link when it was posted on facebook</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
(function() {
|
|
const queryExample = document.querySelector('#query-container .query-example');
|
|
const legendItems = document.querySelectorAll('#query-container .query-legend-item');
|
|
|
|
legendItems.forEach(item => {
|
|
item.addEventListener('mouseenter', () => {
|
|
const qpart = item.dataset.qpart;
|
|
const qparam = item.dataset.qparam;
|
|
|
|
// Find target element to scroll to
|
|
let scrollTarget = null;
|
|
if (qpart) {
|
|
scrollTarget = document.querySelector(`#query-container .query-example [data-qpart="${qpart}"]`);
|
|
} else if (qparam) {
|
|
scrollTarget = document.querySelector(`#query-container .query-param-group[data-qparam="${qparam}"]`);
|
|
}
|
|
|
|
if (scrollTarget && queryExample) {
|
|
const containerRect = queryExample.getBoundingClientRect();
|
|
const partRect = scrollTarget.getBoundingClientRect();
|
|
const partCenter = partRect.left - containerRect.left + queryExample.scrollLeft + (partRect.width / 2);
|
|
const scrollPos = partCenter - (containerRect.width / 2);
|
|
queryExample.scrollTo({ left: scrollPos, behavior: 'smooth' });
|
|
}
|
|
});
|
|
});
|
|
})();
|
|
</script>
|
|
|
|
These parameters can be very useful for things like saying how many items should be returned with a query, what specific page the query is for, or for filters on a page itself.
|
|
|
|
`limit=50`, `page=2`, `sort=latest`, `name=JohnJohn%20Doe`, etc...
|
|
|
|
If there are any extra query parameter in a websites URL it isn't harmful to the function of the website because the website and its server can simply just ignore the unused parameters.
|
|
|
|
Over time ad tech companies learned that they can take any arbitrary URL that is displayed on their website and just add their own query parameters to it.
|
|
|
|
A common format that these tracking parameters take are [UTM tracking codes](https://wikipedia.org/wiki/UTM_parameters).
|
|
|
|
| query parameter | description |
|
|
| --- | --- |
|
|
| utm_source | how did you get to the site |
|
|
| utm_medium | what type of link was used to get you to the site |
|
|
| utm_campaign | what specific promotion brought you here |
|
|
| utm_term | search term used |
|
|
| utm_content | what specific page element was clicked to bring you to the page |
|
|
|
|
From there the host site can use that data to track analytics how users got to their site or how their site is being used and if the page is using any scripts served up by those same ad tech companies or tooling they have built then those scripts and tools can harvest that data and send it back to the ad tech company to track user habits.
|
|
|
|
While UTM codes are probably the most common way that tracking information is added to links, they are not the only way and there is nothing stopping companies from using other techniques.
|
|
|
|
One such technique is though the usage of URL shorteners. Not only can url shorteners hide the usage of tracking query parameters behind short nice looking redirect, URL shortener companies also track the ip address's of all users who click on a link as well as embed cookies into your browser sessions to track what sites you are visiting specific down to the individual user level.
|
|
|
|
## How can you help protect yourself and others
|
|
|
|
### Just remove them manually
|
|
|
|
The most basic low tech way to remove the trackers is to just delete them yourself or just not copy them. This can help protect people that you are sharing the links with but it can become a bit tedious to manually copy every single link you want to visit and remove the trackers from its link.
|
|
|
|
<style>
|
|
/* Browser/Platform Detection Styles */
|
|
.protect-section {
|
|
margin: 1.5em 0;
|
|
}
|
|
|
|
.protect-section h3 {
|
|
margin-bottom: 0.75em;
|
|
}
|
|
|
|
/* Extension card styling */
|
|
.extension-card {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 1em;
|
|
padding: 1em;
|
|
background: var(--code-background, #f5f5f5);
|
|
border: 1px solid var(--border-color, #ddd);
|
|
border-radius: 8px;
|
|
margin-bottom: 0.75em;
|
|
text-decoration: none;
|
|
color: inherit;
|
|
transition: border-color 0.2s, box-shadow 0.2s;
|
|
}
|
|
|
|
.extension-card:hover {
|
|
border-color: var(--secondary-color, #3498db);
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.extension-info {
|
|
flex: 1;
|
|
}
|
|
|
|
.extension-name {
|
|
font-weight: 600;
|
|
color: var(--primary-color, #2c3e50);
|
|
margin-bottom: 0.25em;
|
|
}
|
|
|
|
.extension-desc {
|
|
font-size: 0.9em;
|
|
color: #666;
|
|
margin: 0;
|
|
}
|
|
|
|
.extension-badge {
|
|
display: inline-block;
|
|
font-size: 0.75em;
|
|
padding: 0.2em 0.5em;
|
|
border-radius: 4px;
|
|
background: var(--secondary-color, #3498db);
|
|
color: white;
|
|
margin-left: 0.5em;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
/* Browser-specific highlighting - all hidden by default */
|
|
.browser-detected-firefox,
|
|
.browser-detected-chrome,
|
|
.browser-detected-edge {
|
|
display: none;
|
|
}
|
|
|
|
.browser-list-fallback {
|
|
display: block;
|
|
}
|
|
|
|
.browser-dropdown-container {
|
|
display: none;
|
|
}
|
|
|
|
/* Remove border from expandable inside dropdown containers */
|
|
.browser-dropdown-container .expandable,
|
|
.platform-dropdown-container .expandable {
|
|
border: none;
|
|
margin: 0;
|
|
}
|
|
|
|
.browser-dropdown-container .expandable summary,
|
|
.platform-dropdown-container .expandable summary {
|
|
background: none;
|
|
padding: 0.5em 0;
|
|
border-bottom: none;
|
|
}
|
|
|
|
.browser-dropdown-container .expandable[open] summary,
|
|
.platform-dropdown-container .expandable[open] summary {
|
|
border-bottom: none;
|
|
margin-bottom: 0.5em;
|
|
}
|
|
|
|
/* Firefox detection using -moz prefixed properties */
|
|
@supports (-moz-appearance: none) {
|
|
.browser-detected-firefox {
|
|
display: block;
|
|
}
|
|
/* Ensure Chrome/Edge stay hidden even though Firefox supports -webkit-appearance */
|
|
.browser-detected-chrome,
|
|
.browser-detected-edge {
|
|
display: none !important;
|
|
}
|
|
.browser-list-fallback {
|
|
display: none;
|
|
}
|
|
.browser-dropdown-container {
|
|
display: block;
|
|
}
|
|
.browser-dropdown-container .browser-firefox {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
/* Chrome/Chromium/Edge detection - only when NOT Firefox */
|
|
@supports (-webkit-appearance: none) and (not (-moz-appearance: none)) {
|
|
.browser-detected-chrome {
|
|
display: block;
|
|
}
|
|
.browser-list-fallback {
|
|
display: none;
|
|
}
|
|
.browser-dropdown-container {
|
|
display: block;
|
|
}
|
|
.browser-dropdown-container .browser-chrome {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
/* Platform detection for desktop/mobile */
|
|
.platform-detected {
|
|
display: none;
|
|
}
|
|
|
|
.platform-list-fallback {
|
|
display: block;
|
|
}
|
|
|
|
.platform-dropdown-container {
|
|
display: none;
|
|
}
|
|
|
|
/* Platform app cards */
|
|
.app-card {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 1em;
|
|
padding: 1em;
|
|
background: var(--code-background, #f5f5f5);
|
|
border: 1px solid var(--border-color, #ddd);
|
|
border-radius: 8px;
|
|
margin-bottom: 0.75em;
|
|
text-decoration: none;
|
|
color: inherit;
|
|
transition: border-color 0.2s, box-shadow 0.2s;
|
|
}
|
|
|
|
.app-card:hover {
|
|
border-color: var(--secondary-color, #3498db);
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.app-info {
|
|
flex: 1;
|
|
}
|
|
|
|
.app-name {
|
|
font-weight: 600;
|
|
color: var(--primary-color, #2c3e50);
|
|
margin-bottom: 0.25em;
|
|
}
|
|
|
|
.app-desc {
|
|
font-size: 0.9em;
|
|
color: #666;
|
|
margin: 0;
|
|
}
|
|
|
|
.app-platforms {
|
|
display: flex;
|
|
gap: 0.5em;
|
|
margin-top: 0.5em;
|
|
}
|
|
|
|
.platform-tag {
|
|
font-size: 0.75em;
|
|
padding: 0.2em 0.5em;
|
|
border-radius: 4px;
|
|
background: #e0e0e0;
|
|
color: #444;
|
|
}
|
|
|
|
/* Section dividers */
|
|
.protect-divider {
|
|
margin: 2em 0;
|
|
border: none;
|
|
border-top: 1px solid var(--border-color, #ddd);
|
|
}
|
|
</style>
|
|
|
|
### Install browser extensions to automate it for you
|
|
|
|
You can install browser extensions that automatically remove tracking parameters from URLs as you browse:
|
|
|
|
#### ClearURL
|
|
|
|
<div class="protect-section">
|
|
<div class="browser-detected-firefox">
|
|
<a href="https://addons.mozilla.org/en-US/firefox/addon/clearurls/" class="extension-card" target="_blank" rel="noopener">
|
|
<div class="extension-info">
|
|
<div class="extension-name">ClearURLs for Firefox<span class="extension-badge">Recommended for your browser</span></div>
|
|
<p class="extension-desc">Removes tracking elements from URLs automatically</p>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<div class="browser-detected-chrome">
|
|
<a href="https://chromewebstore.google.com/detail/clearurls/lckanjgmijmafbedllaakclkaicjfmnk" class="extension-card" target="_blank" rel="noopener">
|
|
<div class="extension-info">
|
|
<div class="extension-name">ClearURLs for Chrome<span class="extension-badge">Recommended for your browser</span></div>
|
|
<p class="extension-desc">Removes tracking elements from URLs automatically</p>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<div class="browser-detected-edge">
|
|
<a href="https://microsoftedge.microsoft.com/addons/detail/clearurls/mdkdmaickkfdekbjdoojfalpbkgaddei" class="extension-card" target="_blank" rel="noopener">
|
|
<div class="extension-info">
|
|
<div class="extension-name">ClearURLs for Edge<span class="extension-badge">Recommended for your browser</span></div>
|
|
<p class="extension-desc">Removes tracking elements from URLs automatically</p>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<div class="browser-dropdown-container">
|
|
<details class="expandable">
|
|
<summary>Show all browsers</summary>
|
|
<a href="https://addons.mozilla.org/en-US/firefox/addon/clearurls/" class="extension-card browser-firefox" target="_blank" rel="noopener">
|
|
<div class="extension-info">
|
|
<div class="extension-name">ClearURLs for Firefox</div>
|
|
<p class="extension-desc">Removes tracking elements from URLs automatically</p>
|
|
</div>
|
|
</a>
|
|
<a href="https://chromewebstore.google.com/detail/clearurls/lckanjgmijmafbedllaakclkaicjfmnk" class="extension-card browser-chrome" target="_blank" rel="noopener">
|
|
<div class="extension-info">
|
|
<div class="extension-name">ClearURLs for Chrome</div>
|
|
<p class="extension-desc">Removes tracking elements from URLs automatically</p>
|
|
</div>
|
|
</a>
|
|
<a href="https://microsoftedge.microsoft.com/addons/detail/clearurls/mdkdmaickkfdekbjdoojfalpbkgaddei" class="extension-card browser-edge" target="_blank" rel="noopener">
|
|
<div class="extension-info">
|
|
<div class="extension-name">ClearURLs for Edge</div>
|
|
<p class="extension-desc">Removes tracking elements from URLs automatically</p>
|
|
</div>
|
|
</a>
|
|
</details>
|
|
</div>
|
|
<div class="browser-list-fallback">
|
|
<a href="https://addons.mozilla.org/en-US/firefox/addon/clearurls/" class="extension-card" target="_blank" rel="noopener">
|
|
<div class="extension-info">
|
|
<div class="extension-name">ClearURLs for Firefox</div>
|
|
<p class="extension-desc">Removes tracking elements from URLs automatically</p>
|
|
</div>
|
|
</a>
|
|
<a href="https://chromewebstore.google.com/detail/clearurls/lckanjgmijmafbedllaakclkaicjfmnk" class="extension-card" target="_blank" rel="noopener">
|
|
<div class="extension-info">
|
|
<div class="extension-name">ClearURLs for Chrome</div>
|
|
<p class="extension-desc">Removes tracking elements from URLs automatically</p>
|
|
</div>
|
|
</a>
|
|
<a href="https://microsoftedge.microsoft.com/addons/detail/clearurls/mdkdmaickkfdekbjdoojfalpbkgaddei" class="extension-card" target="_blank" rel="noopener">
|
|
<div class="extension-info">
|
|
<div class="extension-name">ClearURLs for Edge</div>
|
|
<p class="extension-desc">Removes tracking elements from URLs automatically</p>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
[Source Code](https://github.com/ClearURLs/Addon)
|
|
|
|
### Use websites with tools to do it for you
|
|
|
|
You can also use web tools that you can give a URL and it will clean it for you:
|
|
|
|
<div class="protect-section">
|
|
<div class="platform-list-fallback">
|
|
<a href="https://linkcleaner.app/" class="app-card" target="_blank" rel="noopener">
|
|
<div class="app-info">
|
|
<div class="app-name">LinkCleaner</div>
|
|
<p class="app-desc">Paste any URL and get a clean version without tracking parameters. Works in your browser - no installation needed.</p>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ### Desktop applications
|
|
|
|
Clipboard monitoring apps that automatically clean URLs when you copy them:
|
|
|
|
<div class="protect-section">
|
|
<div class="platform-list-fallback">
|
|
<a href="" class="app-card" target="_blank" rel="noopener">
|
|
<div class="app-info">
|
|
<div class="app-name"></div>
|
|
<p class="app-desc"></p>
|
|
<div class="app-platforms">
|
|
<span class="platform-tag">Linux</span>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div> -->
|
|
|
|
### Mobile applications
|
|
|
|
There are some mobile apps that can also help remove trackers from links:
|
|
|
|
<div class="protect-section">
|
|
<div class="platform-list-fallback">
|
|
<a href="https://f-droid.org/packages/com.svenjacobs.app.leon/" class="app-card" target="_blank" rel="noopener">
|
|
<div class="app-info">
|
|
<div class="app-name">Leon</div>
|
|
<p class="app-desc">Android share target app that removes tracking parameters from URLs. Share any link to Leon before sharing elsewhere.</p>
|
|
<div class="app-platforms">
|
|
<span class="platform-tag">Android</span>
|
|
<span class="platform-tag">F-Droid</span>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div> |