Skip to content

Commit 6895348

Browse files
authored
Merge pull request #149 from hiranya25/feature/add-discord-support
feat: add discord support
2 parents d0686c4 + 65b9b07 commit 6895348

6 files changed

Lines changed: 73 additions & 57 deletions

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ Lightweight social sharing component for web applications. Zero dependencies, fr
7171

7272
## Features
7373

74-
- 🌐 Multiple platforms: WhatsApp, Facebook, X, LinkedIn, Telegram, Reddit, Email, Pinterest
74+
- 🌐 Multiple platforms: WhatsApp, Facebook, X, LinkedIn, Telegram, Reddit, Email, Pinterest, Discord
7575
- 🎯 Zero dependencies - pure vanilla JavaScript
7676
- ⚛️ Framework support: React, Preact, Next.js, Qwik, Vue, Angular, or plain HTML
7777
- 🔄 Auto-detects current URL and page title
@@ -528,7 +528,7 @@ new SocialShareButton({
528528
| `onCopy` | function | `null` | Callback when user copies link: `(url) => {}` |
529529
530530
**Available Platforms:**
531-
`whatsapp`, `facebook`, `twitter`, `linkedin`, `telegram`, `reddit`, `email`, `pinterest`
531+
`whatsapp`, `facebook`, `twitter`, `linkedin`, `telegram`, `reddit`, `email`, `pinterest`, `discord`
532532
533533
### Customize Share Message/Post Text
534534
@@ -555,7 +555,8 @@ new SocialShareButton({
555555
- **Reddit:** `title` - `description` (used as title)
556556
- **Email:** Subject = `title`, Body = `description` + link
557557
- **Pinterest:** `title` + `description` + `hashtags` + link
558-
558+
- **Discord:** `title` + `description` + `hashtags` + link
559+
-
559560
### Customize Button Color & Appearance
560561
561562
**Option 1: Use Pre-built Styles** (Easiest)

index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ <h2 style="color: #fff; margin-bottom: 20px;">Ready to Get Started?</h2>
680680
container: "#demo-social",
681681
url: demoUrl,
682682
title: demoTitle,
683-
platforms: ["facebook", "twitter", "reddit", "pinterest"],
683+
platforms: ["facebook", "twitter", "reddit", "pinterest", "discord"],
684684
buttonText: "Share",
685685
});
686686

@@ -689,7 +689,7 @@ <h2 style="color: #fff; margin-bottom: 20px;">Ready to Get Started?</h2>
689689
container: "#demo-messaging",
690690
url: demoUrl,
691691
title: demoTitle,
692-
platforms: ["whatsapp", "telegram"],
692+
platforms: ["whatsapp", "telegram", "discord"],
693693
buttonText: "Share",
694694
});
695695

src/social-share-button-preact.jsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import { useEffect, useRef } from "preact/hooks";
22

3-
/**
4-
* SocialShareButton Preact Wrapper
5-
*
6-
* Provides a lightweight Preact functional component that wraps the core
7-
* SocialShareButton vanilla JS library. Handles lifecycle, dynamic updates,
8-
* and browser-only initialization.
9-
*
10-
*/
3+
/**
4+
* SocialShareButton Preact Wrapper
5+
*
6+
* Provides a lightweight Preact functional component that wraps the core
7+
* SocialShareButton vanilla JS library. Handles lifecycle, dynamic updates,
8+
* and browser-only initialization.
9+
*
10+
*/
1111

