Skip to content

feat(ui): add easy way to copy package version#3044

Open
WilhelmBerggren wants to merge 2 commits into
npmx-dev:mainfrom
WilhelmBerggren:wilhelm/copy-version
Open

feat(ui): add easy way to copy package version#3044
WilhelmBerggren wants to merge 2 commits into
npmx-dev:mainfrom
WilhelmBerggren:wilhelm/copy-version

Conversation

@WilhelmBerggren

@WilhelmBerggren WilhelmBerggren commented Jul 15, 2026

Copy link
Copy Markdown

🔗 Linked issue

Resolves #2646 (but of course more could be done)

🧭 Context

The linked issue describes the desire to have a quick way to copy the version number. Right now there is a quick way to copy the package name or an install command, but not the version number alone.

📚 Description

This PR adds a version number in the Header with a copy button and an entry in the command palette when viewing the /package/<name>/v/<version> route

Base /package/nuxt (no change):
image

Show version in header on /package/nuxt/v/4.4.8 (new):

Screen.Recording.2026-07-15.at.15.40.53.mov

Copy package version visible in command palette while on /package/nuxt/v/4.4.8:
image

Disclosure: I did use Claude Code to help write part of the code in this PR

@vercel

vercel Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Jul 22, 2026 7:07pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Jul 22, 2026 7:07pm
npmx-lunaria Ignored Ignored Jul 22, 2026 7:07pm

Request Review

@github-actions

Copy link
Copy Markdown

Hello! Thank you for opening your first PR to npmx, @WilhelmBerggren! 🚀

Here’s what will happen next:

  1. Our GitHub bots will run to check your changes.
    If they spot any issues you will see some error messages on this PR.
    Don’t hesitate to ask any questions if you’re not sure what these mean!

  2. In a few minutes, you’ll be able to see a preview of your changes on Vercel

  3. One or more of our maintainers will take a look and may ask you to make changes.
    We try to be responsive, but don’t worry if this takes a few days.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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

Changes

Package version copying

Layer / File(s) Summary
Route parameter normalisation
app/composables/usePackageRoute.ts, test/nuxt/composables/use-package-route.spec.ts
Route parameters are normalised across package-related route patterns, including docs catch-all paths and diff version ranges, with coverage for package, organisation, and requested-version values.
Header version display and copying
app/components/Package/Header.vue, i18n/locales/en.json, i18n/schema.json, test/nuxt/components/Package/Header.spec.ts, test/e2e/interactions.spec.ts
The header displays and copies resolved versions when a version is requested, adds a command-palette copy action and translation key, and updates component and end-to-end coverage for the revised copy-button structure.

Sequence Diagram(s)

sequenceDiagram
  participant PackageHeader
  participant CopyToClipboardButton
  participant useClipboard
  participant ClipboardAPI
  CopyToClipboardButton->>useClipboard: Invoke copyPkgVersion
  PackageHeader->>useClipboard: Invoke copyPkgVersion from context command
  useClipboard->>ClipboardAPI: Copy resolvedVersion
  ClipboardAPI-->>useClipboard: Update copiedPkgVersion
Loading

Possibly related PRs

  • npmx-dev/npmx.dev#3056: Modifies the same header behaviour with resolved-version clipboard actions and related translations.
  • npmx-dev/npmx.dev#2701: Updates the package header copy-button rendering and corresponding end-to-end hover behaviour.
  • npmx-dev/npmx.dev#2997: Extends the package header’s command-palette actions in the same wiring area.

Suggested reviewers: ghostdevv

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: adding an easy way to copy the package version.
Description check ✅ Passed The description is directly related to the changes, describing the new version copy UI and command palette entry.
Linked Issues check ✅ Passed The PR satisfies #2646 by adding version copying and making the version more visible in the header.
Out of Scope Changes check ✅ Passed The changes stay focused on version display/copying and supporting route/test/i18n updates.
✨ 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.

@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

