Lightweight social sharing component for web applications. Zero dependencies, framework-agnostic.
- 🌐 Multiple platforms: WhatsApp, Facebook, X, LinkedIn, Telegram, Reddit, Email
- 🎯 Zero dependencies - pure vanilla JavaScript
- ⚛️ Framework support: React, Next.js, Vue, Angular, or plain HTML
- 🔄 Auto-detects current URL and page title
- 📱 Fully responsive and mobile-ready
- 🎨 Customizable themes (dark/light)
- ⚡ Lightweight (< 10KB gzipped)
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.css">
<script src="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.js"></script>🚫 IMPORTANT: Do NOT create new files like
ShareButton.jsxorShareButton.tsx!
✅ Add code directly to your existing component (Header, Navbar, etc.)
📦 Create React App
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.css">
</head>
<body>
<div id="root"></div>
<script src="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.js"></script>
</body>Step 2: In your existing React component (e.g., MainLayout.jsx, Header.jsx, or wherever you want the button):
import { useEffect, useRef } from 'react';
function YourComponent() { // Use your actual component name (Header, Navbar, etc.)
const shareButtonRef = useRef(null);
const initRef = useRef(false);
useEffect(() => {
if (initRef.current || !window.SocialShareButton) return;
shareButtonRef.current = new window.SocialShareButton({
container: '#share-button'
});
initRef.current = true;
return () => {
if (shareButtonRef.current?.destroy) {
shareButtonRef.current.destroy();
}
initRef.current = false;
};
}, []);
return (
<header>
<div id="share-button"></div>
</header>
);
}▲ Next.js (App Router)
import Script from 'next/script';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.css"
/>
</head>
<body>
{children}
<Script
src="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.js"
strategy="beforeInteractive"
/>
</body>
</html>
);
}Step 2: In your existing React component (e.g., MainLayout.jsx, Header.jsx, or wherever you want the button):
'use client';
import { useEffect, useRef } from 'react';
export default function YourComponent() { // Use your actual component name
const shareButtonRef = useRef<any>(null);
const containerRef = useRef<HTMLDivElement>(null);
const initRef = useRef(false);
useEffect(() => {
const initButton = () => {
if (initRef.current || !window.SocialShareButton || !containerRef.current) return;
shareButtonRef.current = new window.SocialShareButton({
container: '#share-button'
});
initRef.current = true;
};
if (window.SocialShareButton) {
initButton();
} else {
const checkInterval = setInterval(() => {
if (window.SocialShareButton) {
clearInterval(checkInterval);
initButton();
}
}, 100);
return () => {
clearInterval(checkInterval);
if (shareButtonRef.current?.destroy) {
shareButtonRef.current.destroy();
}
initRef.current = false;
};
}
return () => {
if (shareButtonRef.current?.destroy) {
shareButtonRef.current.destroy();
}
initRef.current = false;
};
}, []);
return (
<header>
<div id="share-button" ref={containerRef}></div>
</header>
);
}
declare global {
interface Window {
SocialShareButton: any;
}
}📄 Next.js (Pages Router)
import { Html, Head, Main, NextScript } from 'next/document';
export default function Document() {
return (
<Html>
<Head>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.css"
/>
</Head>
<body>
<Main />
<NextScript />
<script src="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.js"></script>
</body>
</Html>
);
}import { useEffect, useRef } from 'react';
export default function YourComponent() { // Use your actual component name
const shareButtonRef = useRef<any>(null);
const containerRef = useRef<HTMLDivElement>(null);
const initRef = useRef(false);
useEffect(() => {
const initButton = () => {
if (initRef.current || !window.SocialShareButton || !containerRef.current) return;
shareButtonRef.current = new window.SocialShareButton({
container: '#share-button'
});
initRef.current = true;
};
if (window.SocialShareButton) {
initButton();
} else {
const checkInterval = setInterval(() => {
if (window.SocialShareButton) {
clearInterval(checkInterval);
initButton();
}
}, 100);
return () => {
clearInterval(checkInterval);
if (shareButtonRef.current?.destroy) {
shareButtonRef.current.destroy();
}
initRef.current = false;
};
}
return () => {
if (shareButtonRef.current?.destroy) {
shareButtonRef.current.destroy();
}
initRef.current = false;
};
}, []);
return (
<header>
<div id="share-button" ref={containerRef}></div>
</header>
);
}
declare global {
interface Window {
SocialShareButton: any;
}
}⚡ Vite / Vue / Angular
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.css">
</head>
<body>
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@v1.0.3/src/social-share-button.js"></script>
</body>new window.SocialShareButton({
container: '#share-button'
});new SocialShareButton({
container: '#share-button', // Required: CSS selector or DOM element
url: 'https://example.com', // Optional: defaults to window.location.href
title: 'Custom Title', // Optional: defaults to document.title
buttonText: 'Share', // Optional: button label text
buttonStyle: 'primary', // default | primary | compact | icon-only
theme: 'dark', // dark | light
platforms: ['twitter', 'linkedin'] // Optional: defaults to all platforms
});| Option | Type | Default | Description |
|---|---|---|---|
container |
string/Element | - | Required. CSS selector or DOM element |
url |
string | window.location.href |
URL to share |
title |
string | document.title |
Share title/headline |
description |
string | '' |
Additional description text |
hashtags |
array | [] |
Hashtags for posts (e.g., ['js', 'webdev']) |
via |
string | '' |
Twitter handle (without @) |
platforms |
array | All platforms | Platforms to show (see below) |
buttonText |
string | 'Share' |
Button label text |
buttonStyle |
string | 'default' |
default, primary, compact, icon-only |
buttonColor |
string | '' |
Custom button background color |
buttonHoverColor |
string | '' |
Custom button hover color |
customClass |
string | '' |
Additional CSS class for button |
theme |
string | 'dark' |
dark or light |
modalPosition |
string | 'center' |
Modal position on screen |
showButton |
boolean | true |
Show/hide the share button |
onShare |
function | null |
Callback when user shares: (platform, url) => {} |
onCopy |
function | null |
Callback when user copies link: (url) => {} |
Available Platforms:
whatsapp, facebook, twitter, linkedin, telegram, reddit, email
Control the text that appears when users share to social platforms:
new SocialShareButton({
container: '#share-button',
url: 'https://myproject.com',
title: 'Check out my awesome project!', // Main title/headline
description: 'An amazing tool for developers', // Additional description
hashtags: ['javascript', 'webdev', 'opensource'], // Hashtags included in posts
via: 'MyProjectHandle' // Your Twitter handle
});How messages are customized per platform:
- WhatsApp:
title+description+hashtags+ link - Facebook:
title+description+hashtags+ link - Twitter/X:
title+description+hashtags+viahandle + link - Telegram:
title+description+hashtags+ link - LinkedIn:
title+description+ link - Reddit:
title-description(used as title) - Email: Subject =
title, Body =description+ link
Option 1: Use Pre-built Styles (Easiest)
new SocialShareButton({
container: '#share-button',
buttonStyle: 'primary' // or 'default', 'compact', 'icon-only'
});Option 2: Programmatic Color Customization (Recommended)
Pass buttonColor and buttonHoverColor to match your project's color scheme:
new SocialShareButton({
container: '#share-button',
buttonColor: '#ff6b6b', // Button background color
buttonHoverColor: '#ff5252' // Hover state color
});Option 3: CSS Class Customization (Advanced)
For more complex styling, use a custom CSS class:
new SocialShareButton({
container: '#share-button',
buttonStyle: 'primary',
customClass: 'my-custom-button'
});Then in your CSS file:
/* Override the button background color */
.my-custom-button.social-share-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
/* Customize hover state */
.my-custom-button.social-share-btn:hover {
background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
}Color Examples:
// Material Design Red
new SocialShareButton({
container: '#share-button',
buttonColor: '#f44336',
buttonHoverColor: '#da190b'
});
// Tailwind Blue
new SocialShareButton({
container: '#share-button',
buttonColor: '#3b82f6',
buttonHoverColor: '#2563eb'
});
// Custom Brand Color
new SocialShareButton({
container: '#share-button',
buttonColor: '#your-brand-color',
buttonHoverColor: '#your-brand-color-dark'
});| Style | Description |
|---|---|
default |
Standard button with icon and text |
primary |
Gradient button (recommended) |
compact |
Smaller size for tight spaces |
icon-only |
Icon without text |
new SocialShareButton({
container: '#share-button',
onShare: (platform, url) => {
console.log(`Shared on ${platform}: ${url}`);
},
onCopy: (url) => {
console.log('Link copied:', url);
}
});import SocialShareButton from 'social-share-button-aossie';
import 'social-share-button-aossie/src/social-share-button.css';
new SocialShareButton({
container: '#share-button'
});If you want a reusable React component, copy src/social-share-button-react.jsx to your project:
import { SocialShareButton } from './components/SocialShareButton';
function App() {
return <SocialShareButton platforms={['twitter', 'linkedin']} />;
}const shareButton = useRef(null);
useEffect(() => {
shareButton.current = new window.SocialShareButton({
container: '#share-button'
});
}, []);
useEffect(() => {
if (shareButton.current) {
shareButton.current.updateOptions({
url: window.location.href
});
}
}, [pathname]); // Update on route changeMultiple buttons appearing
Cause: Component re-renders creating duplicate instances
Solution: Use useRef to track initialization (already in examples above)
Button not appearing
Cause: Script loads after component renders
Solution: Add null check:
if (window.SocialShareButton) {
new window.SocialShareButton({ container: '#share-button' });
}Modal not opening
Cause: CSS not loaded or ID mismatch
Solution:
- Verify CSS CDN link in
<head> - Match container ID:
container: '#share-button'=<div id="share-button">
TypeError: SocialShareButton is not a constructor
Cause: CDN script not loaded yet
Solution: Use interval polling (see Next.js example above)
URL not updating on navigation
Cause: Component initialized once, doesn't track routes
Solution: Use updateOptions() method (see Advanced Usage above)
<nav>
<div id="share-button"></div>
</nav>// Professional networks only
new SocialShareButton({
container: '#share-button',
platforms: ['linkedin', 'twitter', 'email']
});
// Messaging apps only
new SocialShareButton({
container: '#share-button',
platforms: ['whatsapp', 'telegram']
});new SocialShareButton({
container: '#share-button',
buttonStyle: 'icon-only',
theme: 'light'
});Open index.html in your browser to see all features.
Tutorial: https://youtu.be/cLJaT-8rEvQ?si=CLipA0Db4WL0EqKM
We welcome contributions of all kinds! To contribute:
- Fork the repository and create your feature branch (
git checkout -b feature/AmazingFeature). - Commit your changes (
git commit -m 'Add some AmazingFeature'). - Test your changes by opening
index.htmlin your browser to verify functionality. - Push your branch (
git push origin feature/AmazingFeature). - Open a Pull Request for review.
If you encounter bugs, need help, or have feature requests:
- Please open an issue in this repository providing detailed information.
- Describe the problem clearly and include any relevant logs or screenshots.
We appreciate your feedback and contributions!
This project is licensed under the GNU General Public License v3.0. See the LICENSE file for details.