11import { useEffect } from 'react'
22import { useRouter } from 'next/router'
33
4- type UtmPreserverProps = {
5- // CSS selector for links that should preserve UTM parameters
6- linkSelector ?: string
7- // Specific page paths where this component should be active
8- activePaths ?: string [ ]
9- }
10-
11- export const UtmPreserver = ( {
12- linkSelector = 'a[href*="github.com/copilot"], a[href*="github.com/github-copilot"]' ,
13- activePaths = [ '/copilot/get-started/plans' ] ,
14- } : UtmPreserverProps ) => {
4+ export const UtmPreserver = ( ) => {
155 const router = useRouter ( )
166
177 useEffect ( ( ) => {
18- // Check if current page should have UTM preservation
19- const shouldPreserveUtm = activePaths . some ( ( path ) => router . asPath . includes ( path ) )
20- if ( ! shouldPreserveUtm ) return
21-
228 // Extract UTM parameters from current URL
239 const getUtmParams = ( ) : URLSearchParams => {
2410 const urlParams = new URLSearchParams ( window . location . search )
@@ -33,6 +19,22 @@ export const UtmPreserver = ({
3319 return utmParams
3420 }
3521
22+ const utmParams = getUtmParams ( )
23+ if ( utmParams . toString ( ) === '' ) return
24+
25+ // Check if a link should have UTM parameters preserved
26+ const shouldPreserveUtm = ( url : string ) : boolean => {
27+ const lowercaseUrl = url . toLowerCase ( )
28+
29+ // Preserve UTM for any external github.com links (including subdomains like blog.github.com)
30+ // but NOT for docs.github.com (which are internal links anyway)
31+ const hasProtocol = lowercaseUrl . startsWith ( 'https://' ) || lowercaseUrl . startsWith ( 'http://' )
32+ const isGithubCom = lowercaseUrl . includes ( 'github.com' )
33+ const isDocsGithubCom = lowercaseUrl . includes ( 'docs.github.com' )
34+
35+ return hasProtocol && isGithubCom && ! isDocsGithubCom
36+ }
37+
3638 // Add UTM parameters to a URL
3739 const addUtmParamsToUrl = ( url : string , utmParams : URLSearchParams ) : string => {
3840 try {
@@ -51,14 +53,10 @@ export const UtmPreserver = ({
5153
5254 // Apply UTM parameters to relevant links
5355 const applyUtmToLinks = ( ) : void => {
54- const utmParams = getUtmParams ( )
55-
56- if ( utmParams . toString ( ) === '' ) return
57-
58- const links = document . querySelectorAll < HTMLAnchorElement > ( linkSelector )
56+ const links = document . querySelectorAll < HTMLAnchorElement > ( 'a[href]' )
5957
6058 links . forEach ( ( link ) => {
61- if ( link . href && ( link . href . startsWith ( 'http://' ) || link . href . startsWith ( 'https://' ) ) ) {
59+ if ( link . href && shouldPreserveUtm ( link . href ) ) {
6260 link . href = addUtmParamsToUrl ( link . href , utmParams )
6361 }
6462 } )
@@ -67,15 +65,9 @@ export const UtmPreserver = ({
6765 // Handle click events for dynamic link modification
6866 const handleLinkClick = ( event : Event ) : void => {
6967 const link = ( event . target as Element ) ?. closest ( 'a' ) as HTMLAnchorElement
70- if ( ! link ) return
71-
72- // Check if this link matches our selector
73- if ( ! link . matches ( linkSelector ) ) return
74-
75- const utmParams = getUtmParams ( )
76- if ( utmParams . toString ( ) === '' ) return
68+ if ( ! link || ! link . href ) return
7769
78- if ( link . href && ( link . href . startsWith ( 'http://' ) || link . href . startsWith ( 'https://' ) ) ) {
70+ if ( shouldPreserveUtm ( link . href ) ) {
7971 link . href = addUtmParamsToUrl ( link . href , utmParams )
8072 }
8173 }
@@ -99,7 +91,7 @@ export const UtmPreserver = ({
9991 document . removeEventListener ( 'click' , handleLinkClick , true )
10092 router . events . off ( 'routeChangeComplete' , handleRouteChange )
10193 }
102- } , [ router . asPath , router . events , linkSelector , activePaths ] )
94+ } , [ router . asPath , router . events ] )
10395
10496 // This component doesn't render anything
10597 return null
0 commit comments