1212
export default function SocialShareButton({
1313
url = "",
1414
title = "",
1515
description = "",
1616
hashtags = [],
1717
via = "",
18-
platforms = ["whatsapp", "facebook", "twitter", "linkedin", "telegram", "reddit"],
18+
platforms = ["whatsapp", "facebook", "twitter", "linkedin", "telegram", "reddit", "discord"],
1919
theme = "dark",
2020
buttonText = "Share",
2121
customClass = "",
@@ -26,7 +26,7 @@ export default function SocialShareButton({
2626
onCopy = null,
2727
buttonStyle = "default",
2828
modalPosition = "center",
29-
29+
3030
// Analytics props — the library emits events but never collects data itself.
3131
analytics = true,
3232
onAnalytics = null, // (payload) => void hook
@@ -36,10 +36,10 @@ export default function SocialShareButton({
3636
}) {
3737
// DOM reference to the container where the button will be injected
3838
const containerRef = useRef(null);
39-
39+
4040
// Reference to the vanilla JS class instance
4141
const shareButtonRef = useRef(null);
42-
42+
4343
// Storage for the latest options to avoid stale closures during async initialization
4444
const latestOptionsRef = useRef(null);
4545

@@ -97,7 +97,7 @@ export default function SocialShareButton({
9797
};
9898

9999
// SSR Check: Ensure we're in a browser environment
100-
if (typeof window === "undefined") return () => {};
100+
if (typeof window === "undefined") return () => { };
101101

102102
if (window.SocialShareButton) {
103103
// Core library is already loaded
@@ -135,7 +135,7 @@ export default function SocialShareButton({
135135
* Synchronizes prop changes from Preact down to the vanilla JS instance
136136
* without re-mounting the entire component.
137137
*/
138-
138+
139139
// Stringify array dependencies to prevent unnecessary re-runs when
140140
// parent components pass fresh array literals on every render.
141141
const hashtagsDep = JSON.stringify(hashtags);

src/social-share-button-qwik.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ interface Props {
1919
export const SocialShareButton = component$<Props>((props) => {
2020
const containerRef = useSignal<HTMLDivElement>();
2121

22-
22+
2323
useVisibleTask$(({ cleanup }) => {
2424
if (typeof window !== 'undefined' && (window as any).SocialShareButton && containerRef.value) {
2525
const shareButton = new (window as any).SocialShareButton({
@@ -29,7 +29,7 @@ export const SocialShareButton = component$<Props>((props) => {
2929
description: props.description || '',
3030
hashtags: props.hashtags || [],
3131
via: props.via || '',
32-
platforms: props.platforms || ['whatsapp', 'facebook', 'twitter', 'linkedin', 'telegram', 'reddit'],
32+
platforms: props.platforms || ['whatsapp', 'facebook', 'twitter', 'linkedin', 'telegram', 'reddit', 'discord'],
3333
theme: props.theme || 'dark',
3434
buttonText: props.buttonText || 'Share',
3535
customClass: props.customClass || '',

src/social-share-button-react.jsx

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ export const SocialShareButton = ({
1313
description = "",
1414
hashtags = [],
1515
via = "",
16-
platforms = ["whatsapp", "facebook", "twitter", "linkedin", "telegram", "reddit", "pinterest"],
16+
platforms = ["whatsapp", "facebook", "twitter", "linkedin", "telegram", "reddit", "pinterest", "discord"],
1717
theme = "dark",
1818
buttonText = "Share",
1919
customClass = "",
2020
onShare = null,
2121
onCopy = null,
2222
buttonStyle = "default",
2323
modalPosition = "center",
24-
24+
2525
// Analytics: library emits events but never collects data
2626
analytics = true,
2727
onAnalytics = null, // Event callback
@@ -31,7 +31,7 @@ export const SocialShareButton = ({
3131
}) => {
3232
// DOM reference for the injection target
3333
const containerRef = useRef(null);
34-
34+
3535
// Reference to the vanilla JS class instance
3636
const shareButtonRef = useRef(null);
3737

@@ -46,47 +46,47 @@ export const SocialShareButton = ({
4646
* Includes a safe check for the global SocialShareButton class.
4747
*/
4848
useEffect(() => {
49-
if (containerRef.current && !shareButtonRef.current) {
50-
if (typeof window !== "undefined" && window.SocialShareButton) {
51-
shareButtonRef.current = new window.SocialShareButton({
52-
container: containerRef.current,
53-
url: currentUrl,
54-
title: currentTitle,
55-
description,
56-
hashtags,
57-
via,
58-
platforms,
59-
theme,
60-
buttonText,
61-
customClass,
62-
onShare,
63-
onCopy,
64-
buttonStyle,
65-
modalPosition,
66-
analytics,
67-
onAnalytics,
68-
analyticsPlugins,
69-
componentId,
70-
debug,
71-
});
72-
}
49+
if (containerRef.current && !shareButtonRef.current) {
50+
if (typeof window !== "undefined" && window.SocialShareButton) {
51+
shareButtonRef.current = new window.SocialShareButton({
52+
container: containerRef.current,
53+
url: currentUrl,
54+
title: currentTitle,
55+
description,
56+
hashtags,
57+
via,
58+
platforms,
59+
theme,
60+
buttonText,
61+
customClass,
62+
onShare,
63+
onCopy,
64+
buttonStyle,
65+
modalPosition,
66+
analytics,
67+
onAnalytics,
68+
analyticsPlugins,
69+
componentId,
70+
debug,
71+
});
7372
}
73+
}
7474

75-
return () => {
76-
if (shareButtonRef.current) {
77-
shareButtonRef.current.destroy();
78-
shareButtonRef.current = null;
79-
}
80-
};
81-
}, []);
75+
return () => {
76+
if (shareButtonRef.current) {
77+
shareButtonRef.current.destroy();
78+
shareButtonRef.current = null;
79+
}
80+
};
81+
}, []);
8282

8383
/**
8484
* Update Effect
8585
*
8686
* Synchronizes React prop changes with the underlying vanilla JS instance
8787
* without re-mounting the entire component.
8888
*/
89-
89+
9090
useEffect(() => {
9191
if (shareButtonRef.current) {
9292
// Use the library's built-in update method

src/social-share-button.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class SocialShareButton {
2323
"telegram",
2424
"reddit",
2525
"pinterest",
26+
"discord",
2627
],
2728
theme: options.theme || "dark",
2829
buttonText: options.buttonText || "Share",
@@ -172,6 +173,11 @@ class SocialShareButton {
172173
color: "#E60023",
173174
icon: '<path d="M12 0C5.372 0 0 5.373 0 12c0 4.99 3.052 9.267 7.386 11.059-.102-.94-.194-2.385.04-3.413.211-.904 1.356-5.752 1.356-5.752s-.346-.693-.346-1.717c0-1.608.932-2.808 2.093-2.808.987 0 1.463.741 1.463 1.63 0 .993-.632 2.476-.958 3.853-.273 1.155.58 2.098 1.718 2.098 2.062 0 3.646-2.174 3.646-5.31 0-2.778-1.997-4.722-4.847-4.722-3.304 0-5.242 2.478-5.242 5.039 0 .997.384 2.066.865 2.647.095.115.109.215.08.331-.088.365-.282 1.155-.321 1.316-.05.212-.165.257-.381.155-1.418-.66-2.305-2.733-2.305-4.397 0-3.579 2.601-6.867 7.497-6.867 3.936 0 6.998 2.805 6.998 6.557 0 3.91-2.466 7.058-5.892 7.058-1.15 0-2.232-.597-2.6-1.302l-.707 2.692c-.255.983-.946 2.215-1.408 2.966A12.002 12.002 0 0024 12C24 5.373 18.627 0 12 0z"/>',
174175
},
176+
discord: {
177+
name: "Discord",
178+
color: "#5865F2",
179+
icon: '<path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 11.756 11.756 0 0 0-.617-1.25.077.077 0 0 0-.079-.037 19.736 19.736 0 0 0-4.885 1.515.069.069 0 0 0-.032.027C.533 9.048-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.419-2.157 2.419zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.419-2.157 2.419z"/>',
180+
},
175181
};
176182

177183
return this.options.platforms
@@ -244,6 +250,7 @@ class SocialShareButton {
244250
reddit: `https://reddit.com/submit?url=${encodedUrl}&title=${encodedReddit}`,
245251
email: `mailto:?subject=${encodedTitle}&body=${encodedEmail}%20${encodedUrl}`,
246252
pinterest: `https://pinterest.com/pin/create/button/?url=${encodedUrl}&description=${encodedPinterest}`,
253+
discord: "https://discord.com/channels/@me",
247254
};
248255

249256
return urls[platform] || "";
@@ -409,9 +416,17 @@ class SocialShareButton {
409416
if (shareUrl) {
410417
this._emit("social_share_click", "share", { platform });
411418

412-
if (platform === "email") {
419+
// Platform-specific sharing trigger logic:
420+
// Discord does not provide a native web-share intent; therefore, the most reliable
421+
// fallback is to copy the share URL to the clipboard and then navigate the user
422+
// towards Discord's direct messaging area.
423+
if (platform === "discord") {
424+
this.copyLink();
425+
window.open(shareUrl, "_blank", "noopener,noreferrer");
426+
} else if (platform === "email") {
413427
window.location.href = shareUrl;
414428
} else {
429+
// Default behavior: open platform's share intent in a specialized popup window
415430
window.open(shareUrl, "_blank", "noopener,noreferrer,width=600,height=600");
416431
}
417432

0 commit comments

Comments
 (0)