Uh oh!
There was an error while loading. Please reload this page.
feat: add Share button to package pages via Web Share API - #2997
feat: add Share button to package pages via Web Share API#2997tomayac wants to merge 11 commits into
Conversation
Adds a share button to the package header using navigator.share(), with a fallback to url/text-only sharing when the OG image can't be attached, plus a "v" keyboard shortcut and a command palette entry.
The latest updates on your projects. Learn more about Vercel for GitHub.
2 Skipped Deployments
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR adds native Web Share support for package pages through a client-only button and header actions. It exposes programmatic button clicks and adds translation, schema, and accessibility test updates. ChangesPackage Web Share feature
Sequence Diagram(s)sequenceDiagram
participant User
participant Header as Package/Header.vue
participant ShareButton as PackageShareButton
participant NavigatorShare as navigator.share
User->>Header: select package share action
Header->>Header: call sharePackage()
Header->>NavigatorShare: share package metadata and current URL
User->>ShareButton: click or press "v"
ShareButton->>ShareButton: build ShareData and optional image file
ShareButton->>NavigatorShare: share(shareData)
NavigatorShare-->>ShareButton: resolve or reject
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Lunaria Status Overview🌕 This pull request will trigger status changes. Learn moreBy default, every PR changing files present in the Lunaria configuration's You can change this by adding one of the keywords present in the Tracked Files
Warnings reference
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
app/components/Package/ShareButton.client.vue (2)
22-36: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winNo test coverage for share fallback logic.
getOgImageFile()andshare()contain the core fallback behaviour (capability probing, fetch failure handling, combined-payload gating) but no unit tests were added for this new logic.As per path instructions,
**/*.{test,spec}.{ts,tsx}should "Write unit tests for core functionality usingvitest"; this new share logic is a good candidate.🤖 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/components/Package/ShareButton.client.vue` around lines 22 - 36, Add unit tests for the share fallback behavior around getOgImageFile() and share() in ShareButton.client.vue, since the new capability probing, fetch/error handling, and combined-payload gating are not covered. Create vitest tests that exercise the main branches: navigator.canShare unavailable/false returns null, og:image missing or non-image content returns null, fetch failure is swallowed, and share() only includes the OG file when getOgImageFile() succeeds. Use the existing ShareButton.client.vue logic and its getOgImageFile/share symbols to locate the code.Source: Path instructions
57-57: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueSilently swallowing all share errors.
.catch(() => {})suppresses both expected cancellations (AbortError) and genuine failures. Consider only swallowingAbortErrorand logging other errors for observability.🤖 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/components/Package/ShareButton.client.vue` at line 57, The share flow in ShareButton.client.vue is swallowing every error from navigator.share, which hides real failures. Update the share handling around navigator.share(shareData) to only ignore expected AbortError cancellations, and route any other errors to the existing logging/observability path so genuine share failures can be diagnosed. Use the ShareButton component and its shareData/navigator.share call site to locate the change.
🤖 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/ShareButton.client.vue`:
- Around line 38-58: The package share payload is implemented inconsistently
between ShareButton.client.vue and Header.vue, so the command-palette share
action uses a less rich ShareData than the button and shortcut. Extract the
shared share flow into a common helper/composable such as usePackageShare() that
builds the title/text/url payload, optionally attaches the og:image file when
navigator.canShare allows it, and is reused by both share() and Header.vue's
sharePackage() so all entry points behave the same.
- Around line 10-20: The ShareButton.client.vue keyboard handler currently uses
a raw onKeyStroke, so the v shortcut ignores the global shortcuts toggle. Update
the shortcut registration in the ShareButton component to go through
useShortcuts(), matching the pattern used by Header.vue and other package
actions, and keep the existing isKeyWithoutModifiers / isEditableElement checks
and buttonRef click behavior intact.
---
Nitpick comments:
In `@app/components/Package/ShareButton.client.vue`:
- Around line 22-36: Add unit tests for the share fallback behavior around
getOgImageFile() and share() in ShareButton.client.vue, since the new capability
probing, fetch/error handling, and combined-payload gating are not covered.
Create vitest tests that exercise the main branches: navigator.canShare
unavailable/false returns null, og:image missing or non-image content returns
null, fetch failure is swallowed, and share() only includes the OG file when
getOgImageFile() succeeds. Use the existing ShareButton.client.vue logic and its
getOgImageFile/share symbols to locate the code.
- Line 57: The share flow in ShareButton.client.vue is swallowing every error
from navigator.share, which hides real failures. Update the share handling
around navigator.share(shareData) to only ignore expected AbortError
cancellations, and route any other errors to the existing logging/observability
path so genuine share failures can be diagnosed. Use the ShareButton component
and its shareData/navigator.share call site to locate the change.
🪄 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: 26b214ff-9bba-4cf5-875b-f3a1d72c6e10
📒 Files selected for processing (6)
app/components/Button/Base.vueapp/components/Package/Header.vueapp/components/Package/ShareButton.client.vuei18n/locales/en.jsoni18n/schema.jsontest/unit/a11y-component-coverage.spec.ts
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…ate PRs Per review feedback, keeps this PR focused on PWA installability, WCO, and app badging. The Share button and native switch polyfill now live in npmx-dev#2997 and npmx-dev#2998 respectively.
tomayac
commented
Aug 4, 2026
CC: @userquin per his request :-) |
chore: add spinner icon while sharing
We still need to add the I'm working on it. |
userquin
commented
Aug 27, 2026
I'm adding support to disable shorcut when shorcuts disabled at settings. |
| :classicon="sharing ? 'i-svg-spinners:ring-resize' : 'i-lucide:share-2'" | ||
| :aria-label="$t('package.share_aria_label', { package: packageName })" | ||
| :aria-keyshortcuts="'v'" | ||
| :ariaKeyshortcuts="keyboardShortcutsEnabled ? 'v' : undefined" |
There was a problem hiding this comment.
When I press Ctrl + click in my IDE (WebStorm) on :aria-keyshortcuts, it redirects to the DOM library, when it should redirect to the ariaKeyshortcuts prop of the Button component.
danielroe
commented
Aug 28, 2026
this is beautifully done my main worry is:
|
tomayac
commented
Aug 28, 2026
I work in DevRel, and I have this need constantly. People ask me all the time what package they should use for x, y, or z, and especially on the socials where the Share feature lets me share directly with apps on mobile. (The desktop share experience is more limited by default — but I use Shareful — on mobile it's amazing.) |
Summary
navigator.share(), attaching the package's OG image when the full payload (title/text/url/files) is confirmed shareable, falling back to url/text-only otherwise.vkeyboard shortcut and a command palette entry for sharing the current package.Split out of #2982 per review feedback to keep that PR focused on PWA/WCO/badging.
Test plan
pnpm test:unit— 1673/1673 passingpnpm run test:types— passingvp lint— 0 errorsnode scripts/find-invalid-translations.ts— no missing/unused i18n keysknip— clean