Skip to content

Conversation

@thesmithdao
Copy link
Collaborator

@thesmithdao thesmithdao commented Oct 8, 2025

Summary

  • Instrument LocalizedLink trigger the Addressable Pixel conversion event.
  • Forward any provided onClick, open app links in a new tab
  • Updated TypeScript config to exclude auxiliary scripts from compilation.

Acceptance

  • Successfully tested at Addressable dashboard.
image

Output:

  },
  "server_timestamp": 1759944953,
  "headers": {
    "accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
    "accept-encoding": "gzip, deflate, br, zstd",
    "accept-language": "en-US,en;q=0.9",
    "Host": "tag.adrsbl.io",
    "priority": "i",
    "referer": "https://shapeshift-mkt-git-addrsbl-pixel-v2-defismith.vercel.app/",
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
    "X-Forwarded-Port": "443",
    "X-Forwarded-Proto": "https"
  },
  "is_conversion": "true"
}

Summary by CodeRabbit

  • Enhancements

    • Link component accepts string or object URLs, preserves pathname/query/hash, and applies language prefixes for internal links.
    • External app links are reliably opened in a new tab with analytics tracking and respect user-provided click handlers.
    • Link behavior and external-detection are more consistent across different URL shapes.
  • Chores

    • Build config updated to exclude additional script files; no public API changes.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 8, 2025

📝 Walkthrough

Walkthrough

Preserves UrlObject href parts and reconstructs absolute URLs; distinguishes anchors/mailto/tel/external/non-root links; prefixes language for internal root links; adds app.shapeshift.com click path that calls global __adrsbl and opens in a new tab with router fallback; centralizes click handling; excludes scripts in tsconfig.

Changes

Cohort / File(s) Summary of Changes
Link localization & click handling
app/[lang]/_components/LocalizedLink.tsx
Accepts string and UrlObject hrefs; preserves pathname, query, hash; adds fullUrlFromObj to assemble absolute URLs; refactors external/link-avoidance logic to handle both string and object hrefs; prepends language for internal root links and returns a UrlObject when input was an object; adds isAppLink detection for app.shapeshift.com, invokes global __adrsbl if present, opens window.open(fullUrl, "_blank") with router.push fallback; introduces unified handleClick preserving user onClick; updates TLocalizedLinkProps to omit href from anchor attributes; retains displayName.
Build configuration
tsconfig.json
Adds scripts to exclude alongside node_modules and .next.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant LocalizedLink
  participant Router
  participant Window
  participant Analytics as "__adrsbl"

  User->>LocalizedLink: click(href, event)
  alt anchor / mailto / tel / external / non-root internal
    LocalizedLink->>LocalizedLink: call user onClick (if any)
    Note right of LocalizedLink: allow default/browser behavior (no client routing)
  else host == app.shapeshift.com
    LocalizedLink->>LocalizedLink: build fullUrl (from string or UrlObject)
    LocalizedLink->>Analytics: invoke __adrsbl() (optional)
    Analytics-->>LocalizedLink: return
    LocalizedLink->>Window: window.open(fullUrl, "_blank")
    alt open blocked / error
      LocalizedLink->>Router: router.push(fullUrl) (fallback)
    end
  else internal root-relative
    LocalizedLink->>LocalizedLink: normalize href (prepend lang, preserve query/hash)
    LocalizedLink->>Router: router.push(localized href)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

A rabbit hops through links and keys,
I stitch path, query, hash with ease.
For app links I tap the watcher bell,
A new tab springs where trackers dwell.
Language stitched — the routes now please. 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "fire pixel on app clicks" directly and specifically addresses the primary objective of this pull request: instrumenting the LocalizedLink component to trigger the Addressable Pixel conversion event when app links are clicked. The title is concise, clear, and avoids vague terminology while accurately conveying the main change without needing to cover secondary changes like the tsconfig updates, which is appropriate for a PR title. A teammate scanning commit history would immediately understand that this PR adds pixel-firing functionality to app link clicks.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9f0f42e and fbd41eb.

📒 Files selected for processing (1)
  • app/[lang]/_components/LocalizedLink.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/[lang]/_components/LocalizedLink.tsx

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 29665de and 905db99.

