UTM links are easy to add and easy to ruin.
The usual mistake is not technical. It is naming. One person uses Bluesky, another uses bluesky, another uses bsky, and Google Analytics treats those as separate values.
Use TheBlue.social's UTM builder when you want a quick tracked URL for a social post. I use it before I schedule posts with links, especially when the same landing page is going out to Bluesky, X, Threads, LinkedIn, Pinterest, or Mastodon.
Start with the three fields that matter
Google's URL builder documentation says that when you add campaign parameters to a URL, you should always use utm_source, utm_medium, and utm_campaign.
That is the minimum I use for organic social posts.
utm_source=bluesky
utm_medium=social
utm_campaign=summer-launch
I use utm_source for the platform, utm_medium for the channel, and utm_campaign for the campaign name I want to see later.
Nothing fancy.
If the link is for a normal Bluesky post, this is enough:
https://example.com/pricing?utm_source=bluesky&utm_medium=social&utm_campaign=summer-launch
If the same campaign also goes to LinkedIn, only the source changes:
https://example.com/pricing?utm_source=linkedin&utm_medium=social&utm_campaign=summer-launch
Same campaign, different source. The report stays readable.
Keep the naming convention boring
Google Analytics parameter values are case sensitive. Google's documentation gives the plain example that utm_source=google and utm_source=Google are different values.
That one detail causes a lot of bad reports.
My rule:
- lowercase everything
- use hyphens, not spaces
- use the same platform names every time
- do not rename a campaign halfway through
The campaign name is where I see the most avoidable mess. If the launch is called summer-launch, I keep that exact string on every platform. I do not use summer_launch in one post and summer-launch-2026 in another unless those are intentionally different campaigns.
This matters more when a link gets reused. A post draft may start on Bluesky, then get adapted for Threads, X, and LinkedIn. The copy can change. The campaign value should not.
Platform source values I use
For TheBlue posts, I would use these source values:
bluesky
x
threads
instagram
linkedin
pinterest
mastodon
I do not use twitter for one post and x for another unless I intentionally want two rows. Most of the time, I want one row per platform.
Use optional fields only when they answer a real question
utm_content is useful when the campaign and platform are the same, but the creative is different.
Google's docs describe it as a way to differentiate creatives, such as two call-to-action links in one email. I use the same idea for social posts.
Good uses:
utm_content=short-hook
utm_content=customer-example
utm_content=image-version
utm_content=reply-link
Weak uses:
utm_content=post
utm_content=social
utm_content=link
Those do not tell me anything. If every social post has utm_content=post, I have added noise.
I leave utm_term blank for normal social posts.
Google describes utm_term as paid keyword data. If I am not tracking paid keywords, I do not fill it in just because the field exists.
The UTM builder shows the field because it is part of the standard parameter set. Empty is fine when the field does not apply.
I also skip utm_id for most small organic campaigns. It can be useful when you have a separate campaign import system or paid campaign IDs. For a solo creator or small team tracking organic posts, readable names are usually enough.
The field I add most often is utm_content, and only when I know what decision I want to make later.
For example, this is useful:
utm_source=bluesky
utm_medium=social
utm_campaign=pricing-page-refresh
utm_content=short-hook
So is this:
utm_source=bluesky
utm_medium=social
utm_campaign=pricing-page-refresh
utm_content=screenshot-post
Now I can compare two Bluesky posts in the same campaign without pretending they were different campaigns.
Check the link before scheduling
After building the URL, I check three things.
- The landing page still opens.
- The UTM values are still in the address bar after redirects.
- The link card looks right.
Redirects are the quiet failure
The redirect check matters. If your landing page redirects from /pricing to /pricing/ and drops the query string, the UTM work is gone before Analytics sees it.
I check this by opening the final URL in a private window and looking at the address bar after the page finishes loading. If the URL still has utm_source, utm_medium, and utm_campaign, I move on. If the parameters are gone, I fix the redirect or use the final canonical URL in the post.
I also avoid using a shortened link unless I need it. Short links add another redirect and another place where tracking can get stripped or hidden. If the platform displays a card anyway, a clean full URL is usually fine.
Then I run the URL through TheBlue.social's Open Graph preview tool. UTMs should not change the card title, description, or image. If they do, the page is probably generating metadata from the full URL instead of the canonical page.
For the post text around the link, I use the multi-platform post previewer. A tracked URL is often long. The visible post still has to fit the platform.
Where the data shows up in GA4
Google says manually tagged values appear as dimensions in reports and explorations. For a simple check, its URL builder docs point to the Traffic acquisition report, using dimensions like Session source/medium, Session source, Session medium, and Session campaign.
That is where I look first.
The quick test:
- Open the tagged URL yourself.
- Wait for GA4 processing.
- Check Traffic acquisition.
- Look for the source, medium, and campaign values you used.
If the visit shows as direct, I check the page tag and redirects before blaming the social platform.
I also check whether I am looking at the right scope. A campaign can show up differently depending on whether I am looking at first-user, session, or event-scoped dimensions. For a quick social post check, session source, session medium, and session campaign are the practical starting point.
If I am testing immediately after clicking, I do not expect every standard report to update instantly. For a real campaign, I care more about whether the values are shaped correctly than whether my own test click appears in the first minute.
The workflow I use
For a link post, this is the practical flow:
- Build the URL in the UTM builder.
- Keep
utm_source,utm_medium, andutm_campaignconsistent. - Add
utm_contentonly when it identifies a specific creative or variation. - Open the final URL and make sure the parameters survive redirects.
- Check the card in the OG preview tool.
- Check the copy in the post previewer.
- Schedule the cleaned-up post in TheBlue.social.
This is small-tool work. Build the URL, check the page, check the post, schedule it.
I do not try to remember UTM names from old posts. I keep a tiny campaign note and reuse it until the campaign is done.
When the campaign is important enough to repeat across platforms, I save the naming convention next to the campaign brief:
source: bluesky, x, threads, linkedin
medium: social
campaign: summer-launch
content: short-hook, customer-example, image-version
That is enough to stop one campaign from turning into six messy rows later.
TheBlue's scheduler comes after this work, not before it. I want the final post to carry the final link. If I change the campaign name later, I rebuild the URL and update the scheduled drafts before they go out.
For small launches, the note can be a line in the content calendar. For larger campaigns, I put it beside the landing page URL, the final post copy, and the expected publish dates. The important part is that every scheduled post pulls from the same source of truth.
Last updated: June 18, 2026