Skip to content

Commit 02b389a

Browse files
authored
Merge branch 'AOSSIE-Org:main' into main
2 parents 0f1e21f + a3cffc8 commit 02b389a

11 files changed

Lines changed: 1003 additions & 25 deletions

.coderabbit.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,3 +278,16 @@ reviews:
278278
- Proper @2x and @3x variants for different screen densities
279279
- SVG assets are optimized
280280
- Font files are licensed and optimized
281+
282+
# Path-based review instructions for specific files/patterns
283+
- path: "src/**/*.{js,jsx}"
284+
instructions: |
285+
Ensure newly added or modified methods and properties have brief inline comments:
286+
287+
- Use minimal, concise inline comments (not JSDoc style)
288+
- Add comments for logical blocks explaining what they do
289+
- Add comments for edge cases and non-obvious logic (safety checks, race condition prevention, re-entrancy guards, cleanup callbacks, etc.)
290+
- No need to document parameters or return values
291+
- Not every function needs comments - only add where it aids understanding
292+
293+
Flag any newly added or modified function or property that lacks descriptive inline comments for non-obvious logic or edge cases.
Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
---
2+
agent: agent
3+
description: >
4+
Connect SocialShareButton analytics events to any analytics provider:
5+
Google Analytics 4, Mixpanel, Segment, Plausible, PostHog, or a custom
6+
system. Use this skill whenever a developer asks how to track share
7+
interactions or wire up analytics.
8+
---
9+
10+
# SocialShareButton — Analytics Integration Skill
11+
12+
You are helping a developer connect **SocialShareButton** interaction events to
13+
their analytics stack. The library is **privacy-by-design**: it never collects
14+
or transmits data itself — it only emits local events that the host website
15+
forwards to whatever tool they choose.
16+
17+
> **Prerequisite:** The button must already be integrated into the project.
18+
> If it isn't, use the **`integrate-social-share-button`** skill first, then
19+
> return here to wire up analytics.
20+
21+
---
22+
23+
## 1 — Standard event payload (every event carries these fields)
24+
25+
```js
26+
{
27+
version : "1.0", // schema version — increment on breaking changes
28+
source : "social-share-button", // always this value; useful for stream filtering
29+
eventName : "social_share_click", // see event catalogue below
30+
interactionType: "share", // "share" | "copy" | "popup_open" | "popup_close" | "error"
31+
platform : "twitter", // null for non-platform events
32+
url : "https://example.com",
33+
title : "My Page Title",
34+
timestamp : 1709800000000, // Date.now()
35+
componentId : "hero-share", // null unless set by developer
36+
errorMessage : "...", // only on social_share_error
37+
}
38+
```
39+
40+
---
41+
42+
## 2 — Core events catalogue
43+
44+
| `eventName` | `interactionType` | Fires when |
45+
| ---------------------------- | ----------------- | ----------------------------------------------- |
46+
| `social_share_popup_open` | `popup_open` | Share modal/popup opens |
47+
| `social_share_popup_close` | `popup_close` | Modal closes (button, overlay, or Esc key) |
48+
| `social_share_click` | `share` | User clicks a platform button (share intent) |
49+
| `social_share_success` | `share` | Platform share window opened successfully |
50+
| `social_share_copy` | `copy` | User copies the link to clipboard |
51+
| `social_share_error` | `error` | Share or copy action failed |
52+
53+
---
54+
55+
## 3 — Three delivery paths (choose one or combine freely)
56+
57+
### Path A — DOM CustomEvent (best for CDN / vanilla / any framework)
58+
59+
```js
60+
// Fires on the container element and bubbles through the DOM (composed:true
61+
// means it also crosses shadow-DOM boundaries).
62+
document.addEventListener("social-share", (e) => {
63+
const payload = e.detail;
64+
// Forward to your analytics tool here
65+
});
66+
```
67+
68+
Multiple independent listeners can subscribe simultaneously — useful when GA4
69+
and Mixpanel both need the same event.
70+
71+
### Path B — `onAnalytics` callback (best for inline single-consumer setups)
72+
73+
```js
74+
new SocialShareButton({
75+
container: "#share-button",
76+
onAnalytics: (payload) => {
77+
// Forward to your analytics tool here
78+
},
79+
});
80+
```
81+
82+
### Path C — `analyticsPlugins` adapter registry (best for multiple providers)
83+
84+
Load the adapters file **in addition to** the main library script:
85+
86+
```html
87+
<!-- After the main social-share-button.js script tag -->
88+
<!-- CDN (pick whichever tag version ships this file): -->
89+
<script src="https://cdn.jsdelivr.net/gh/AOSSIE-Org/SocialShareButton@main/src/social-share-analytics.js"></script>
90+
91+
<!-- Or via npm: -->
92+
<!-- import { GoogleAnalyticsAdapter, MixpanelAdapter } from "social-share-button-aossie/src/social-share-analytics.js"; -->
93+
```
94+
95+
```js
96+
const { GoogleAnalyticsAdapter, MixpanelAdapter } = window.SocialShareAnalytics;
97+
98+
new SocialShareButton({
99+
container: "#share-button",
100+
analyticsPlugins: [
101+
new GoogleAnalyticsAdapter(),
102+
new MixpanelAdapter(),
103+
],
104+
});
105+
```
106+
107+
---
108+
109+
## 4 — Built-in adapters (from `src/social-share-analytics.js`)
110+
111+
Each adapter checks that the provider's global exists before calling it, so
112+
no errors occur if a provider hasn't loaded yet.
113+
114+
> **Relationship to `onShare` / `onCopy`:** These legacy callbacks fire for
115+
> backwards-compatibility when a share or copy happens. `onAnalytics` and
116+
> `analyticsPlugins` are the dedicated analytics channels — they receive
117+
> **all** events (popup open/close, errors, etc.), not just share and copy.
118+
> You can use both simultaneously without conflict.
119+
120+
### Google Analytics 4
121+
122+
Prerequisite: GA4 `gtag.js` snippet loaded by the host.
123+
124+
```js
125+
const { GoogleAnalyticsAdapter } = window.SocialShareAnalytics;
126+
127+
new SocialShareButton({
128+
container: "#share-button",
129+
analyticsPlugins: [new GoogleAnalyticsAdapter()],
130+
});
131+
132+
// Calls: gtag('event', payload.eventName, { share_platform, share_url, ... })
133+
```
134+
135+
Custom event category (optional):
136+
137+
```js
138+
new GoogleAnalyticsAdapter({ eventCategory: "engagement" })
139+
```
140+
141+
### Mixpanel
142+
143+
Prerequisite: `mixpanel-browser` snippet or SDK loaded.
144+
145+
```js
146+
const { MixpanelAdapter } = window.SocialShareAnalytics;
147+
new SocialShareButton({
148+
container: "#share-button",
149+
analyticsPlugins: [new MixpanelAdapter()],
150+
});
151+
// Calls: mixpanel.track(eventName, { platform, url, ... })
152+
```
153+
154+
### Segment (Analytics.js / analytics-next)
155+
156+
```js
157+
const { SegmentAdapter } = window.SocialShareAnalytics;
158+
new SocialShareButton({
159+
container: "#share-button",
160+
analyticsPlugins: [new SegmentAdapter()],
161+
});
162+
// Calls: analytics.track(eventName, { platform, url, ... })
163+
```
164+
165+
### Plausible
166+
167+
Prerequisite: Plausible `script.js` loaded with custom events enabled.
168+
169+
```js
170+
const { PlausibleAdapter } = window.SocialShareAnalytics;
171+
new SocialShareButton({
172+
container: "#share-button",
173+
analyticsPlugins: [new PlausibleAdapter()],
174+
});
175+
// Calls: plausible(eventName, { props: { platform, url, ... } })
176+
```
177+
178+
### PostHog
179+
180+
```js
181+
const { PostHogAdapter } = window.SocialShareAnalytics;
182+
new SocialShareButton({
183+
container: "#share-button",
184+
analyticsPlugins: [new PostHogAdapter()],
185+
});
186+
// Calls: posthog.capture(eventName, { platform, url, ... })
187+
```
188+
189+
### Custom / inline function
190+
191+
Wrap any one-off function without subclassing:
192+
193+
```js
194+
const { CustomAdapter } = window.SocialShareAnalytics;
195+
new SocialShareButton({
196+
analyticsPlugins: [
197+
new CustomAdapter((payload) => {
198+
fetch("/api/analytics", {
199+
method: "POST",
200+
body: JSON.stringify(payload),
201+
});
202+
}),
203+
],
204+
});
205+
```
206+
207+
### Custom provider class (full adapter)
208+
209+
```js
210+
class MyAnalyticsAdapter {
211+
track(payload) {
212+
MyAnalytics.logEvent(payload.eventName, {
213+
platform: payload.platform,
214+
url: payload.url,
215+
});
216+
}
217+
}
218+
219+
new SocialShareButton({
220+
analyticsPlugins: [new MyAnalyticsAdapter()],
221+
});
222+
```
223+
224+
---
225+
226+
## 5 — Combining multiple providers
227+
228+
All three delivery paths run simultaneously. The example below sends events to
229+
GA4, Mixpanel, and a custom endpoint at the same time:
230+
231+
```js
232+
const { GoogleAnalyticsAdapter, MixpanelAdapter, CustomAdapter } = window.SocialShareAnalytics;
233+
234+
document.addEventListener("social-share", (e) => {
235+
console.log("Raw event:", e.detail); // Debugging / logging
236+
});
237+
238+
new SocialShareButton({
239+
container: "#share-button",
240+
componentId: "homepage-hero",
241+
analyticsPlugins: [
242+
new GoogleAnalyticsAdapter(),
243+
new MixpanelAdapter(),
244+
new CustomAdapter((p) => fetch("/log", { method: "POST", body: JSON.stringify(p) })),
245+
],
246+
});
247+
```
248+
249+
---
250+
251+
## 6 — Debug mode
252+
253+
Pass `debug: true` to log every emitted event to the browser console during
254+
development. Remove or set to `false` in production.
255+
256+
```js
257+
new SocialShareButton({
258+
container: "#share-button",
259+
debug: true,
260+
// → [SocialShareButton Analytics] { version: '1.0', source: 'social-share-button', ... }
261+
});
262+
```
263+
264+
---
265+
266+
## 7 — Opting out of analytics
267+
268+
Set `analytics: false` to disable all event emission. No CustomEvents,
269+
callbacks, or adapter calls will be made — useful for environments where any
270+
instrumentation must be explicitly consented to before activation.
271+
272+
```js
273+
new SocialShareButton({
274+
container: "#share-button",
275+
analytics: false,
276+
});
277+
```
278+
279+
---
280+
281+
## 8 — Privacy and compliance
282+
283+
- The library **never** initiates network requests.
284+
- Payloads contain only the `url` and `title` the host developer already chose
285+
to share — no PII is inferred or added.
286+
- GDPR / CCPA: activate analytics adapters only **after** the user has consented
287+
via your consent management platform (CMP):
288+
289+
```js
290+
+const shareButtonInstance = new SocialShareButton({
291+
+ container: "#share-button",
292+
+ analytics: false,
293+
+});
294+
+
295+
+// Activate only after CMP consent
296+
consentManager.onConsent("analytics", () => {
297+
shareButtonInstance.updateOptions({
298+
+ analytics: true,
299+
analyticsPlugins: [new GoogleAnalyticsAdapter()],
300+
});
301+
});
302+
```
303+
304+
---
305+
306+
## 9 — Event naming alignment (GA4)
307+
308+
All events follow `social_<object>_<action>`, which matches GA4's recommended
309+
naming convention for custom events. The built-in Mixpanel and Segment
310+
adapters forward the same event names unchanged:
311+
312+
| Library event | GA4 event name | Mixpanel / Segment built-in adapters |
313+
| ------------------------- | ------------------------- | ------------------------------------ |
314+
| `social_share_click` | `social_share_click` | `social_share_click` |
315+
| `social_share_success` | `social_share_success` | `social_share_success` |
316+
| `social_share_copy` | `social_share_copy` | `social_share_copy` |
317+
| `social_share_popup_open` | `social_share_popup_open` | `social_share_popup_open` |
318+
319+
---
320+
321+
## 10 — Output format
322+
323+
- Show only the snippet relevant to the developer's chosen analytics provider.
324+
- If the developer asks about GDPR / consent, always demonstrate the deferred
325+
activation pattern from section 8.
326+
- Never suggest bundling analytics SDKs inside the component — point to the
327+
host-side script tag instead.
328+
- Remind developers that `debug: true` should be removed before production.