📒 Files selected for processing (2)
  • app/[lang]/_components/LocalizedLink.tsx (1 hunks)
  • tsconfig.json (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-02T02:04:59.408Z
Learnt from: thesmithdao
PR: shapeshift/website-frontend#66
File: app/[lang]/page.tsx:262-296
Timestamp: 2025-09-02T02:04:59.408Z
Learning: User thesmithdao prefers to avoid refactoring to LocalizedLink components for landing info cards in app/[lang]/page.tsx, preferring to keep the implementation clean with plain anchor tags.

Applied to files:

  • app/[lang]/_components/LocalizedLink.tsx
🧬 Code graph analysis (1)
app/[lang]/_components/LocalizedLink.tsx (1)
app/[lang]/_utils/i18nconfig.ts (2)
  • getLanguageFromPath (59-64)
  • DEFAULT_LANGUAGE (52-52)

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)
app/[lang]/_components/LocalizedLink.tsx (1)

93-101: Previous critical issue resolved; consider minor optimization.

The past issue with UrlObject navigation has been correctly fixed—both window.open and the fallback window.location.assign now use fullUrlFromObj(hrefObj) to generate the complete absolute URL. Well done!

Minor optimization: the absolute URL is computed twice (lines 93-95 and line 98). You could compute it once before the outer try block to reduce duplication:

 			}
 			e.preventDefault()