File Note
i18n/locales/en.json Source changed, localizations will be marked as outdated.
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@app/components/Terminal/Install.vue`:
- Around line 142-152: Conditionally register the `package-copy-version` command
only when an explicitly requested package version exists. Update the command
array construction around the visible command definition, following the existing
pattern for conditional commands, so `copyPkgVersion()` and its clipboard
announcement are unavailable when no version was requested.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b4ea07ff-5ece-4d47-8c49-b0865523a985

📥 Commits

Reviewing files that changed from the base of the PR and between 5bbce3e and fbf13b2.

📒 Files selected for processing (7)
  • app/components/Package/Header.vue
  • app/components/Terminal/Install.vue
  • app/composables/useInstallCommand.ts
  • i18n/locales/en.json
  • i18n/schema.json
  • test/nuxt/components/Package/Header.spec.ts
  • test/nuxt/composables/use-install-command.spec.ts

Comment thread app/components/Terminal/Install.vue Outdated
@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 53.84615% with 12 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
app/composables/usePackageRoute.ts 63.15% 0 Missing and 7 partials ⚠️
app/components/Package/Header.vue 28.57% 2 Missing and 3 partials ⚠️

📢 Thoughts on this report? Let us know!

@gameroman gameroman left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hi, thanks for the PR

Could you add a screenshot or a video to the PR description, please, so it's easier to see the change visually

@WilhelmBerggren

Copy link
Copy Markdown
Author

Hi, thanks for the PR

Could you add a screenshot or a video to the PR description, please, so it's easier to see the change visually

Of course! Added to the description now.

@ghostdevv ghostdevv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

hey, ty for the PR and coming to the meetup in Berlin!

One weird thing I noticed was that on some of the tabs the version disappears. E.g.

for example, it's visible for example, it's gone
Image Image

Show version in header on /package/nuxt/v/4.4.8 (new):

Weirdly we had this before, but it was removed in #2030 - but I think it's safe to assume that was a mistake

Comment thread app/components/Package/Header.vue Outdated
Comment on lines +240 to +242
<LinkBase :to="packageRoute(packageName, resolvedVersion)" class="text-fg-muted">
{{ resolvedVersion }}
</LinkBase>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How come this is a link?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Just personal preference, but I can't really justify it. Removed!

Comment thread app/components/Terminal/Install.vue Outdated
Comment on lines +143 to +144
if (props.requestedVersion) {
commands.push({

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I wonder if this should go in the header so it's usable on other tabs aside from the main one where this is rendered

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Agreed, that makes more sense!

// Copy state
// Copy state — separate clipboard instances so copying the version does not
// flip the install command's copied indicator (and vice versa).
const { copied, copy } = useClipboard({ copiedDuring: 2000 })

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should probably rename these variables too, and then we can remove the comment above

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

After adding the command via the Header directly no changes were needed in this file, removing the need for this workaround.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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.

Inline comments:
In `@app/components/Package/Header.vue`:
- Around line 106-116: Gate the `package-copy-version` command in the command
list using the same condition as the title version control: require both
`requestedVersion` and `resolvedVersion` to be present. Keep the existing
`copyPkgVersion` action unchanged once the condition is satisfied.

In `@app/composables/usePackageRoute.ts`:
- Around line 24-31: Update the route parsing around vIndex, nameSegments, and
version to determine the unscoped or scoped package prefix first, then recognize
v only when it is the segment immediately following that prefix. Treat
/package-docs/v as having no package version marker, and preserve later v
segments as part of the remaining route rather than interpreting them as the
version delimiter.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1d9e9c7a-d520-4958-b791-ba55e2f015a1

📥 Commits

Reviewing files that changed from the base of the PR and between 2446ac9 and cdd432b.

📒 Files selected for processing (7)
  • app/components/Package/Header.vue
  • app/composables/usePackageRoute.ts
  • i18n/locales/en.json
  • i18n/schema.json
  • test/e2e/interactions.spec.ts
  • test/nuxt/components/Package/Header.spec.ts
  • test/nuxt/composables/use-package-route.spec.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • i18n/locales/en.json
  • test/e2e/interactions.spec.ts
  • i18n/schema.json

Comment thread app/components/Package/Header.vue
Comment thread app/composables/usePackageRoute.ts
@WilhelmBerggren

Copy link
Copy Markdown
Author

hey, ty for the PR and coming to the meetup in Berlin!

One weird thing I noticed was that on some of the tabs the version disappears. E.g.
for example, it's visible for example, it's gone
Image Image

Show version in header on /package/nuxt/v/4.4.8 (new):

Weirdly we had this before, but it was removed in #2030 - but I think it's safe to assume that was a mistake

Hey Willow! Thank you, it was great to meet you in Berlin :)

The reason the version wasn't showing on other tabs was because the usePackageRoute hook only looked at the /package routes. I expanded it to resolve for all tabs (first commit).

After your suggestions the PR is much more straightforward!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
app/composables/usePackageRoute.ts (1)

33-36: 🎯 Functional Correctness | 🟠 Major

Stop the docs version at the first segment.

For /package-docs/nuxt/v/4.2.0/api, this joins the page slug into requestedVersion as 4.2.0/api, causing downstream version lookups to receive an invalid version. Use only segments[prefixLength + 1]; subsequent segments belong to the docs route.

Suggested fix
       const version =
         segments[prefixLength] === 'v' && segments.length > prefixLength + 1
-          ? segments.slice(prefixLength + 1).join('/')
+          ? segments[prefixLength + 1]
           : null

Add a regression test for /package-docs/nuxt/v/4.2.0/api.

🤖 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 `@app/composables/usePackageRoute.ts` around lines 33 - 36, Update the version
extraction in the route parsing logic to use only segments[prefixLength + 1]
when the v marker and version segment are present, rather than joining
subsequent segments. Keep later path segments available as the docs route, and
add a regression test covering /package-docs/nuxt/v/4.2.0/api.
🤖 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.

Duplicate comments:
In `@app/composables/usePackageRoute.ts`:
- Around line 33-36: Update the version extraction in the route parsing logic to
use only segments[prefixLength + 1] when the v marker and version segment are
present, rather than joining subsequent segments. Keep later path segments
available as the docs route, and add a regression test covering
/package-docs/nuxt/v/4.2.0/api.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d685b6a0-5d36-46ec-8b2b-f2cabe801c7f

📥 Commits

Reviewing files that changed from the base of the PR and between cdd432b and b6fe2fe.

📒 Files selected for processing (7)
  • app/components/Package/Header.vue
  • app/composables/usePackageRoute.ts
  • i18n/locales/en.json
  • i18n/schema.json
  • test/e2e/interactions.spec.ts
  • test/nuxt/components/Package/Header.spec.ts
  • test/nuxt/composables/use-package-route.spec.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • i18n/schema.json
  • test/nuxt/composables/use-package-route.spec.ts
  • i18n/locales/en.json
  • test/e2e/interactions.spec.ts
  • app/components/Package/Header.vue
  • test/nuxt/components/Package/Header.spec.ts

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.

A quick way to copy package version

4 participants