README.md

Lines changed: 3 additions & 2 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
74+
- 🌐 Multiple platforms: WhatsApp, Facebook, X, LinkedIn, Telegram, Reddit, Email, Pinterest
7575
- 🎯 Zero dependencies - pure vanilla JavaScript
7676
- ⚛️ Framework support: React, Preact, Next.js, Vue, Angular, or plain HTML
7777
- 🔄 Auto-detects current URL and page title
@@ -533,7 +533,7 @@ new SocialShareButton({
533533
| `onCopy` | function | `null` | Callback when user copies link: `(url) => {}` |
534534
535535
**Available Platforms:**
536-
`whatsapp`, `facebook`, `twitter`, `linkedin`, `telegram`, `reddit`, `email`
536+
`whatsapp`, `facebook`, `twitter`, `linkedin`, `telegram`, `reddit`, `email`, `pinterest`
537537
538538
### Customize Share Message/Post Text
539539
@@ -559,6 +559,7 @@ new SocialShareButton({
559559
- **LinkedIn:** `title` + `description` + link
560560
- **Reddit:** `title` - `description` (used as title)
561561
- **Email:** Subject = `title`, Body = `description` + link
562+
- **Pinterest:** `title` + `description` + `hashtags` + link
562563
563564
### Customize Button Color & Appearance
564565

0 commit comments

Comments
 (0)