Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 31, 2025

External link icons were only appearing within <article> elements due to overly scoped CSS selectors. Additionally, MDX links in docs pages weren't rendering the icon because fumadocs doesn't pass through the data-external-link attribute.

Changes

  • Remove article scope from external link icon selectors in apps/www/app/globals.css for both light and dark modes
  • Add fallback CSS selectors to match external links based on rel="noopener" and target="_blank" attributes (used by fumadocs for MDX links)
  • Exclude image links with :not(:has(img)) to prevent icons on logo/image links

Before:

article a[data-external-link]:not(.fd-card):not([data-card]):not([class*="fd-"]):not([data-no-arrow]) {
  /* icon styles */
}

After:

a[data-external-link]:not(.fd-card):not([data-card]):not([class*="fd-"]):not([data-no-arrow]),
a[rel*="noopener"][target="_blank"]:not(.fd-card):not([data-card]):not([class*="fd-"]):not([data-no-arrow]):not(:has(img)) {
  /* icon styles */
}

Screenshots

Desktop:

Mobile (375×667):

The external link icon (↗) now appears consistently across:

  • Homepage footer ("ArkType ecosystem" link)
  • All docs pages (T3 Env, znv, envalid, dotenv-safe, etc.)
  • Both desktop and mobile viewports
Original prompt

This section details on the original issue you should resolve

<issue_title>External link icon isn't visible on mobile</issue_title>
<issue_description></issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Summary by CodeRabbit

  • Style
    • Switched external-link indicator to rely on standard anchor attributes rather than a custom attribute.
    • Added explicit exclusions for images, opt-out markers, certain utility classes and card elements to avoid unwanted indicators.
    • Adjusted indicator size, position and color for clearer visuals and applied the same behavior in dark mode for consistency.

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

@changeset-bot
Copy link

changeset-bot bot commented Dec 31, 2025

⚠️ No Changeset found

Latest commit: 14f6ba0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 31, 2025

Walkthrough

This change updates the external-link arrow styling in global CSS: it replaces the data-external-link trigger with selectors targeting a[rel*="noopener"][target="_blank"], adds exclusions (:not(:has(img)), [data-no-arrow], [class*="fd-"]), and introduces explicit background sizing/positioning.

Changes

Cohort / File(s) Summary
External Link Arrow Styling
apps/www/app/globals.css
Replaced article a[data-external-link] selector with a[rel*="noopener"][target="_blank"] (scoped/in article and .dark variants); added exclusions :not(:has(img)), [data-no-arrow], [class*="fd-"], [data-card] considerations; added background-size: 0.9em and background-position: center right; preserved padding/right background-image and adjusted dark-mode stroke color.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

docs

Poem

🐰 I hopped through CSS fields with delight,
Swapped attributes so the arrows take flight,
Sized and placed them snug, tucked out of sight,
Now links gleam clear in day and night. ✨

Pre-merge checks

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing external link icon visibility by updating CSS selectors to work on homepage and docs pages without the article scope restriction.
Linked Issues check ✅ Passed The PR addresses the linked issue #675 by updating CSS selectors to display external link icons on mobile and across docs pages using rel and target attributes as fallback triggers.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing external link icon visibility in apps/www/app/globals.css as required; no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 80102b4 and 14f6ba0.

