Skip to content

Conversation

@essenmitsosse
Copy link
Contributor

@essenmitsosse essenmitsosse commented Feb 10, 2026

Currently all links in the readme are intercepted via JavaScript and if they go to npmjs.com redirected to npmx.dev. This has several problems, most of which stem from the fact, that the link in the URL is not the link we are going to.

This PR:

  • replaces the link in the generated HTML and removes the JavaScript handler (JavaScript handler is still needed for code copy button)
  • adds an indicator for external link (aligned with regular links)
  • aligns the link styling with regular links)

Good example readme: /package/is-odd

Screenshot 2026-02-10 at 15 25 23

@vercel
Copy link

vercel bot commented Feb 10, 2026

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

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Feb 10, 2026 5:04pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Feb 10, 2026 5:04pm
npmx-lunaria Ignored Ignored Feb 10, 2026 5:04pm

Request Review

@essenmitsosse essenmitsosse force-pushed the replace-links-in-markdown-text branch from 0dc35ee to e30cb04 Compare February 10, 2026 14:32
@essenmitsosse essenmitsosse changed the title Replace links in markdown text feat: replace links in markdown instead of via javascript Feb 10, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Updated Readme.vue to ignore clicks with modifier keys or non-primary buttons, expanded anchor handling to treat both hash (#...) and leading-slash (/...) hrefs as in-page or internal routes routed via router.push, and removed previous npmjs-to-internal-route mapping. Styling for README links was migrated to Tailwind @apply utilities, added :focus-visible rules and an external-link indicator for target="_blank". On the server, server/utils/readme.ts gained a reserved-path list and a helper to identify redirectable npmjs.com URLs; URL resolution now returns pathname+query+hash for those npmjs URLs. Unit tests for npmjs URL redirection were added.

Possibly related PRs

Suggested labels

idea

Suggested reviewers

  • danielroe
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description clearly explains the problem (links intercepted via JavaScript with URL mismatch issues) and describes the three main changes being implemented (link replacement in HTML, external link indicator, and link styling alignment).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@codecov
Copy link

codecov bot commented Feb 10, 2026

Codecov Report

❌ Patch coverage is 0% with 4 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
app/components/Readme.vue 0.00% 2 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

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

essenmitsosse and others added 4 commits February 10, 2026 15:44
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
essenmitsosse and others added 2 commits February 10, 2026 16:30
Co-authored-by: Alex Savelyev <91429106+alexdln@users.noreply.github.com>
alexdln
alexdln previously approved these changes Feb 10, 2026
@alexdln
Copy link
Contributor

alexdln commented Feb 10, 2026

@essenmitsosse Just remembered one more weird behavior with this "new tab" markers

image

@alexdln
Copy link
Contributor

alexdln commented Feb 10, 2026

@essenmitsosse It seems that if you specify for after: display: inline and content: "__" it will work well, but it needs to be tested

@essenmitsosse
Copy link
Contributor Author

@alexdln can't make it inline because, then the icon does not work. I don't think there is a robust solution that doesn't make the problem worse then it currently is.

@alexdln
Copy link
Contributor

alexdln commented Feb 10, 2026

@essenmitsosse Have you checked by adding content: "__" (2x "_")?

@alexdln
Copy link
Contributor

alexdln commented Feb 10, 2026

image

@danielroe
Copy link
Member

danielroe commented Feb 10, 2026

the JS handler will still be needed for client-side navigation, which will be more performant, but you can update it to check if window.location is the same as the href origin.

@essenmitsosse
Copy link
Contributor Author

the JS handler will still be needed for client-side navigation, which will be more performant, but you can update it to check if window.location is the same as the href origin.

@danielroe what do you mean by that? Why do we need a JS handler for client side navigation?

@danielroe
Copy link
Member

because nuxt doesn't listen to clicks on <a> elements, only on <NuxtLink>. so even though you are replacing the href, these links will result in a full refresh of the page, with a full server round trip

@essenmitsosse
Copy link
Contributor Author

@essenmitsosse Have you checked by adding content: "__" (2x "_")?

  1. now it works, I don't know why
  2. WHAT KIND OF SORCERY IS THIS???

@essenmitsosse
Copy link
Contributor Author

because nuxt doesn't listen to clicks on <a> elements, only on <NuxtLink>. so even though you are replacing the href, these links will result in a full refresh of the page, with a full server round trip

Aw shucks!

Co-authored-by: Alex Savelyev <91429106+alexdln@users.noreply.github.com>
@alexdln
Copy link
Contributor

alexdln commented Feb 10, 2026

No sorcery, just uno adds a mask with icon under the current container. And since you had an inline with no content, its width was 0. So you just needed to increase the width.

You can't use width for an inline, but you can use content that won't be visible and preferably won't interfere with the mask and not wrapping

@essenmitsosse
Copy link
Contributor Author

No sorcery, just uno adds a mask with icon under the current container. And since you had an inline with no content, its width was 0. So you just needed to increase the width.

You can't use width for an inline, but you can use content that won't be visible and preferably won't interfere with the mask and not wrapping

If that is not sorcery, what is then. 😂 But glad it works!

@essenmitsosse
Copy link
Contributor Author

because nuxt doesn't listen to clicks on <a> elements, only on <NuxtLink>. so even though you are replacing the href, these links will result in a full refresh of the page, with a full server round trip

@danielroe

I also added a check for modifier keys, so CTRL + click for new tab works as expected, which it didn't before.

Co-authored-by: Daniel Roe <daniel@roe.dev>
@danielroe danielroe added this pull request to the merge queue Feb 10, 2026
Merged via the queue into npmx-dev:main with commit e782462 Feb 10, 2026
17 checks passed
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