Skip to content

Conversation

@carlagn
Copy link
Contributor

@carlagn carlagn commented Dec 12, 2025

tentative fix on docs utm persistence

Summary by CodeRabbit

  • New Features

    • Site-wide UTM persistence hook and automatic appending of UTM parameters to navigation links and the site logo.
  • Refactor

    • Improved UTM persistence and restoration logic for more reliable behavior across navigation and tabs.
    • Navbar and link handling updated to preserve UTMs for internal navigation.
  • Chores

    • Removed unused component imports from docs.
    • Removed extraneous debug logging and redundant comments.

✏️ Tip: You can customize this high-level summary in your review settings.

tentative fix on docs utm persistence
@github-actions
Copy link
Contributor

Dangerous URL check

No absolute URLs to prisma.io/docs found.
No local URLs found.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 12, 2025

Walkthrough

Adds a new client-side useUTMParams hook and wires UTM propagation into navbar links, nav items, and a new Theme Logo component; refactors UTM persistence logic; removes unused BorderBox imports from two MDX pages; and deletes a middleware debug log line.

Changes

Cohort / File(s) Summary
MDX import cleanup
content/300-accelerate/index.mdx, content/700-optimize/index.mdx
Removed BorderBox from @site/src/components/GettingStarted import lists.
New UTM hook
src/hooks/useUTMParams.ts
Adds export const useUTMParams(): string — reads sessionStorage.getItem('utm_params'), initializes state, refreshes on storage events and via periodic polling, and cleans up on unmount; returns the UTM string.
Navbar / NavLink / Logo updates
src/theme/NavbarItem/NavbarNavLink.tsx, src/theme/Navbar/Content/index.tsx, src/theme/Logo/index.tsx
Integrates useUTMParams; introduces helper to append UTM query string to internal URLs (preserves existing query separators and fragments); external links remain unchanged. Adds a new Logo component at src/theme/Logo/index.tsx that appends UTMs to its link and computes accessible alt text.
UTM persistence logic
src/utils/useUTMPersistenceDocs.ts
Consolidates UTM extraction and persistence: adds UTM_KEYS/STORAGE_KEY, replaces prior per-URL utilities, simplifies effect logic to persist/restore stored UTMs based on navigation, removes manual-removal branches and initial-skip behavior, and updates dependencies.
Middleware log removal
functions/_middleware.ts
Removed a debug console.log that printed fetched markdown path and content-type; request handling unchanged.
Layout minor cleanup
src/theme/Layout/index.tsx
Removed several comments and a retro-compatibility comment; no runtime behavior changes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Focus review on SSR/window-safety in useUTMParams and any components that call it (guards for window/sessionStorage).
  • Verify correct URL composition when appending UTMs: existing query strings, ? vs &, encoding, and hash/fragment preservation across NavbarNavLink, Navbar/Content, and Logo.
  • Inspect src/utils/useUTMPersistenceDocs.ts for edge cases: navigation detection, history.replace vs push usage, timing/race conditions from polling, and removal/restoration semantics.
  • Check Logo alt text/accessibility logic and correct forwarding of target/rel attributes.
  • Confirm the middleware log removal didn't remove important diagnostic behavior for other dev flows.

Possibly related PRs

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main objective: implementing a fix for UTM persistence (DR-6518). It directly reflects the substantial changes across multiple files for UTM parameter handling.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

@github-actions
Copy link
Contributor

Redirect check

This PR probably requires the following redirects to be added to static/_redirects:

  • This PR does not change any pages in a way that would require a redirect.

@carlagn carlagn changed the title Remove leftover code fix: DR-6518 UTM persistence Dec 12, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/theme/NavbarItem/NavbarNavLink.tsx (1)

38-55: Consider using the URL API for more robust parsing.

After fixing the hash fragment issue, you could further improve robustness by using the native URL API. This handles all edge cases automatically and is more maintainable.

Example refactor using URL API:

const appendUtmParams = (url: string): string => {
  if (!utmParams) {
    return url;
  }
  
  try {
    // URL API requires absolute URLs for parsing, so we use a base
    const urlObj = new URL(url, 'http://placeholder');
    
    // Append each UTM parameter
    const params = new URLSearchParams(utmParams);
    params.forEach((value, key) => {
      urlObj.searchParams.append(key, value);
    });
    
    // Return the pathname, search, and hash (without the placeholder origin)
    return `${urlObj.pathname}${urlObj.search}${urlObj.hash}`;
  } catch (e) {
    // Fallback to original URL if parsing fails
    return url;
  }
};

Note: This approach is more robust but requires that utmParams is in the format param1=value1&param2=value2.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f0ecc9f and 2b10b01.