📒 Files selected for processing (1)
  • apps/www/app/globals.css
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/www/app/globals.css
⏰ 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). (6)
  • GitHub Check: test-e2e (e2e)
  • GitHub Check: test-e2e (a11y)
  • GitHub Check: test-build (lts/*)
  • GitHub Check: test-typesafety
  • GitHub Check: test-build (latest)
  • GitHub Check: Deploy-Preview

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.

Copilot AI changed the title [WIP] Fix external link icon visibility on mobile Fix external link icon visibility outside article elements Dec 31, 2025
Copilot AI requested a review from yamcodes December 31, 2025 06:14
@yamcodes yamcodes marked this pull request as ready for review December 31, 2025 06:32
@github-actions github-actions bot added the www Improvements or additions to arkenv.js.org label Dec 31, 2025
@arkenv-bot
Copy link
Contributor

arkenv-bot bot commented Dec 31, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (Asia/Almaty)
arkenv Ready Ready Preview, Comment Dec 31 2025, 11:35 AM (Asia/Almaty)

@yamcodes
Copy link
Owner

That’s working well in the homepage but not in every docs page, for example I can’t find the external link icon in the “Comparison” page even though some of the links are external

@copilot

MDX links rendered by fumadocs don't pass through the data-external-link attribute, so add fallback CSS selectors to also match links with rel="noopener" and target="_blank" attributes. This ensures external link icons appear consistently across all external links in both homepage and docs pages.

Co-authored-by: yamcodes <[email protected]>
Copy link
Contributor Author

Copilot AI commented Dec 31, 2025

That’s working well in the homepage but not in every docs page, for example I can’t find the external link icon in the “Comparison” page even though some of the links are external

@copilot...

Fixed! External link icons now appear on all docs pages including the Comparison page.

The issue was that fumadocs doesn't pass through the data-external-link attribute to MDX links. Added fallback CSS selectors to also match links with rel="noopener" and target="_blank" attributes.

All external links (T3 Env, znv, envalid, etc.) now show the ↗ icon correctly on both desktop and mobile. ✅

📦 Commit: 8e407b1

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • fonts.googleapis.com
  • https://api.github.com/repos/yamcodes/arkenv

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Fix external link icon visibility outside article elements Fix external link icon visibility on homepage and docs pages Dec 31, 2025
@yamcodes
Copy link
Owner

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 31, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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)
apps/www/app/globals.css (1)

45-57: Inconsistent selector scoping causes external link icons to fail outside <article> elements.

The fallback selector (lines 48-51) is restricted to article elements, while the primary selector (lines 45-47) is not. This contradicts the PR objective of removing article scope and directly causes the user-reported issue where external link icons don't appear consistently across docs pages.

Additionally, the :not(:has(img)) exclusion is only applied to the fallback selector, not the primary selector, creating another inconsistency. For reference, the underline styling (lines 21-32) demonstrates the correct pattern by providing both scoped and unscoped variants.

🔎 Proposed fix to align both selectors
 /* External links in documentation */
 a[data-external-link]:not(.fd-card):not([data-card]):not([class*="fd-"]):not(
-		[data-no-arrow]
+		[data-no-arrow]
+	):not(:has(img)),
+a[rel*="noopener"][target="_blank"]:not(.fd-card):not([data-card]):not(
+		[class*="fd-"]
+	):not([data-no-arrow]):not(:has(img)),
+article
+	a[data-external-link]:not(.fd-card):not([data-card]):not([class*="fd-"]):not(
+		[data-no-arrow]
+	):not(:has(img)),
+article
+	a[rel*="noopener"][target="_blank"]:not(.fd-card):not([data-card]):not(
+		[class*="fd-"]
-	),
-article
-	a[rel*="noopener"][target="_blank"]:not(.fd-card):not([data-card]):not(
-		[class*="fd-"]
-	):not([data-no-arrow]):not(:has(img)) {
+	):not([data-no-arrow]):not(:has(img)) {
 	padding-right: 1.1em;
 	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23374151' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='7 7 17 7 17 17'%3E%3C/polyline%3E%3Cline x1='7' y1='17' x2='17' y2='7'%3E%3C/line%3E%3C/svg%3E");
 	background-repeat: no-repeat;
 	background-size: 0.9em;
 	background-position: center right;
 }

This provides both scoped (within article) and unscoped variants for each selector type, adds the missing :not(:has(img)) exclusion to all selectors, and follows the same pattern as the underline styling above.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a6c0927 and 80102b4.

📒 Files selected for processing (1)
  • apps/www/app/globals.css

Comment on lines 59 to 69
.dark
article
a[data-external-link]:not(.fd-card):not([data-card]):not([class*="fd-"]):not(
[data-no-arrow]
) {
),
.dark
article
a[rel*="noopener"][target="_blank"]:not(.fd-card):not([data-card]):not(
[class*="fd-"]
):not([data-no-arrow]):not(:has(img)) {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23d1d5db' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='7 7 17 7 17 17'%3E%3C/polyline%3E%3Cline x1='7' y1='17' x2='17' y2='7'%3E%3C/line%3E%3C/svg%3E");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Dark mode variant has the same selector scoping inconsistency.

The dark mode selectors exhibit the same issue as the light mode variant: the fallback selector is restricted to article elements while the primary selector is not, and the :not(:has(img)) exclusion is inconsistently applied.

🔎 Proposed fix to align dark mode selectors
 .dark
 	a[data-external-link]:not(.fd-card):not([data-card]):not([class*="fd-"]):not(
 		[data-no-arrow]
+	):not(:has(img)),
+.dark
+	a[rel*="noopener"][target="_blank"]:not(.fd-card):not([data-card]):not(
+		[class*="fd-"]
+	):not([data-no-arrow]):not(:has(img)),
+.dark
+	article
+	a[data-external-link]:not(.fd-card):not([data-card]):not([class*="fd-"]):not(
+		[data-no-arrow]
+	):not(:has(img)),
+.dark
+	article
+	a[rel*="noopener"][target="_blank"]:not(.fd-card):not([data-card]):not(
+		[class*="fd-"]
-	),
-.dark
-	article
-	a[rel*="noopener"][target="_blank"]:not(.fd-card):not([data-card]):not(
-		[class*="fd-"]
-	):not([data-no-arrow]):not(:has(img)) {
+	):not([data-no-arrow]):not(:has(img)) {
 	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23d1d5db' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='7 7 17 7 17 17'%3E%3C/polyline%3E%3Cline x1='7' y1='17' x2='17' y2='7'%3E%3C/line%3E%3C/svg%3E");
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/www/app/globals.css around lines 59 to 69, the dark-mode rule scoping is
inconsistent: the first selector targets a[data-external-link] globally while
the second is restricted to article and the :not(:has(img)) exclusion is only on
the second selector; update the dark variant so both selectors mirror each other
(same scoping and exclusions) — i.e., make the first selector also scoped to
article (or remove article from the second to match the first) and apply
:not(:has(img)) consistently to both selectors so both selectors have identical
structure and exclusions as the light-mode counterpart.

@yamcodes
Copy link
Owner

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 31, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@yamcodes yamcodes merged commit 3559ee0 into main Dec 31, 2025
14 of 15 checks passed
@yamcodes yamcodes deleted the copilot/fix-external-link-icon-mobile branch December 31, 2025 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

www Improvements or additions to arkenv.js.org

Projects

None yet

Development

Successfully merging this pull request may close these issues.

External link icon isn't visible on mobile

2 participants