Skip to content

feat: support npmjs versions redirect#2800

Open
johnnyreilly wants to merge 2 commits into
npmx-dev:mainfrom
johnnyreilly:redirect-verions
Open

feat: support npmjs versions redirect#2800
johnnyreilly wants to merge 2 commits into
npmx-dev:mainfrom
johnnyreilly:redirect-verions

Conversation

@johnnyreilly
Copy link
Copy Markdown
Contributor

🔗 Linked issue

Resolves #2781

🧭 Context

There's a good level of intentional URL compatibility between npmjs.com and npmx.dev. The idea being that if you swapped out the prefix you'd see the same feature on npmx.dev that you see on npmjs.com

This doesn't apply for versions. So if you go to:
https://www.npmjs.com/package/webpack?activeTab=versions

Then go to
https://www.npmx.dev/package/webpack?activeTab=versions

You do not see a versions view. However, a versions view does exist:
https://npmx.dev/package/webpack/versions

📚 Description

This PR changes npmx.dev such that https://www.npmx.dev/package/webpack?activeTab=versions would be 301'd to https://npmx.dev/package/webpack/versions

This means that users swapping the prefix will see the versions view. The URL is a redirect, but that seems appropriate given there isn't a "tab" for versions in npmx

cc @gameroman

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 26, 2026

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

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment May 26, 2026 10:01am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview May 26, 2026 10:01am
npmx-lunaria Ignored Ignored May 26, 2026 10:01am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9c57c93c-7ed2-48dc-8006-4cb2a04e071c

📥 Commits

Reviewing files that changed from the base of the PR and between 0b4b070 and 18e6258.

📒 Files selected for processing (1)
  • test/e2e/url-compatibility.spec.ts

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Improved URL canonicalisation for package pages: navigating with the activeTab=versions query parameter now redirects to the cleaner /package/.../versions URL, removes the activeTab parameter, and preserves other query parameters.
  • Tests

    • Added end-to-end tests verifying ?activeTab=versions redirects to the /versions route and displays the Version History heading.

Walkthrough

Middleware now canonicalises package URLs with ?activeTab=versions by redirecting to /package/{name}/versions, preserving other query parameters and setting cache headers. E2E tests confirm redirects for both scoped and unscoped packages and that the versions page renders the expected heading.

Changes

activeTab=versions URL canonicalisation

Layer / File(s) Summary
activeTab=versions redirect implementation
server/middleware/canonical-redirects.global.ts
Middleware parses incoming request path and query, detects activeTab=versions on /package/... URLs, removes the activeTab parameter, sets cache-control headers, and issues a 301 redirect to the canonical /package/${name}/versions path with remaining query parameters preserved. The existing getRouteRules early-return guard is repositioned to execute after this new redirect logic.
E2E tests for activeTab=versions redirects
test/e2e/url-compatibility.spec.ts
New test suite validates that navigating to /package/vue?activeTab=versions and /package/@nuxt/kit?activeTab=versions correctly redirects to the corresponding /versions paths and renders the expected package heading for both scoped and unscoped packages.
🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive The PR partially addresses the linked issue by implementing a redirect mechanism, but does not fully implement the requested feature of displaying per-version download counts. Clarify whether the redirect alone meets the feature request or if additional work is needed to display per-version downloads inline as originally requested in #2781.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: support npmjs versions redirect' clearly and concisely describes the main change: adding a redirect to support npmjs-style version tab URLs.
Description check ✅ Passed The description provides context and reasoning for the change, explaining the URL compatibility goal and the specific redirect being implemented.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing the versions tab redirect and its corresponding tests; no unrelated modifications detected.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
test/e2e/url-compatibility.spec.ts (1)

123-140: ⚡ Quick win

Consider adding a test case for query parameter preservation.

The middleware preserves non-activeTab query parameters when redirecting (e.g., /package/vue?activeTab=versions&foo=bar/package/vue/versions?foo=bar). Adding a test case for this behaviour would improve coverage and catch potential regressions.

✅ Example test case for query param preservation
test('/package/vue?activeTab=versions&utm_source=test → preserves other params', async ({
  page,
  goto,
}) => {
  await goto('/package/vue?activeTab=versions&utm_source=test', {
    waitUntil: 'domcontentloaded',
  })

  await expect(page).toHaveURL(/\/package\/vue\/versions\?utm_source=test$/)
  await expect(page.locator('h1')).toContainText('vue')
})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/e2e/url-compatibility.spec.ts` around lines 123 - 140, Add a new E2E
test in the existing describe block that verifies the middleware preserves
non-activeTab query params when redirecting: create a test similar to the
existing tests (e.g., titled "/package/vue?activeTab=versions&utm_source=test →
preserves other params") that uses the same helpers (test, goto, page, expect)
to navigate with goto('/package/vue?activeTab=versions&utm_source=test', {
waitUntil: 'domcontentloaded' }), assert the final URL matches
/\/package\/vue\/versions\?utm_source=test$/ with expect(page).toHaveURL(...),
and confirm the page renders correctly with
expect(page.locator('h1')).toContainText('vue'); place it alongside the other
tests in the "npmjs.com activeTab=versions Compatibility" describe block so it
runs with the existing suite.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/e2e/url-compatibility.spec.ts`:
- Around line 123-140: Add a new E2E test in the existing describe block that
verifies the middleware preserves non-activeTab query params when redirecting:
create a test similar to the existing tests (e.g., titled
"/package/vue?activeTab=versions&utm_source=test → preserves other params") that
uses the same helpers (test, goto, page, expect) to navigate with
goto('/package/vue?activeTab=versions&utm_source=test', { waitUntil:
'domcontentloaded' }), assert the final URL matches
/\/package\/vue\/versions\?utm_source=test$/ with expect(page).toHaveURL(...),
and confirm the page renders correctly with
expect(page.locator('h1')).toContainText('vue'); place it alongside the other
tests in the "npmjs.com activeTab=versions Compatibility" describe block so it
runs with the existing suite.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1dd00a97-a700-4535-aaa0-1f0b93134bcd

📥 Commits

Reviewing files that changed from the base of the PR and between db64da9 and 0b4b070.

📒 Files selected for processing (2)
  • server/middleware/canonical-redirects.global.ts
  • test/e2e/url-compatibility.spec.ts

@gameroman gameroman added the needs review This PR is waiting for a review from a maintainer label May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs review This PR is waiting for a review from a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Downloads by package version

2 participants