EN | FR
A modern and adaptable Web Component that streamlines content sharing across all devices and platforms. It prioritizes the native Web Share API when available, while providing a polished and universal fallback experience. Lightweight, multilingual, and framework-independent.
-
🔗 Native Web Share API Support Uses the
navigator.share()
method when available, ideal for mobile and PWA contexts. -
🧭 Automatic Fallback
Gracefully falls back to a modern, touch-friendly modal when native sharing isn't supported. -
🎯 Share Metadata Detection
Automatically reads sharetitle
,text
, andurl
from attributes, the HTML document, or the web manifest. -
📧 Multi-Platform Sharing
Supports Email, SMS, X (Twitter), Facebook, WhatsApp, LinkedIn, Telegram, and Reddit. -
🚫 Per-Platform Disabling
Disable any platform using attributes likefacebook="false"
orsms="false"
.
-
🌐 Multilingual Support(
lang
)
Fully localized interface and ARIA labels, auto-detected or manually set via thelang
attribute. -
🦮 Keyboard & ARIA Support
Accessible modal with proper roles, focus trap, and keyboard navigation (Escape, Tab, Shift+Tab). -
📢 Assistive Feedback
Custom messages on copy success/failure, sharing errors, or initialization issues.
-
🖌 CSS Variables for Styling
Customize both button and modal via CSS custom properties (--bux-share-btn-*
,--bux-share-fallback-*
, etc.). -
🪄 Slot-Based Button Content
Add your own icon and/or label inside the main button using<slot name="icon">
. -
📱 Mobile Modal Animation
Mobile-first fallback with slide-up motion and swipe-to-dismiss support.
-
🧼 Optional Shadow DOM (
no-shadow
)
Renders in Shadow DOM by default; opt out to apply global styles more freely. -
🧩 Framework Agnostic
Works with any frontend framework (React, Vue, Angular, etc.) or plain HTML. -
📦 Lightweight and Tree-shakable
Zero dependencies. Only imports what you use, with TypeScript typings included. -
🧪 Typed and Modular
Built in TypeScript with typedSharePlatform
enums and exportable utilities (getShareIcon
,getBestIconUrl
).
The <browserux-share-button>
Web Component provides a seamless sharing experience by leveraging the Web Share API when available, and falling back to a fully featured, accessible modal on unsupported platforms.
When the user clicks the button:
- If
navigator.share()
is supported (typically mobile or PWA), it opens the native share sheet. - If not, it displays a custom modal fallback with share links and a copy-to-clipboard option.
The component automatically determines what to share:
- Title: from the
title
attribute,<title>
tag, or manifest. - Text: from the
text
attribute, meta description, or manifest. - URL: from the
url
attribute orlocation.href
.
This behavior ensures zero setup for simple cases, just drop the component in your HTML.
When fallback is triggered, the modal:
- Lists only the enabled platforms (email, X, WhatsApp, etc.).
- Displays a preview box with the app’s icon, title, and link.
- Allows users to copy the link with visual feedback (
"Link copied!"
). - Supports keyboard and touch navigation (Escape key, swipe-to-dismiss on mobile)
- The component auto-detects the UI language via the
lang
attribute or<html lang>
. - All labels and ARIA messages are translated (10+ languages supported).
- Modal and button are fully accessible (ARIA roles, keyboard navigation, focus trapping).
npm install browserux-share-button
Or via CDN:
<script type="module" src="https://unpkg.com/browserux-share-button/dist/browserux-share-button.min.js"></script>
Use the
.esm.js
build when integrating via a bundler (React, Vue, Angular, etc.), and the.min.js
version when using directly in HTML via a<script>
tag.
- Import the component globally in your main script:
import 'browserux-share-button';
- Then use it in your HTML:
<browserux-share-button
url="https://example.com"
text="Check this out!"
></browserux-share-button>
- Dynamically import the component inside a
useEffect
:
import { useEffect } from 'react';
useEffect(() => {
import('browserux-share-button');
}, []);
- Then use it in JSX as a regular HTML tag:
<browserux-share-button></browserux-share-button>
For JSX type support, you can manually create a
browserux-share-button.d.ts
typing file if needed.
- Import it globally in your main.js or main.ts:
import 'browserux-share-button';
- Use it like a native HTML element:
<browserux-share-button></browserux-share-button>
- Add the import to your
main.ts
:
import 'browserux-share-button';
- In
AppModule
, allow custom elements:
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule {}
- Load the script directly from a CDN:
<script type="module" src="https://unpkg.com/browserux-share-button/dist/browserux-share-button.min.js"></script>
- Use the tag wherever you want:
<browserux-share-button></browserux-share-button>
<browserux-share-button>
supports various customization options and integration features:
Parameter | Type | Name | Description |
---|---|---|---|
URL | Attribute | url |
The URL to share (default: current location.href ) |
Title | Attribute | title |
Title used in native and fallback share methods |
Text | Attribute | text |
Text snippet to accompany the shared link |
Language | Attribute | lang |
Forces the component language (en , fr , etc.) |
No Shadow DOM | Attribute | no-shadow |
Renders component without Shadow DOM |
Platform Disabling | Attribute | facebook="false" |
Disables specific platform in fallback UI |
Manifest Source | Attribute | manifest-src |
Custom path to web app manifest for metadata fallback |
Custom Labels | Data attr | data-label-* |
Override default labels (data-label-copy , etc.) |
Share Button icon | Slot | icon |
Customize Share Button icon |
By default, the <browserux-share-button>
component shares the current page's URL (location.href
).
However, you can override this behavior by explicitly setting a different URL using the url
attribute.
- Type:
string
(valid URL) - Default value:
location.href
- Effect: specifies the URL to be passed to the native Web Share API or fallback share links.
<browserux-share-button
url="https://example.com/page-to-share"
></browserux-share-button>
In this example, clicking the share button will share https://example.com/page-to-share
, regardless of the actual page URL.
This is useful for:
- Sharing a specific canonical or shortened URL
- Promoting a landing page from multiple contexts
- Testing different links without changing the page's location
Make sure the URL is publicly accessible and starts with https://
for best compatibility across social and native share services.
The title is used by some sharing platforms as a subject (e.g. email) or headline (e.g. Twitter/X or LinkedIn). By default, the component tries to extract the title from the current document or web app manifest.
- Type:
string
- Default value: from
<title>
tag or web manifest - Effect: provides a human-readable headline or subject in share payloads
<browserux-share-button
title="Check out this amazing article!"
></browserux-share-button>
In this case, platforms like email will use this as the subject line, and X/Twitter will include it as part of the tweet text.
If no title
is provided:
- The component checks the current page's
<title>
tag - If unavailable, it attempts to read the
name
field from the app manifest (if found) - If all fail, the title is omitted
Provide a custom title
if:
- The current page title is too generic
- You want to promote a specific message or product
- You’re sharing a page from within an app shell or embedded view
Tip: Combine
title
,text
, andurl
for best presentation across all platforms.
The text
attribute provides a message or summary accompanying the shared URL. This content is commonly used in messaging apps, social platforms, and even email bodies.
- Type:
string
- Default: fetched from the web manifest (
description
) or left blank - Effect: adds context to the share payload—especially useful when URLs alone aren't descriptive enough
<browserux-share-button
text="Here's a quick read I think you'll enjoy."
></browserux-share-button>
- Suggesting a reason to click or read the link
- Including promotional copy alongside the URL
- Describing the linked content more clearly
If no text
is defined:
- The component attempts to fetch the
description
field from the web manifest - If not available, it leaves the message portion empty in the share payload
Tip: Keep it concise and relevant to maximize click-through across platforms.
The lang
attribute controls which language is used for all built-in labels, ARIA descriptions, and fallback UI content.
- Type:
string
(e.g.,"en"
,"fr"
,"es"
,"de"
) - Default: derived from the component,
<html lang>
, or fallback toen
- Effect: adjusts internationalized content inside the component
<browserux-share-button lang="fr"></browserux-share-button>
In this example, all labels such as "Copy link" or error messages will appear in French.
- Explicit
lang
attribute on the component - Fallback to
<html lang>
- Fallback to
"en"
(English)
- English (
en
) - French (
fr
) - Spanish (
es
) - German (
de
) - Japanese (
ja
) - Russian (
ru
) - Portuguese (
pt
) - Italian (
it
) - Dutch (
nl
)
Tip: You can also override any label with
data-label-*
for custom copy regardless of language.
By default, the component uses Shadow DOM to encapsulate its styles and structure. You can disable this behavior by adding the no-shadow
attribute.
- Type:
boolean
(presence-only) - Effect: renders component content in the light DOM (no encapsulation)
<browserux-share-button no-shadow></browserux-share-button>
- You want to style the component via global CSS
- You use a framework that has limitations or bugs with Shadow DOM
- You prefer easier inspection/debugging in DevTools
⚠️ Disabling Shadow DOM makes the component more vulnerable to global style conflicts.
The <browserux-share-button>
component includes a fallback UI that shows sharing options for multiple platforms. If you want to hide specific platforms (e.g., those irrelevant to your audience or use case), you can disable them using a simple boolean attribute.
- Attribute name: matching the platform name
- Attribute value:
"false"
(as a string)
email
sms
x
facebook
whatsapp
linkedin
telegram
reddit
<browserux-share-button facebook="false" sms="false"></browserux-share-button>
By default, if you do not explicitly provide the title
or text
attributes, <browserux-share-button>
will try to load metadata from your web app's manifest file.
The component looks for:
name
→ used as the share titledescription
→ used as the share text
This enables automatic integration with existing PWA metadata.
- Type:
string
(valid URL path or absolute URL) - Default: uses
<link rel="manifest">
from the current page - Effect: overrides the manifest URL used to fetch metadata
<browserux-share-button
manifest-src="/custom-manifest.webmanifest"
></browserux-share-button>
- Your manifest file is not declared in the page header
- You want to load share metadata from a different file (e.g., per-page manifest)
- The default manifest path is incorrect or inaccessible
If no manifest-src
is defined:
- The component looks for a
<link rel="manifest">
in the<head>
- If found, it tries to fetch and parse it
- If this fails, the component continues with defaults or empty values
Tip: The manifest must be served with the correct MIME type (
application/manifest+json
) and must be accessible via CORS.html
You can override the component’s built-in labels (used for ARIA accessibility or fallback UI) using data-label-*
attributes. This is particularly helpful for localization, branding tone, or changing default behavior messages.
- Attribute name:
data-label-*
- Value: custom string (visible to screen readers or in the UI)
Attribute | Purpose |
---|---|
data-label-copy |
Text shown on the "Copy link" button |
data-label-copied |
Message shown briefly after copying success |
data-label-error-copy |
Error shown when clipboard copy fails |
data-label-error-init |
Warning shown if manifest or init fails |
data-label-error-share |
Message when navigator.share() throws an error |
<browserux-share-button
data-label-copy="Copier le lien"
data-label-copied="Lien copié !"
data-label-error-copy="Erreur lors de la copie"
data-label-error-init="Erreur lors de l'initialisation"
data-label-error-share="Échec du partage natif"
></browserux-share-button>
- To provide localized labels outside the default
lang
system - To customize tone or phrasing for your brand
- To replace fallback text with emojis or icons (e.g., ✅ Copied!)
Tip: These labels override those provided by
lang
, so they are useful for hybrid or multilingual apps.
npm install
npm run build
The project uses TypeScript and Rollup to generate build outputs:
dist/browserux-share-button.esm.js
dist/browserux-share-button.umd.js
dist/browserux-share-button.d.ts
dist/browserux-share-button.min.js
These builds are ready to be used in both module-based environments and traditional script loading contexts.
class ShareButton extends HTMLElement
│
├── 🔐 Private properties
│ ├── shareTitle: string
│ ├── shareText: string
│ ├── shareUrl: string
│ ├── root: ShadowRoot | HTMLElement
│ ├── labels: typeof I18N_LABELS[string]
│ ├── externalFallbackEl?: HTMLDivElement
│ └── focusTrapRemover?: () => void
│
├── 🛠️ Configuration & Utilities
│ ├── private isDisabled(platform: SharePlatform): boolean
│ └── private getShareConfig(platform: SharePlatform): { href: string; label: string; icon: string } | null
│
├── 🌐 Localization & Initialization
│ └── private onKeyDown = (e: KeyboardEvent): void
│
├── 🖼️ Main Button Rendering
│ └── private render(): void
│
├── 📱 Fallback Rendering (Modal)
│ ├── private renderExternalFallback(): void
│ ├── private renderPlatformLinks(container: HTMLElement): void
│ ├── private renderCopyButton(container: HTMLElement, initialCopyHtml: string): void
│ ├── private bindFallbackEvents(container: HTMLElement): void
│ └── private showFallback(): void
│
└── 🔄 Lifecycle
└── async connectedCallback(): Promise<void>
MIT License, Free to use, modify, and distribute.