CampaignLink.astro — UTM Campaign Links

A reusable Astro component for real UTM campaign links: newsletter CTAs, paid/social campaigns, promo banners, partner campaigns, launches, and controlled ad landing URLs.

Good fits

  • Email newsletter CTAs
  • Paid/social campaign links
  • Promo banners
  • Partner campaign links
  • Launch campaign links
  • Controlled ad landing-page URLs

Component


interface Props {
	href: string;
	utmSource: string;
	utmMedium: string;
	utmCampaign: string;
	utmContent?: string;
	utmTerm?: string;
	class?: string;
	target?: "_self" | "_blank" | "_parent" | "_top";
	rel?: string;
	ariaLabel?: string;
}

const {
	href,
	utmSource,
	utmMedium,
	utmCampaign,
	utmContent,
	utmTerm,
	class: className,
	target,
	rel,
	ariaLabel,
} = Astro.props;

const campaignUrl = new URL(href, Astro.url);

campaignUrl.searchParams.set("utm_source", utmSource);
campaignUrl.searchParams.set("utm_medium", utmMedium);
campaignUrl.searchParams.set("utm_campaign", utmCampaign);

if (utmContent) {
	campaignUrl.searchParams.set("utm_content", utmContent);
}

if (utmTerm) {
	campaignUrl.searchParams.set("utm_term", utmTerm);
}

const campaignHref = campaignUrl.href;
const externalRel = target === "_blank" ? "noopener noreferrer" : undefined;
const linkRel = rel ?? externalRel;

<a
	href={campaignHref}
	class:list={className}
	target={target}
	rel={linkRel}
	aria-label={ariaLabel}
>
	<slot />
</a>

Examples

Email newsletter CTA

---
import CampaignLink from "@/components/CampaignLink.astro";
---

<CampaignLink
	href="/free-consultation/"
	utmSource="newsletter"
	utmMedium="email"
	utmCampaign="may-2026-consultation"
	utmContent="main-cta-button"
>
	Book a free consultation
</CampaignLink>

Promo banner

---
import CampaignLink from "@/components/CampaignLink.astro";
---

<CampaignLink
	href="/offer/"
	utmSource="website"
	utmMedium="banner"
	utmCampaign="spring-sale"
	utmContent="homepage-top-banner"
	class="promo-banner-link"
>
	View the offer
</CampaignLink>
---
import CampaignLink from "@/components/CampaignLink.astro";
---

<CampaignLink
	href="https://clientsite.com/dental-implants/"
	utmSource="facebook"
	utmMedium="paid-social"
	utmCampaign="dental-implants-may-2026"
	utmContent="before-after-video"
	target="_blank"
>
	Preview campaign landing page
</CampaignLink>

Prop contract

PropRequiredUse
hrefYesDestination URL.
utmSourceYesTraffic source, such as google, newsletter, facebook, instagram.
utmMediumYesChannel type, such as cpc, email, paid-social, social, banner.
utmCampaignYesCampaign or promotion name, such as may-2026-consultation.
utmContentNoCreative, CTA, placement, or variant.
utmTermNoPaid search keyword. Use only when relevant.
classNoOptional CSS class.
targetNoOptional anchor target.
relNoOptional custom rel value.
ariaLabelNoOptional accessible label.

Naming rules

Lowercase, hyphen-separated values.

utm_source=facebook
utm_medium=paid-social
utm_campaign=dental-implants-may-2026
utm_content=before-after-video