📒 Files selected for processing (4)
  • content/300-accelerate/index.mdx (0 hunks)
  • content/700-optimize/index.mdx (0 hunks)
  • src/hooks/useUTMParams.ts (1 hunks)
  • src/theme/NavbarItem/NavbarNavLink.tsx (3 hunks)
💤 Files with no reviewable changes (2)
  • content/700-optimize/index.mdx
  • content/300-accelerate/index.mdx
🧰 Additional context used
🧬 Code graph analysis (1)
src/theme/NavbarItem/NavbarNavLink.tsx (1)
src/hooks/useUTMParams.ts (1)
  • useUTMParams (3-15)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Check internal links
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (3)
src/theme/NavbarItem/NavbarNavLink.tsx (3)

35-36: LGTM! Hook usage is correct.

The UTM parameters are correctly retrieved from the custom hook.


79-102: LGTM! External/internal link handling is correct.

The logic correctly differentiates between external and internal links, applying UTM parameters only to internal navigation. The use of prependBaseUrlToHref is handled appropriately.


104-119: LGTM! The 'to' prop handling is correct.

UTM parameters are correctly appended to the toUrl, and all navigation props are preserved appropriately.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Dec 15, 2025

Deploying docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: fc8bf26
Status: ✅  Deploy successful!
Preview URL: https://ea303d86.docs-51g.pages.dev
Branch Preview URL: https://fix-dr-6518-docs-utm-persist.docs-51g.pages.dev

View logs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/utils/useUTMPersistenceDocs.ts (1)

40-44: Pathname comparison logic appears incorrect.

The condition location.pathname === previousSearch.current.split('?')[0] will never work as intended. previousSearch.current stores location.search (e.g., "?utm_source=foo"), so splitting by '?' and taking index 0 yields an empty string—not the pathname.

Also, the console.log on line 43 should be removed before merging to production.

If the intent is to detect manual URL bar edits on the same page, you'd need to track the pathname separately:

 const previousSearch = useRef('');
+const previousPathname = useRef('');

 // ... inside useEffect, update both refs:
-previousSearch.current = location.search;
+previousSearch.current = location.search;
+previousPathname.current = location.pathname;

 // ... and fix the comparison:
