|
1 | 1 | import { useHistory, useLocation } from '@docusaurus/router'; |
2 | 2 | import { useEffect, useRef } from 'react'; |
3 | 3 |
|
4 | | -const hasUTMParams = (search: string) => { |
| 4 | +const UTM_KEYS = ['utm_source', 'utm_medium', 'utm_campaign'] as const; |
| 5 | +const STORAGE_KEY = 'utm_params'; |
| 6 | + |
| 7 | +const extractUTMParams = (search: string): string => { |
5 | 8 | const params = new URLSearchParams(search); |
6 | | - return ['utm_source', 'utm_medium', 'utm_campaign'].some(p => params.has(p)); |
| 9 | + const utmParams = new URLSearchParams(); |
| 10 | + UTM_KEYS.forEach(key => { |
| 11 | + const value = params.get(key); |
| 12 | + if (value) utmParams.set(key, value); |
| 13 | + }); |
| 14 | + return utmParams.toString(); |
7 | 15 | }; |
8 | 16 |
|
9 | 17 | export const useUTMPersistenceDocs = () => { |
10 | 18 | const location = useLocation(); |
11 | 19 | const history = useHistory(); |
12 | | - const isManualRemoval = useRef(false); |
13 | | - const previousSearch = useRef(''); |
14 | | - |
15 | | - const getUTMParams = (search: string) => { |
16 | | - const params = new URLSearchParams(search); |
17 | | - const utmParams = new URLSearchParams(); |
18 | | - ['utm_source', 'utm_medium', 'utm_campaign'].forEach(param => { |
19 | | - const value = params.get(param); |
20 | | - if (value) utmParams.set(param, value); |
21 | | - }); |
22 | | - return utmParams.toString(); |
23 | | - }; |
| 20 | + const prevPathname = useRef(location.pathname); |
24 | 21 |
|
25 | 22 | useEffect(() => { |
26 | | - // Skip initial render |
27 | | - if (previousSearch.current === '') { |
28 | | - previousSearch.current = location.search; |
29 | | - if (hasUTMParams(location.search)) { |
30 | | - sessionStorage.setItem('utm_params', getUTMParams(location.search)); |
31 | | - } |
32 | | - return; |
33 | | - } |
| 23 | + const currentUTMs = extractUTMParams(location.search); |
| 24 | + const storedUTMs = sessionStorage.getItem(STORAGE_KEY); |
| 25 | + const isNavigation = prevPathname.current !== location.pathname; |
34 | 26 |
|
35 | | - const hadUTMs = hasUTMParams(previousSearch.current); |
36 | | - const hasUTMs = hasUTMParams(location.search); |
37 | | - |
38 | | - // Detect manual removal |
39 | | - if (hadUTMs && !hasUTMs && location.pathname === previousSearch.current.split('?')[0]) { |
40 | | - isManualRemoval.current = true; |
41 | | - sessionStorage.removeItem('utm_params'); |
42 | | - console.log('Manual removal detected - UTMs cleared'); |
43 | | - } |
44 | | - // Save new UTMs if they exist |
45 | | - else if (hasUTMs) { |
46 | | - isManualRemoval.current = false; |
47 | | - sessionStorage.setItem('utm_params', getUTMParams(location.search)); |
48 | | - } |
49 | | - // Restore UTMs if they're missing and weren't manually removed |
50 | | - else if (!isManualRemoval.current) { |
51 | | - const storedParams = sessionStorage.getItem('utm_params'); |
52 | | - if (storedParams) { |
53 | | - const newSearch = storedParams ? `?${storedParams}` : ''; |
54 | | - if (location.search !== newSearch) { |
55 | | - history.replace({ |
56 | | - pathname: location.pathname, |
57 | | - search: newSearch, |
58 | | - }); |
59 | | - } |
60 | | - } |
| 27 | + if (currentUTMs) { |
| 28 | + sessionStorage.setItem(STORAGE_KEY, currentUTMs); |
| 29 | + } else if (storedUTMs && isNavigation) { |
| 30 | + history.replace({ |
| 31 | + pathname: location.pathname, |
| 32 | + search: `?${storedUTMs}`, |
| 33 | + hash: location.hash, |
| 34 | + }); |
| 35 | + } else if (!currentUTMs && storedUTMs && !isNavigation) { |
| 36 | + sessionStorage.removeItem(STORAGE_KEY); |
61 | 37 | } |
62 | 38 |
|
63 | | - previousSearch.current = location.search; |
64 | | - }, [location, history]); |
| 39 | + prevPathname.current = location.pathname; |
| 40 | + }, [location.pathname, location.search, location.hash]); |
65 | 41 | }; |
0 commit comments