+			const absolute = hrefObj
+				? fullUrlFromObj(hrefObj)
+				: hrefString || (typeof href === 'string' ? href : '')
 			try {
-				const absolute = hrefObj
-					? fullUrlFromObj(hrefObj)
-					: hrefString || (typeof href === 'string' ? href : '')
 				window.open(absolute, '_blank', 'noopener,noreferrer')
 			} catch {
-				const absolute = hrefObj ? fullUrlFromObj(hrefObj) : hrefString
 				if (absolute) {
 					window.location.assign(absolute)
 				}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 905db99 and 1e90018.

📒 Files selected for processing (1)
  • app/[lang]/_components/LocalizedLink.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: thesmithdao
PR: shapeshift/website-frontend#66
File: app/[lang]/page.tsx:262-296
Timestamp: 2025-09-02T02:04:59.408Z
Learning: User thesmithdao prefers to avoid refactoring to LocalizedLink components for landing info cards in app/[lang]/page.tsx, preferring to keep the implementation clean with plain anchor tags.
📚 Learning: 2025-09-02T02:04:59.408Z
Learnt from: thesmithdao
PR: shapeshift/website-frontend#66
File: app/[lang]/page.tsx:262-296
Timestamp: 2025-09-02T02:04:59.408Z
Learning: User thesmithdao prefers to avoid refactoring to LocalizedLink components for landing info cards in app/[lang]/page.tsx, preferring to keep the implementation clean with plain anchor tags.

Applied to files:

  • app/[lang]/_components/LocalizedLink.tsx
🧬 Code graph analysis (1)
app/[lang]/_components/LocalizedLink.tsx (1)
app/[lang]/_utils/i18nconfig.ts (2)
  • getLanguageFromPath (59-64)
  • DEFAULT_LANGUAGE (52-52)
🔇 Additional comments (3)
app/[lang]/_components/LocalizedLink.tsx (3)

48-57: Verify undefined/null query parameter handling.

When a query parameter value is undefined or null, line 56 appends an empty string (e.g., ?key=). Confirm this is the intended behavior—typically, such values are omitted from query strings entirely. If omission is preferred, remove the else clause:

 					for (const [k, v] of Object.entries(obj.query as Record<string, unknown>)) {
 						if (Array.isArray(v)) {
 							for (const item of v) {
 								params.append(k, String(item))
 							}
 						} else if (v !== undefined && v !== null) {
 							params.append(k, String(v))
-						} else {
-							params.append(k, '')
 						}
 					}

109-130: LGTM: External link detection is comprehensive.

The logic correctly identifies external links, anchors, mailto, tel, and non-root paths, bypassing localization for these cases. The conditional onClick on line 126 properly applies handleClick only for app links while preserving the original onClick for other external links.


132-145: LGTM: Localization preserves URL structure correctly.

The localization logic correctly:

  • Detects existing language prefixes (line 133)
  • Prepends the current language only when needed and not default (lines 138-140)
  • Preserves UrlObject properties (query, hash) by returning a modified UrlObject (lines 142-144) instead of stringifying

This ensures Next.js Link receives the appropriate href format and all URL components are maintained.

Copy link
Member

@0xApotheosis 0xApotheosis left a comment

Choose a reason for hiding this comment

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

Both internal and external links seem to be working as expected. Some minor tweaks requested.

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

🧹 Nitpick comments (1)
app/[lang]/_components/LocalizedLink.tsx (1)

93-103: Simplify the fallback chain for consistency.

Line 96 includes a redundant fallback (typeof href === 'string' ? href : '') since hrefString is already set to href when it's a string (line 33). The catch block (line 99) doesn't include this fallback, creating an inconsistency.

Consider simplifying line 96 to match line 99:

 			try {
-				const absolute = hrefObj
-					? fullUrlFromObj(hrefObj)
-					: hrefString || (typeof href === 'string' ? href : '')
+				const absolute = hrefObj ? fullUrlFromObj(hrefObj) : hrefString
 				window.open(absolute, '_blank', 'noopener,noreferrer')
 			} catch {
 				const absolute = hrefObj ? fullUrlFromObj(hrefObj) : hrefString
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1e90018 and c3a80ae.

📒 Files selected for processing (1)
  • app/[lang]/_components/LocalizedLink.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: thesmithdao
PR: shapeshift/website-frontend#66
File: app/[lang]/page.tsx:262-296
Timestamp: 2025-09-02T02:04:59.408Z
Learning: User thesmithdao prefers to avoid refactoring to LocalizedLink components for landing info cards in app/[lang]/page.tsx, preferring to keep the implementation clean with plain anchor tags.
📚 Learning: 2025-09-02T02:04:59.408Z
Learnt from: thesmithdao
PR: shapeshift/website-frontend#66
File: app/[lang]/page.tsx:262-296
Timestamp: 2025-09-02T02:04:59.408Z
Learning: User thesmithdao prefers to avoid refactoring to LocalizedLink components for landing info cards in app/[lang]/page.tsx, preferring to keep the implementation clean with plain anchor tags.

Applied to files:

  • app/[lang]/_components/LocalizedLink.tsx
🧬 Code graph analysis (1)
app/[lang]/_components/LocalizedLink.tsx (1)
app/[lang]/_utils/i18nconfig.ts (2)
  • getLanguageFromPath (59-64)
  • DEFAULT_LANGUAGE (52-52)
🔇 Additional comments (4)
app/[lang]/_components/LocalizedLink.tsx (4)

70-80: LGTM! App link detection is comprehensive.

The detection logic correctly handles both string hrefs and UrlObject with host information. The regex pattern appropriately matches app.shapeshift.com links with case-insensitive matching.


105-107: LGTM! onClick propagation is handled correctly.

The user-provided onClick handler is properly forwarded after the analytics and navigation logic, ensuring compatibility with existing click handlers.


110-131: LGTM! External link handling is well-structured.

The logic correctly identifies external links (including anchors, mailto, tel, and UrlObject with host/protocol) and bypasses localization for them. The conditional onClick on line 127 ensures app links get the analytics + new-tab behavior while other external links retain their original click handlers.


133-146: LGTM! Localization logic correctly preserves UrlObject structure.

The implementation properly:

  • Detects existing language prefixes to avoid double-prefixing
  • Only adds language prefix when not using the default language
  • Preserves the original type (string or UrlObject) which maintains query and hash parameters

Based on coding guidelines (relevant_code_snippets show DEFAULT_LANGUAGE and getLanguageFromPath usage).

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c3a80ae and bfed48e.

📒 Files selected for processing (1)
  • app/[lang]/_components/LocalizedLink.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: thesmithdao
PR: shapeshift/website-frontend#66
File: app/[lang]/page.tsx:262-296
Timestamp: 2025-09-02T02:04:59.408Z
Learning: User thesmithdao prefers to avoid refactoring to LocalizedLink components for landing info cards in app/[lang]/page.tsx, preferring to keep the implementation clean with plain anchor tags.
📚 Learning: 2025-09-02T02:04:59.408Z
Learnt from: thesmithdao
PR: shapeshift/website-frontend#66
File: app/[lang]/page.tsx:262-296
Timestamp: 2025-09-02T02:04:59.408Z
Learning: User thesmithdao prefers to avoid refactoring to LocalizedLink components for landing info cards in app/[lang]/page.tsx, preferring to keep the implementation clean with plain anchor tags.

Applied to files:

  • app/[lang]/_components/LocalizedLink.tsx
🧬 Code graph analysis (1)
app/[lang]/_components/LocalizedLink.tsx (1)
app/[lang]/_utils/i18nconfig.ts (2)
  • getLanguageFromPath (59-64)
  • DEFAULT_LANGUAGE (52-52)
🔇 Additional comments (8)
app/[lang]/_components/LocalizedLink.tsx (8)

13-14: LGTM!

The ESLint disable and global declaration are appropriate for integrating with the Addressable pixel library.


16-19: LGTM!

The type definition properly combines Next.js Link props with standard anchor attributes.


24-33: LGTM!

The component properly supports both string and UrlObject hrefs, extracting the pathname for processing while preserving the original object structure.


75-85: LGTM!

The app link detection correctly handles both string and UrlObject hrefs with appropriate pattern matching.


110-112: Verify onClick propagation behavior is intentional.

When isAppLink is true, the handler calls preventDefault() and opens the link in a new tab, but still invokes the original onClick afterward. Confirm this is the intended behavior, as users might expect their onClick to control navigation. If the onClick is meant only for side effects (e.g., analytics), this is fine; otherwise, consider calling onClick before preventDefault() to allow it to cancel the action.


115-136: LGTM!

The external link detection correctly handles both string patterns (http, #, mailto, tel, non-root paths) and UrlObject indicators (host, hostname, protocol), ensuring only internal root paths are localized.


138-151: LGTM!

The language prefix logic correctly handles both string and UrlObject hrefs, preserving query and hash parameters when returning a UrlObject for localized internal links.


153-165: LGTM!

The final return properly renders the localized link with all props forwarded, and the displayName is set for debugging.

@thesmithdao thesmithdao changed the title chore: click_app event / fire pixel on app clicks chore: fire pixel on app clicks Oct 11, 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: 0

♻️ Duplicate comments (1)
app/[lang]/_components/LocalizedLink.tsx (1)

96-100: Add guard to prevent opening blank tab for empty hrefs.

If hrefObj, hrefString, and href are all empty or falsy, the computed absolute will be an empty string, and window.open('', '_blank', 'noopener,noreferrer') will open about:blank. Consider adding an early return or validation.

Apply this diff:

 		const absolute = hrefObj
 			? fullUrlFromObj(hrefObj)
 			: hrefString || (typeof href === 'string' ? href : '')
+		if (!absolute) return
 		try {
 			window.open(absolute, '_blank', 'noopener,noreferrer')
🧹 Nitpick comments (2)
app/[lang]/_components/LocalizedLink.tsx (2)

49-49: Remove redundant type assertion.

The type assertion as string is unnecessary here since the typeof obj.query === 'string' check on line 47 already narrows the type to string.

Apply this diff:

-					const raw = obj.query as string
+					const raw = obj.query

136-136: Consider using getLanguageFromPath for more accurate language detection.

The current regex /^\/([a-z]{2})(\/|$)/ matches any two-letter prefix, which means paths like /ab/test (where ab isn't a supported language) will be treated as already localized and won't get the language prepended. Using the existing getLanguageFromPath utility would validate against SUPPORTED_LANGUAGES and be more robust.

Apply this diff:

-		const hasLanguagePrefix = hrefString.match(/^\/([a-z]{2})(\/|$)/)
+		const hasLanguagePrefix = !!getLanguageFromPath(hrefString)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2faf556 and 20a5b98.

📒 Files selected for processing (2)
  • app/[lang]/_components/LocalizedLink.tsx (1 hunks)
  • tsconfig.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tsconfig.json
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: thesmithdao
PR: shapeshift/website-frontend#66
File: app/[lang]/page.tsx:262-296
Timestamp: 2025-09-02T02:04:59.408Z
Learning: User thesmithdao prefers to avoid refactoring to LocalizedLink components for landing info cards in app/[lang]/page.tsx, preferring to keep the implementation clean with plain anchor tags.
📚 Learning: 2025-09-02T02:04:59.408Z
Learnt from: thesmithdao
PR: shapeshift/website-frontend#66
File: app/[lang]/page.tsx:262-296
Timestamp: 2025-09-02T02:04:59.408Z
Learning: User thesmithdao prefers to avoid refactoring to LocalizedLink components for landing info cards in app/[lang]/page.tsx, preferring to keep the implementation clean with plain anchor tags.

Applied to files:

  • app/[lang]/_components/LocalizedLink.tsx
🧬 Code graph analysis (1)
app/[lang]/_components/LocalizedLink.tsx (1)
app/[lang]/_utils/i18nconfig.ts (2)
  • getLanguageFromPath (59-64)
  • DEFAULT_LANGUAGE (52-52)
🔇 Additional comments (3)
app/[lang]/_components/LocalizedLink.tsx (3)

19-20: Verify if content is missing near these lines.

Past review comments indicate that line 19 had a "useful comment" that was removed and then "restored," but no comment is visible on line 19 in the current code. Additionally, line 20 has an unresolved question asking if it "is still removed." Please verify whether any content is missing here due to line number shifts or incomplete restoration.


85-110: Good implementation of analytics integration and new-tab behavior.

The handleClick function properly triggers the Addressable pixel, opens app links in a new tab with fallback handling, and correctly forwards custom onClick handlers. The defensive try-catch around the third-party __adrsbl call is appropriate.


145-148: Well done preserving UrlObject structure.

Returning a UrlObject with the updated pathname when the original href was a UrlObject ensures that query parameters and hash fragments are preserved correctly. This maintains type consistency and proper URL semantics.

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fadd75f and 4d1dc0e.

📒 Files selected for processing (1)
  • app/[lang]/_components/LocalizedLink.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-02T02:04:59.408Z
Learnt from: thesmithdao
PR: shapeshift/website-frontend#66
File: app/[lang]/page.tsx:262-296
Timestamp: 2025-09-02T02:04:59.408Z
Learning: User thesmithdao prefers to avoid refactoring to LocalizedLink components for landing info cards in app/[lang]/page.tsx, preferring to keep the implementation clean with plain anchor tags.

Applied to files:

  • app/[lang]/_components/LocalizedLink.tsx
🧬 Code graph analysis (1)
app/[lang]/_components/LocalizedLink.tsx (1)
app/[lang]/_utils/i18nconfig.ts (2)
  • getLanguageFromPath (59-64)
  • DEFAULT_LANGUAGE (52-52)
🔇 Additional comments (4)
app/[lang]/_components/LocalizedLink.tsx (4)

40-76: Well-structured URL reconstruction helper.

The fullUrlFromObj function correctly handles both string and object-form queries (as addressed in previous review), properly serializes query parameters, and gracefully handles missing values. The logic is comprehensive and defensive.


78-88: App link detection works correctly for both string and UrlObject hrefs.

The isAppLink logic correctly identifies app.shapeshift.com links regardless of whether href is a string or UrlObject, ensuring the pixel fires consistently.


141-154: Localization logic preserves UrlObject structure correctly.

The code correctly checks for existing language prefixes, only adds the language when appropriate, and importantly preserves the original UrlObject structure (query, hash) when the input was a UrlObject. This ensures no data loss during localization.


118-129: Relative path skipping in LocalizedLink is intentional behavior—no action needed.

Line 126's check (!hrefString.startsWith('/')) correctly treats relative paths as non-localized. This is by design: the component is built for absolute paths and external URLs. Your codebase usage across 100+ instances confirms this—all hrefs are absolute paths like /blog, /chains/bitcoin, or external URLs. The defensive check prevents accidental misuse. The JSDoc explicitly states the component "automatically prepends the current language to internal links"—implying only absolute paths are intended inputs.

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: 4

🧹 Nitpick comments (1)
app/[lang]/_components/LocalizedLink.tsx (1)

148-156: Progressive enhancement: add target/rel on app links.

Set target="_blank" and rel="noopener noreferrer" so links still open in a new tab without JS; security attributes are explicit.

Apply:

 			return (
 				<Link
 					href={href}
 					ref={ref}
 					{...props}
+					target={isAppLink ? '_blank' : props.target}
+					rel={isAppLink ? 'noopener noreferrer' : props.rel}
 					onClick={isAppLink ? handleClick : onClick}>
 					{children}
 				</Link>
 			)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4d1dc0e and 9f0f42e.

📒 Files selected for processing (1)
  • app/[lang]/_components/LocalizedLink.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-02T02:04:59.408Z
Learnt from: thesmithdao
PR: shapeshift/website-frontend#66
File: app/[lang]/page.tsx:262-296
Timestamp: 2025-09-02T02:04:59.408Z
Learning: User thesmithdao prefers to avoid refactoring to LocalizedLink components for landing info cards in app/[lang]/page.tsx, preferring to keep the implementation clean with plain anchor tags.

Applied to files:

  • app/[lang]/_components/LocalizedLink.tsx
🧬 Code graph analysis (1)
app/[lang]/_components/LocalizedLink.tsx (1)
app/[lang]/_utils/i18nconfig.ts (2)
  • getLanguageFromPath (59-64)
  • DEFAULT_LANGUAGE (52-52)

Copy link
Member

@0xApotheosis 0xApotheosis left a comment

Choose a reason for hiding this comment

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

This breaks some external links: https://jam.dev/c/f74d605d-5df2-4853-a3fa-451dcf782acb

E.g. clicking "Get Started" or "Launch App" now opens a new tab and redirects the current tab to the new URL.

@thesmithdao thesmithdao marked this pull request as draft October 28, 2025 16:55
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.

2 participants