The same piece of content on a WordPress site is often reachable through more than one URL without anyone intending it — http vs https, with vs without www, trailing slash vs none, and tracking parameters appended by ad campaigns all technically point to different URLs as far as a crawler is concerned, even though a human sees the same page.
Where the duplicate URLs actually come from
https://example.com/post-name/
https://example.com/post-name
https://www.example.com/post-name/
https://example.com/post-name/?utm_source=newsletter
https://example.com/post-name/?ref=homepage
Without a canonical tag, a search engine can end up indexing several of these as separate pages, splitting whatever ranking signal that content would otherwise have concentrated in one place.
Self-referencing canonical tags
add_action('wp_head', function() {
if (is_singular()) {
echo '<link rel="canonical" href="' . esc_url(get_permalink()) . '" />';
}
}, 1);
This tells search engines that regardless of which URL variation was used to reach the page, this is the one to actually index. Most SEO plugins already do this — worth checking before adding a duplicate.
Server-level redirects for the structural variants
Canonical tags are a hint, not a hard rule — search engines mostly respect them, but not always. A 301 redirect is a stronger, unambiguous signal for the variants that should never be reachable at all:
# Nginx: force https and non-www
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
Tracking parameters specifically
Rather than trying to redirect away every possible UTM combination, the canonical tag is the right tool here — it lets the tracked URL work normally for the visitor (so your analytics still capture the campaign source) while telling search engines to consolidate ranking signal to the clean, parameter-free version. Trying to strip parameters via redirect instead would break attribution in your analytics, which is usually not worth the tradeoff.