-if (hadUTMs && !hasUTMs && location.pathname === previousSearch.current.split('?')[0]) {
+if (hadUTMs && !hasUTMs && location.pathname === previousPathname.current) {
♻️ Duplicate comments (1)
src/hooks/useUTMParams.ts (1)

9-12: Validate and sanitize stored UTM parameters.

The hook reads from sessionStorage without validation. If the stored value is malformed or tampered with, it could break URL construction or introduce injection risks downstream. A previous review flagged this same concern.

🧹 Nitpick comments (3)
src/utils/useUTMPersistenceDocs.ts (1)

52-54: Redundant ternary check.

On line 54, storedParams ? \?${storedParams}` : ''is inside a block that already guaranteesstoredParams` is truthy (line 53). The ternary is unnecessary.

-        const newSearch = storedParams ? `?${storedParams}` : '';
+        const newSearch = `?${storedParams}`;
src/theme/Navbar/Content/index.tsx (1)

70-75: Duplicated appendUtmParams helper.

This same helper function is defined identically in src/theme/Logo/index.tsx (lines 56-63). Consider extracting it to a shared utility—perhaps alongside useUTMParams or in src/utils/—to keep things DRY and ensure consistent behavior if the logic ever needs adjustment.

Example extraction to src/utils/utmHelpers.ts:

export const appendUtmParams = (url: string, utmParams: string): string => {
  if (!utmParams) return url;
  const separator = url.includes('?') ? '&' : '?';
  return `${url}${separator}${utmParams}`;
};

Then import and use in both components.

src/hooks/useUTMParams.ts (1)

27-33: Polling pattern has cleanup edge case and is somewhat heavy-handed.

Two concerns here:

  1. Memory leak potential: The setTimeout at line 31-33 captures the interval ID, but if the component unmounts before the 2-second timeout fires, the setTimeout callback still runs after cleanup—though harmless since clearInterval on an already-cleared ID is a no-op.

  2. Polling for 2s at 100ms is aggressive: This fires 20 times. Consider a lighter approach—perhaps a single requestIdleCallback or setTimeout retry pattern, or using a custom event dispatch from the persistence hook when it writes to sessionStorage (which would be synchronous and avoid polling entirely).

A cleaner same-tab sync approach—dispatch a custom event when writing:

// In useUTMPersistenceDocs.ts when setting:
sessionStorage.setItem('utm_params', utms);
window.dispatchEvent(new Event('utm_params_updated'));

// In useUTMParams.ts, listen for it:
window.addEventListener('utm_params_updated', updateUTMParams);

This eliminates polling entirely.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2b10b01 and 80a6667.

📒 Files selected for processing (4)
  • src/hooks/useUTMParams.ts (1 hunks)
  • src/theme/Logo/index.tsx (1 hunks)
  • src/theme/Navbar/Content/index.tsx (3 hunks)
  • src/utils/useUTMPersistenceDocs.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/utils/useUTMPersistenceDocs.ts (1)
src/theme/DocItem/Content/index.js (1)
  • location (30-30)
src/theme/Logo/index.tsx (1)
src/hooks/useUTMParams.ts (1)
  • useUTMParams (3-43)
src/theme/Navbar/Content/index.tsx (1)
src/hooks/useUTMParams.ts (1)
  • useUTMParams (3-43)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Check internal links
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (4)
src/utils/useUTMPersistenceDocs.ts (1)

30-31: LGTM on the refactor.

Extracting utms into an intermediate variable before storing is a clean, readable change. No functional difference, just slightly clearer intent.

src/theme/Navbar/Content/index.tsx (1)

62-62: UTM integration looks correct.

The hook usage and application to the docs link is straightforward and follows the established pattern. The separator logic correctly handles URLs with or without existing query parameters.

Also applies to: 85-85

src/theme/Logo/index.tsx (2)

43-63: Well-structured Logo component with UTM support.

The component cleanly integrates UTM persistence while preserving all standard Docusaurus logo behavior (themed images, alt text fallbacks, target forwarding). The appendUtmParams helper here is identical to the one in Navbar/Content/index.tsx—as noted there, extracting it to a shared utility would reduce duplication.


65-71: Alt text logic is thoughtfully handled.

Good attention to accessibility: when navbarTitle is visible, the logo gets an empty alt (decorative), otherwise it uses the site title. This follows WCAG guidance for avoiding redundant announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/utils/useUTMPersistenceDocs.ts (1)

36-43: Manual UTM removal detection condition can never be true

Right now previousSearch.current stores only location.search, but the detection uses:

if (hadUTMs && !hasUTMs && location.pathname === previousSearch.current.split('?')[0]) {

Since previousSearch.current is something like '?utm_source=…', previousSearch.current.split('?')[0] is always '', so this condition never matches and manual removals are never honored. That means users who delete UTMs from the URL will still have them auto-restored from sessionStorage.

Consider tracking the previous pathname separately (e.g., previousPathnameRef) or storing pathname + search together so you can accurately detect “same page, UTMs removed” and avoid re-applying them.

♻️ Duplicate comments (1)
src/theme/NavbarItem/NavbarNavLink.tsx (1)

35-52: Handle hash fragments when appending UTM params

The new appendUtmParams helper fixes the logging concern and centralizes the UTM logic, but it still doesn’t account for # fragments:

  • For a URL like /docs/guide#section, url.split('?') leaves the hash attached to baseUrl, so you end up with /docs/guide#section?utm_source=…, where the query appears after the fragment. In that form, the UTMs won’t be part of the actual URL query seen by the server or analytics.

To fix this robustly, split off the hash first, then work with the pre-fragment part, and finally reattach the hash:

-  const appendUtmParams = (url: string): string => {
-    if (!utmParams) {
-      return url;
-    }
-    
-    const [baseUrl, existingQuery] = url.split('?');
-    if (existingQuery) {
-      const result = `${baseUrl}?${existingQuery}&${utmParams}`;
-      return result;
-    } else {
-      const result = `${baseUrl}?${utmParams}`;
-      return result;
-    }
-  };
+  const appendUtmParams = (url: string): string => {
+    if (!utmParams) {
+      return url;
+    }
+
+    // Separate hash fragment so query params are always before '#'
+    const hashIndex = url.indexOf('#');
+    const hash = hashIndex !== -1 ? url.slice(hashIndex) : '';
+    const urlWithoutHash = hashIndex !== -1 ? url.slice(0, hashIndex) : url;
+
+    const [baseUrl, existingQuery] = urlWithoutHash.split('?');
+    const queryString = existingQuery
+      ? `${existingQuery}&${utmParams}`
+      : utmParams;
+
+    return `${baseUrl}?${queryString}${hash}`;
+  };

This will correctly handle href and to URLs that include fragments while preserving your new UTM behavior.

Also applies to: 88-91, 101-105

🧹 Nitpick comments (1)
src/utils/useUTMPersistenceDocs.ts (1)

30-31: Intermediate utms variable is fine but not strictly necessary

This refactor is behaviorally identical and clear; no issues from a persistence standpoint. You could inline getUTMParams(location.search) back into setItem if you prefer to keep the effect slightly more compact, but it’s purely stylistic.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 80a6667 and 64a0014.

📒 Files selected for processing (4)
  • functions/_middleware.ts (0 hunks)
  • src/hooks/useUTMParams.ts (1 hunks)
  • src/theme/NavbarItem/NavbarNavLink.tsx (3 hunks)
  • src/utils/useUTMPersistenceDocs.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • functions/_middleware.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/hooks/useUTMParams.ts
🧰 Additional context used
🧬 Code graph analysis (2)
src/utils/useUTMPersistenceDocs.ts (1)
src/theme/DocItem/Content/index.js (1)
  • location (30-30)
src/theme/NavbarItem/NavbarNavLink.tsx (1)
src/hooks/useUTMParams.ts (1)
  • useUTMParams (3-42)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Check internal links
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (1)
src/theme/NavbarItem/NavbarNavLink.tsx (1)

77-86: External links correctly bypass UTM augmentation

The early return for isExternalLink keeps external URLs untouched while still benefiting from the shared link content props. That keeps UTM behavior scoped to internal navigation, which is typically what you want for docs UTMs.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 15, 2025
ArthurGamby
ArthurGamby previously approved these changes Dec 15, 2025
@github-actions
Copy link
Contributor

🍈 Lychee Link Check Report

Note: Links are cached for 5 minutes. Failed links (timeouts, rate limits) are retried in a second run with longer timeout.

📊 Results Overview

Status Count
🔍 Total 2276
✅ Successful 2246
⏳ Timeouts 0
🔀 Redirected 4
👻 Excluded 24
❓ Unknown 0
🚫 Errors 1
⛔ Unsupported 1

Errors per input

Errors in 200-orm/050-overview/500-databases/840-cockroachdb.mdx

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/theme/NavbarItem/NavbarNavLink.tsx (1)

37-50: Hash fragments are still not handled correctly.

The appendUtmParams function splits only on ?, which breaks URLs containing hash fragments. For a URL like /docs/guide#section, the result would be /docs/guide#section?utm_source=x — query parameters must precede the fragment.

Apply this diff to properly handle hash fragments:

  const appendUtmParams = (url: string): string => {
    if (!utmParams) {
      return url;
    }
    
-   const [baseUrl, existingQuery] = url.split('?');
-   if (existingQuery) {
-     const result = `${baseUrl}?${existingQuery}&${utmParams}`;
-     return result;
-   } else {
-     const result = `${baseUrl}?${utmParams}`;
-     return result;
-   }
+   const hashIndex = url.indexOf('#');
+   const hash = hashIndex !== -1 ? url.slice(hashIndex) : '';
+   const urlWithoutHash = hashIndex !== -1 ? url.slice(0, hashIndex) : url;
+   
+   const [baseUrl, existingQuery] = urlWithoutHash.split('?');
+   const queryString = existingQuery ? `${existingQuery}&${utmParams}` : utmParams;
+   
+   return `${baseUrl}?${queryString}${hash}`;
  };
🧹 Nitpick comments (2)
src/utils/useUTMPersistenceDocs.ts (2)

74-82: Duplicated logic between handlePopState and handleHashChange.

The UTM check-and-clear logic is identical in both handlers. Extracting this into a helper function improves maintainability and reduces the risk of the two diverging over time.

+ const clearStoredUTMsIfNeeded = () => {
+   const currentHasUTMs = hasUTMParams(window.location.search);
+   const storedParams = sessionStorage.getItem('utm_params');
+   
+   if (!currentHasUTMs && storedParams) {
+     sessionStorage.removeItem('utm_params');
+     isManualRemoval.current = true;
+   }
+ };

  const handlePopState = () => {
-   setTimeout(() => {
-     const currentHasUTMs = hasUTMParams(window.location.search);
-     const storedParams = sessionStorage.getItem('utm_params');
-     
-     if (!currentHasUTMs && storedParams) {
-       sessionStorage.removeItem('utm_params');
-       isManualRemoval.current = true;
-     }
-   }, 50);
+   requestAnimationFrame(clearStoredUTMsIfNeeded);
  };

- const handleHashChange = () => {
-   const currentHasUTMs = hasUTMParams(window.location.search);
-   const storedParams = sessionStorage.getItem('utm_params');
-   
-   if (!currentHasUTMs && storedParams) {
-     sessionStorage.removeItem('utm_params');
-     isManualRemoval.current = true;
-   }
- };
+ const handleHashChange = clearStoredUTMsIfNeeded;

87-95: Multiple overlapping polling intervals for UTM state.

This 1000ms interval runs alongside the 500ms interval in useUTMParams (see src/hooks/useUTMParams.ts lines 22-23). Both are polling sessionStorage for UTM state changes. This creates:

  1. Extra CPU overhead from two separate timers
  2. Potential race conditions when both read/modify sessionStorage in close succession

Consider consolidating the polling logic into a single location, or using a shared event-based approach (e.g., dispatch a custom event when UTMs change) instead of multiple independent intervals.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 64a0014 and 76c4fc7.

📒 Files selected for processing (4)
  • src/hooks/useUTMParams.ts (1 hunks)
  • src/theme/Logo/index.tsx (1 hunks)
  • src/theme/NavbarItem/NavbarNavLink.tsx (3 hunks)
  • src/utils/useUTMPersistenceDocs.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/hooks/useUTMParams.ts
  • src/theme/Logo/index.tsx
🧰 Additional context used
🧬 Code graph analysis (2)
src/theme/NavbarItem/NavbarNavLink.tsx (1)
src/hooks/useUTMParams.ts (1)
  • useUTMParams (3-34)
src/utils/useUTMPersistenceDocs.ts (1)
src/theme/DocItem/Content/index.js (1)
  • location (30-30)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Check internal links
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (2)
src/theme/NavbarItem/NavbarNavLink.tsx (1)

74-93: Good separation of external vs internal link handling.

The logic correctly bypasses UTM appending for external links (line 74-81) while applying it to internal href-based links (lines 84-93). This is a sensible approach — UTM persistence is typically only relevant for internal navigation tracking.

src/utils/useUTMPersistenceDocs.ts (1)

45-56: UTM restoration replaces the entire query string.

When restoring UTMs (line 48), the logic constructs newSearch = ?${storedParams}, which means any other non-UTM query parameters that might have been in the URL will be lost. If this is intentional (only UTM params should persist), this is fine. If other query params should be preserved, this needs adjustment.

Is dropping non-UTM query parameters during restoration the intended behavior?

@github-actions
Copy link
Contributor

🍈 Lychee Link Check Report

Note: Links are cached for 5 minutes. Failed links (timeouts, rate limits) are retried in a second run with longer timeout.

📊 Results Overview

Status Count
🔍 Total 2276
✅ Successful 2243
⏳ Timeouts 0
🔀 Redirected 4
👻 Excluded 24
❓ Unknown 0
🚫 Errors 4
⛔ Unsupported 1

Errors per input

Errors in 200-orm/800-more/350-ai-tools/100-cursor.mdx

Errors in 800-guides/380-vercel-app-deployment.mdx

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/utils/useUTMPersistenceDocs.ts (1)

22-40: Excellent simplification that eliminates the previous race conditions.

This refactored approach is much cleaner than the previous version with intervals and multiple effects. The single-effect model with pathname tracking is easier to reason about. Let me walk through why it works:

  1. On initial landing with UTMs: currentUTMs is truthy → stored immediately
  2. On navigation without UTMs: isNavigation is true → UTMs restored via history.replace
  3. After the replace: Effect re-runs, now currentUTMs exists → re-stores (idempotent)
  4. Manual URL edit on same page: isNavigation is false → storage cleared appropriately

One small observation: history is used inside the effect but isn't listed in the dependency array. While Docusaurus's history object is stable across renders (so this works in practice), the exhaustive-deps lint rule would flag it. Consider adding it for completeness:

-  }, [location.pathname, location.search, location.hash]);
+  }, [history, location.pathname, location.search, location.hash]);

Also, the !currentUTMs check on line 35 is technically redundant since we're already in the else branch from if (currentUTMs), though it does improve readability by making the condition explicit.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 76c4fc7 and fc8bf26.

📒 Files selected for processing (2)
  • src/theme/Layout/index.tsx (0 hunks)
  • src/utils/useUTMPersistenceDocs.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • src/theme/Layout/index.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
src/utils/useUTMPersistenceDocs.ts (1)
src/theme/DocItem/Content/index.js (1)
  • location (30-30)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Check internal links
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (2)
src/utils/useUTMPersistenceDocs.ts (2)

4-5: Clean constant definitions with good type safety.

Using as const for UTM_KEYS ensures a readonly tuple type, and centralizing STORAGE_KEY prevents magic strings throughout the codebase. This is solid foundational work.


7-15: Well-structured utility function.

This is a clean, pure function that extracts only the relevant UTM parameters. The approach of building a fresh URLSearchParams ensures we don't carry over unrelated query params. Returns an empty string when no UTMs are present, which works nicely with JavaScript's falsy evaluation in the hook logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants