From 9f7767e064c1cb4bbd15c367f955d41878ebf0d1 Mon Sep 17 00:00:00 2001 From: PrithvijitBose Date: Sat, 1 Aug 2026 18:31:56 +0530 Subject: [PATCH 1/9] docs(copilot): update integration prompt instructions --- .../integrate-social-share-button.prompt.md | 732 ++++-------------- 1 file changed, 170 insertions(+), 562 deletions(-) diff --git a/.github/copilot/integrate-social-share-button.prompt.md b/.github/copilot/integrate-social-share-button.prompt.md index bea2b48..9cdcc0b 100644 --- a/.github/copilot/integrate-social-share-button.prompt.md +++ b/.github/copilot/integrate-social-share-button.prompt.md @@ -1,442 +1,128 @@ --- agent: agent description: > - Integrate SocialShareButton into any web project. Covers CDN (recommended), - npm (advanced), and React/Preact/Qwik Wrapper Components (optional). Framework-specific - steps for CRA, Next.js App Router, Next.js Pages Router, Vite/Vue/Angular, - Preact, Qwik, and Vanilla HTML. Use this skill whenever a developer asks how to add the - share button to their project. + Automatically integrate @aossie-org/social-share-button into a client web project + with zero manual steps except specifying where to place the button. --- # SocialShareButton — Integration Skill -You are helping a developer integrate the **SocialShareButton** library -(`social-share-button-aossie`) into their project. Follow these rules strictly. +## Goal +Integrate `@aossie-org/social-share-button` into a client web project with zero manual steps from the user except specifying button location. --- -> 🚫 **IMPORTANT:** Do NOT create new files like `ShareButton.jsx` or `ShareButton.tsx`! -> ✅ Add code directly to the developer's **existing** component (Header, Navbar, etc.) -> 📄 **Exception:** If a separate file is needed (e.g. a dedicated share component), follow **Method 3 — React Wrapper Component** exclusively. +## Step-by-Step Workflow ---- - -## How to respond - -The README defines **3 installation methods**. Ask (or infer) which the developer wants: +### 1. Inspect Repo & Identify Frontend +- Locate frontend `package.json` (look for React, Next.js, Vue, Angular, Qwik, Preact, Vanilla). +- In monorepos (`apps/`, `packages/`), target the frontend app directory only. Never modify backend projects. -| Method | When to use | -| ------------------------------------------------------- | ------------------------------------------------------------------------- | -| **Method 1 — CDN (Recommended)** | Most projects. No build step needed. Load via ` - - -``` - ---- - -### CDN — Create React App - -**Step 1:** Add CDN to `public/index.html`: - -```html - - - - -
- - -``` - -**Step 2:** Open an **existing** component that renders on every page — typically `src/components/Header.jsx`, `src/layouts/MainLayout.jsx`, or your root `App.jsx`. Add the snippet below to that component so the share button is consistently available across your app. +### ⚛️ React / Next.js / Preact +#### npm Method +Create wrapper component (`src/components/ShareButton.jsx`): ```jsx +"use client"; import { useEffect, useRef } from "react"; -import { useLocation } from "react-router-dom"; // omit if not using React Router +import SocialShareButton from "@aossie-org/social-share-button"; +import "@aossie-org/social-share-button/src/social-share-button.css"; -// ⬇️ Replace 'Header' with the name of the component where you want the -// share button to appear — e.g. Navbar, MainLayout, App, etc. -function Header() { - const shareButtonRef = useRef(null); - const initRef = useRef(false); - const { pathname } = useLocation(); // omit if not using React Router +export default function ShareButton({ style = "default", url, title, theme = "dark" }) { + const containerRef = useRef(null); + const instanceRef = useRef(null); useEffect(() => { - if (initRef.current || !window.SocialShareButton) return; - - shareButtonRef.current = new window.SocialShareButton({ - container: "#share-button", + if (!containerRef.current) return; + if (instanceRef.current?.destroy) instanceRef.current.destroy(); + + instanceRef.current = new SocialShareButton({ + container: containerRef.current, + buttonStyle: style, + url, + title, + theme, }); - initRef.current = true; - - return () => { - if (shareButtonRef.current?.destroy) { - shareButtonRef.current.destroy(); - } - initRef.current = false; - }; - }, []); - - // Keep the share URL and title in sync with the current route - useEffect(() => { - if (shareButtonRef.current) { - shareButtonRef.current.updateOptions({ - url: window.location.href, - title: document.title, - }); - } - }, [pathname]); // re-runs on every client-side route change - - return ( -
-
-
- ); -} -``` ---- - -### CDN — Next.js App Router - -**Step 1:** Add CDN to `app/layout.tsx`: + return () => instanceRef.current?.destroy?.(); + }, [style, url, title, theme]); -```tsx -import Script from "next/script"; - -export default function RootLayout({ children }: { children: React.ReactNode }) { - return ( - - - - - - {children} - - - - ); -} -``` - -**Step 2:** Open an existing component that is rendered on every page — typically `components/Header.tsx`, `components/Navbar.tsx`, or `components/Layout.tsx`. Since `_document.tsx` loads the script globally, the button is ready to initialize in any of these components. - -```tsx import { useEffect, useRef } from "react"; -import { useRouter } from "next/router"; -// ⬇️ Replace 'Header' with the name of the component where you want the -// share button to appear — e.g. Navbar, MainLayout, App, etc. -export default function Header() { - const shareButtonRef = useRef(null); - const containerRef = useRef(null); - const initRef = useRef(false); - const { pathname } = useRouter(); +export default function ShareButton({ style = "default", url, title }) { + const containerRef = useRef(null); + const instanceRef = useRef(null); useEffect(() => { - const initButton = () => { - if (initRef.current || !window.SocialShareButton || !containerRef.current) return; - - shareButtonRef.current = new window.SocialShareButton({ - container: "#share-button", + const init = () => { + if (!window.SocialShareButton || !containerRef.current) return; + if (instanceRef.current?.destroy) instanceRef.current.destroy(); + + instanceRef.current = new window.SocialShareButton({ + container: containerRef.current, + buttonStyle: style, + url, + title, }); - initRef.current = true; }; if (window.SocialShareButton) { - initButton(); + init(); } else { - const checkInterval = setInterval(() => { + const timer = setInterval(() => { if (window.SocialShareButton) { - clearInterval(checkInterval); - initButton(); + clearInterval(timer); + init(); } }, 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; - }; - }, []); - - // Keep the share URL and title in sync with the current route - useEffect(() => { - if (shareButtonRef.current) { - shareButtonRef.current.updateOptions({ - url: window.location.href, - title: document.title, - }); + return () => clearInterval(timer); } - }, [pathname]); // re-runs on every client-side navigation - return ( -
-
-
- ); -} + return () => instanceRef.current?.destroy?.(); + }, [style, url, title]); -declare global { - interface Window { - SocialShareButton: any; - } -} -``` - ---- - -### CDN — Vite / Vue / Angular - -**Step 1:** Add CDN to root `index.html`: - -```html - - - - -
- - -``` - -**Step 2:** Open your root or layout component (e.g., `App.vue`, `app.component.html`, or `App.jsx`). Add a container `
` where you want the button to appear, then initialize the button after the DOM is ready: - -```javascript -// Add
to your component's template/HTML first, -// then initialize once the DOM is ready (e.g., in mounted(), ngAfterViewInit(), or useEffect()): -new window.SocialShareButton({ - container: "#share-button", -}); -``` - ---- - -### CDN — Preact - -**Step 1:** Add CDN to root `index.html`: - -```html - - - - -
- - -``` - -**Step 2:** Open your root or layout component (typically `src/components/Header.jsx` or your root `App.jsx`). Add a container element and initialize inside the `useEffect` hook: - -```jsx -import { useEffect, useRef } from "preact/hooks"; - -// ⬇️ Replace 'Header' with the name of the component where you want the -// share button to appear — e.g. Navbar, MainLayout, App, etc. -export default function Header() { - const shareButtonRef = useRef(null); - const containerRef = useRef(null); - const initRef = useRef(false); - - useEffect(() => { - if (initRef.current || !window.SocialShareButton || !containerRef.current) return; - - shareButtonRef.current = new window.SocialShareButton({ - container: "#share-button", - }); - initRef.current = true; - - return () => { - if (shareButtonRef.current?.destroy) { - shareButtonRef.current.destroy(); - } - initRef.current = false; - }; - }, []); - - return ( -
-
-
- ); + return
; } ``` @@ -444,210 +130,132 @@ export default function Header() { ### CDN — Qwik -**Step 1:** Add CDN to your root or layout page (e.g. `src/root.tsx` or layout index): - -```html - - - - - - -``` - -**Step 2:** Create a container element and initialize the button in `useVisibleTask$`: - +Add CDN `` and ` ``` -### Qwik Wrapper Component +#### CDN Method +Add CDN `` & ` +``` -```jsx -// Next.js App Router: import { usePathname } from "next/navigation"; -// Next.js Pages Router: import { useRouter } from "next/router"; -// React Router: import { useLocation } from "react-router-dom"; - -const shareButton = useRef(null); -// Get the current pathname from your router, e.g.: -// const pathname = usePathname(); // Next.js App Router -// const { pathname } = useRouter(); // Next.js Pages Router -// const { pathname } = useLocation(); // React Router - -useEffect(() => { - shareButton.current = new window.SocialShareButton({ - container: "#share-button", +#### CDN Method (Pure HTML) +```html + +
+ + ``` - ---- - -## Troubleshooting - -| Symptom | Cause | Fix | -| --------------------------------------------------- | ------------------------------------------------- | --------------------------------------------------------------------------------------------- | -| Multiple buttons appearing | Component re-renders creating duplicate instances | Use `useRef` + `initRef` guard (shown in all examples above) | -| Button not appearing | Script loads after component renders | Add `if (window.SocialShareButton)` null check | -| Modal not opening | CSS not loaded or ID mismatch | Verify CSS CDN in ``; match `container: '#share-button'` with `
` | -| `TypeError: SocialShareButton is not a constructor` | CDN script not loaded yet | Use interval polling (see Next.js examples above) | -| URL not updating on navigation | Component initialized once, doesn't track routes | Use `updateOptions()` on route change | - ---- - -## Common mistakes to prevent - -| ❌ Wrong | ✅ Correct | -| ----------------------------------------------------- | ------------------------------------------------------------------------- | -| Creating `ShareButton.jsx` / `ShareButton.tsx` | Add directly to existing `Header.jsx`, `Navbar.tsx`, etc. | -| Calling `new SocialShareButton()` inside JSX `return` | Call only inside `useEffect` / lifecycle hook | -| Not calling `destroy()` on unmount | Always clean up — prevents duplicate modals on re-mount | -| Mismatched container ID | `container: '#share-button'` must exactly match `
` | -| Script loads after component renders in Next.js | Use `strategy="beforeInteractive"` **or** poll with `setInterval` | - ---- - -## Output format - -- Ask the developer their **method** (CDN / npm / Wrapper Component) and their **framework** (needed to select the correct CDN integration steps or wrapper component). -- Show only the snippet(s) relevant to their choices. -- Always modify **existing** files — never suggest creating new component files (unless they explicitly ask for a Wrapper Component, in which case instruct them to copy the relevant file from `src/` to their components folder). -- When modifying an existing file, mark additions with `// ADD THIS`. -- Do not add abstractions, wrappers, or extra files beyond what the README shows. From 5fd937a03559ae6c6cd26e21c363f33d50cda141 Mon Sep 17 00:00:00 2001 From: PrithvijitBose Date: Sat, 1 Aug 2026 19:38:37 +0530 Subject: [PATCH 2/9] fixed coderabbit changes --- .../integrate-social-share-button.prompt.md | 156 ++++++++++++++---- 1 file changed, 121 insertions(+), 35 deletions(-) diff --git a/.github/copilot/integrate-social-share-button.prompt.md b/.github/copilot/integrate-social-share-button.prompt.md index 9cdcc0b..f3ee933 100644 --- a/.github/copilot/integrate-social-share-button.prompt.md +++ b/.github/copilot/integrate-social-share-button.prompt.md @@ -8,6 +8,7 @@ description: > # SocialShareButton — Integration Skill ## Goal + Integrate `@aossie-org/social-share-button` into a client web project with zero manual steps from the user except specifying button location. --- @@ -15,14 +16,17 @@ Integrate `@aossie-org/social-share-button` into a client web project with zero ## Step-by-Step Workflow ### 1. Inspect Repo & Identify Frontend + - Locate frontend `package.json` (look for React, Next.js, Vue, Angular, Qwik, Preact, Vanilla). - In monorepos (`apps/`, `packages/`), target the frontend app directory only. Never modify backend projects. ### 2. Lock File & Tech Detection + - Check `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, or `bun.lockb` for package manager (`npm`|`pnpm`|`yarn`|`bun`). - **CRITICAL DIRECTIVE**: Skip directly to the detected framework in **Technology Guides** below. Ignore all other guides. ### 3. Install Package (npm method) + - npm: `npm i @aossie-org/social-share-button` - pnpm: `pnpm add @aossie-org/social-share-button` - yarn: `yarn add @aossie-org/social-share-button` @@ -30,9 +34,11 @@ Integrate `@aossie-org/social-share-button` into a client web project with zero *(Skip if CDN method requested).* ### 4. Ask User Placement (If Unspecified) + Ask: *"Where would you like to place the Social Share Button? Options: npm | CDN. Style: default | round | square."* ### 5. Mandatory Integration Rules + - **ESM Import**: MUST use default import `import SocialShareButton from "@aossie-org/social-share-button";` (Do NOT use named `{ SocialShareButton }`). - **CSS Import**: Include `@aossie-org/social-share-button/src/social-share-button.css` or CDN CSS. - **Next.js Client Components**: Include `"use client";` at top of files using hooks (`useEffect`, `useRef`). @@ -46,10 +52,12 @@ Ask: *"Where would you like to place the Social Share Button? Options: npm | CDN --- -### ⚛️ React / Next.js / Preact +### ⚛️ React / Next.js #### npm Method + Create wrapper component (`src/components/ShareButton.jsx`): + ```jsx "use client"; import { useEffect, useRef } from "react"; @@ -62,8 +70,7 @@ export default function ShareButton({ style = "default", url, title, theme = "da useEffect(() => { if (!containerRef.current) return; - if (instanceRef.current?.destroy) instanceRef.current.destroy(); - + instanceRef.current?.destroy?.(); instanceRef.current = new SocialShareButton({ container: containerRef.current, buttonStyle: style, @@ -71,7 +78,6 @@ export default function ShareButton({ style = "default", url, title, theme = "da title, theme, }); - return () => instanceRef.current?.destroy?.(); }, [style, url, title, theme]); @@ -80,12 +86,14 @@ export default function ShareButton({ style = "default", url, title, theme = "da ``` #### CDN Method + 1. **Global Template**: - - **React/Preact (`public/index.html`)**: Add CDN stylesheet `` to `` and ` + ``` #### CDN Method (Pure HTML) + ```html
From cae3d425d38fda2f45e540df72e3eb45b34a8d89 Mon Sep 17 00:00:00 2001 From: PrithvijitBose Date: Sat, 1 Aug 2026 19:47:49 +0530 Subject: [PATCH 3/9] fixed coderabbit changes --- .../integrate-social-share-button.prompt.md | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/.github/copilot/integrate-social-share-button.prompt.md b/.github/copilot/integrate-social-share-button.prompt.md index f3ee933..9b13695 100644 --- a/.github/copilot/integrate-social-share-button.prompt.md +++ b/.github/copilot/integrate-social-share-button.prompt.md @@ -40,7 +40,7 @@ Ask: *"Where would you like to place the Social Share Button? Options: npm | CDN ### 5. Mandatory Integration Rules - **ESM Import**: MUST use default import `import SocialShareButton from "@aossie-org/social-share-button";` (Do NOT use named `{ SocialShareButton }`). -- **CSS Import**: Include `@aossie-org/social-share-button/src/social-share-button.css` or CDN CSS. +- **CSS Import**: Include `@aossie-org/social-share-button/css` or CDN CSS. - **Next.js Client Components**: Include `"use client";` at top of files using hooks (`useEffect`, `useRef`). - **No `as any` in `.js`/`.jsx`**: Do NOT use TypeScript assertions in JavaScript files. @@ -62,7 +62,7 @@ Create wrapper component (`src/components/ShareButton.jsx`): "use client"; import { useEffect, useRef } from "react"; import SocialShareButton from "@aossie-org/social-share-button"; -import "@aossie-org/social-share-button/src/social-share-button.css"; +import "@aossie-org/social-share-button/css"; export default function ShareButton({ style = "default", url, title, theme = "dark" }) { const containerRef = useRef(null); @@ -141,7 +141,7 @@ Create component (`src/components/ShareButton.jsx`): ```jsx import { useEffect, useRef } from "preact/hooks"; import SocialShareButton from "@aossie-org/social-share-button"; -import "@aossie-org/social-share-button/src/social-share-button.css"; +import "@aossie-org/social-share-button/css"; export default function ShareButton({ style = "default", url, title, theme = "dark" }) { const containerRef = useRef(null); @@ -246,7 +246,7 @@ export default component$(({ style = "default", url, title }) => { +``` -#### npm Method +#### npm Method — New Project / Dedicated File (EXCEPTION) -` ``` -#### CDN Method - -Add CDN `` & ` -``` - -#### CDN Method (Pure HTML) +#### CDN Method (Pure HTML - Inline) ```html From 414a47f12ef3370523275c3fd7e4f58e428f1532 Mon Sep 17 00:00:00 2001 From: PrithvijitBose Date: Thu, 6 Aug 2026 19:08:59 +0530 Subject: [PATCH 7/9] added CDN method in Vue3 --- .../integrate-social-share-button.prompt.md | 136 ++++++++++++++---- 1 file changed, 107 insertions(+), 29 deletions(-) diff --git a/.github/copilot/integrate-social-share-button.prompt.md b/.github/copilot/integrate-social-share-button.prompt.md index bec7619..133be9b 100644 --- a/.github/copilot/integrate-social-share-button.prompt.md +++ b/.github/copilot/integrate-social-share-button.prompt.md @@ -29,11 +29,11 @@ Integrate `@aossie-org/social-share-button` into a client web project with zero - npm: `npm i @aossie-org/social-share-button` | pnpm: `pnpm add @aossie-org/social-share-button` - yarn: `yarn add @aossie-org/social-share-button` | bun: `bun add @aossie-org/social-share-button` -*(Skip if CDN method requested).* + _(Skip if CDN method requested)._ ### 4. Ask User Placement (If Unspecified) -Ask: *"Where would you like to place the Social Share Button? Options: npm | CDN. Style: default | round | square."* +Ask: _"Where would you like to place the Social Share Button? Options: npm | CDN. Style: default | round | square."_ ### 5. Mandatory Integration Rules @@ -105,7 +105,13 @@ export default function ShareButton({ style = "default", url, title, theme = "da useEffect(() => { if (!containerRef.current) return; instanceRef.current?.destroy?.(); - instanceRef.current = new SocialShareButton({ container: containerRef.current, buttonStyle: style, url, title, theme }); + instanceRef.current = new SocialShareButton({ + container: containerRef.current, + buttonStyle: style, + url, + title, + theme, + }); return () => instanceRef.current?.destroy?.(); }, [style, url, title, theme]); @@ -135,13 +141,25 @@ export default function Header() { const init = () => { if (!window.SocialShareButton || !shareContainerRef.current) return; shareInstanceRef.current?.destroy?.(); - shareInstanceRef.current = new window.SocialShareButton({ container: shareContainerRef.current, buttonStyle: "default" }); + shareInstanceRef.current = new window.SocialShareButton({ + container: shareContainerRef.current, + buttonStyle: "default", + }); }; if (window.SocialShareButton) init(); - else timer = setInterval(() => { if (window.SocialShareButton) { clearInterval(timer); init(); } }, 100); + else + timer = setInterval(() => { + if (window.SocialShareButton) { + clearInterval(timer); + init(); + } + }, 100); - return () => { if (timer) clearInterval(timer); shareInstanceRef.current?.destroy?.(); }; + return () => { + if (timer) clearInterval(timer); + shareInstanceRef.current?.destroy?.(); + }; }, []); return ( @@ -173,7 +191,10 @@ export default function Header() { useEffect(() => { if (!shareContainerRef.current) return; shareInstanceRef.current?.destroy?.(); - shareInstanceRef.current = new SocialShareButton({ container: shareContainerRef.current, buttonStyle: "default" }); + shareInstanceRef.current = new SocialShareButton({ + container: shareContainerRef.current, + buttonStyle: "default", + }); return () => shareInstanceRef.current?.destroy?.(); }, []); @@ -201,7 +222,13 @@ export default function ShareButton({ style = "default", url, title, theme = "da useEffect(() => { if (!containerRef.current) return; instanceRef.current?.destroy?.(); - instanceRef.current = new SocialShareButton({ container: containerRef.current, buttonStyle: style, url, title, theme }); + instanceRef.current = new SocialShareButton({ + container: containerRef.current, + buttonStyle: style, + url, + title, + theme, + }); return () => instanceRef.current?.destroy?.(); }, [style, url, title, theme]); @@ -239,7 +266,10 @@ let shareInstance = null; onMounted(() => { if (!shareContainerRef.value) return; - shareInstance = new SocialShareButton({ container: shareContainerRef.value, buttonStyle: "default" }); + shareInstance = new SocialShareButton({ + container: shareContainerRef.value, + buttonStyle: "default", + }); }); onUnmounted(() => shareInstance?.destroy?.()); @@ -260,14 +290,23 @@ import { ref, onMounted, onUnmounted, watch } from "vue"; import SocialShareButton from "@aossie-org/social-share-button"; import "@aossie-org/social-share-button/css"; -const props = defineProps({ style: { type: String, default: "default" }, url: String, title: String }); +const props = defineProps({ + style: { type: String, default: "default" }, + url: String, + title: String, +}); const containerRef = ref(null); let instance = null; const init = () => { if (!containerRef.value) return; instance?.destroy?.(); - instance = new SocialShareButton({ container: containerRef.value, buttonStyle: props.style, url: props.url, title: props.title }); + instance = new SocialShareButton({ + container: containerRef.value, + buttonStyle: props.style, + url: props.url, + title: props.title, + }); }; onMounted(init); @@ -276,6 +315,10 @@ onUnmounted(() => instance?.destroy?.()); ``` +#### CDN Method + +Add CDN `` to `` and ` + ``` +- **NPM Method**: Install dependency (`npm i @aossie-org/social-share-button`, `pnpm add`, `yarn add`, or `bun add`). + +### 4. Ask User Placement & Style +- **Method Preference**: Always recommend **CDN** over NPM. +- **Placement Prompting**: Ask the user explicitly: + - Which file they want to import/place the Social Share button in. + - The exact placement location inside that file (e.g., to the left of, right of, above, or below a specific existing component or DOM element, such as next to a logo, navigation items, or primary action buttons). +- **React / Next.js Guidance**: Always recommend placing in the **Navbar / Header** every time when integrating React or Next.js using CDN. +- **Vanilla HTML Guidance**: For HTML projects, ask for their main HTML file (e.g., `index.html`) and exact placement relative to existing HTML elements. +- **Style Options**: Prompt for preferred button style (`default` | `round` | `square`). + +### 5. Inject Integration Code into Existing Files +- 🛑 **No New Files**: Inject directly into target existing file (e.g., `Header`, `Footer`, `page.tsx`). +- **ESM Import**: `import SocialShareButton from "@aossie-org/social-share-button";` +- **CSS Import**: `@aossie-org/social-share-button/css` +- **Next.js**: Add `"use client";` at top of interactive client components. --- -## Technology Guides - -> ⚠️ **CRITICAL DIRECTIVE**: Jump directly to target framework section. Ignore others. Apply **Default (Inline into Existing Component)** unless starting a new project or given an explicit user request for a separate file. - ---- - -### ⚛️ React / Next.js - -#### npm Method — Existing Project (Inline - DEFAULT) - -Add directly into the target existing file (e.g., `src/components/Header.jsx` or `src/app/page.tsx`): +## Framework Integration Guides +### ⚛️ React / Next.js (NPM Method) ```jsx "use client"; import { useEffect, useRef } from "react"; @@ -67,192 +57,54 @@ import "@aossie-org/social-share-button/css"; export default function Header() { const shareContainerRef = useRef(null); - const shareInstanceRef = useRef(null); useEffect(() => { if (!shareContainerRef.current) return; - shareInstanceRef.current?.destroy?.(); - shareInstanceRef.current = new SocialShareButton({ + const shareInstance = new SocialShareButton({ container: shareContainerRef.current, - buttonStyle: "default", + buttonStyle: "default", // default | round | square }); - return () => shareInstanceRef.current?.destroy?.(); + return () => shareInstance.destroy?.(); }, []); return (
- {/* Existing component markup */}
); } ``` -#### npm Method — New Project / Dedicated File (EXCEPTION) - -Create wrapper component (`src/components/ShareButton.jsx`) ONLY for new projects or explicit requests: - -```jsx -"use client"; -import { useEffect, useRef } from "react"; -import SocialShareButton from "@aossie-org/social-share-button"; -import "@aossie-org/social-share-button/css"; - -export default function ShareButton({ style = "default", url, title, theme = "dark" }) { - const containerRef = useRef(null); - const instanceRef = useRef(null); - - useEffect(() => { - if (!containerRef.current) return; - instanceRef.current?.destroy?.(); - instanceRef.current = new SocialShareButton({ - container: containerRef.current, - buttonStyle: style, - url, - title, - theme, - }); - return () => instanceRef.current?.destroy?.(); - }, [style, url, title, theme]); - - return
; -} -``` - -#### CDN Method - -1. **Global Template**: - - **React (`public/index.html`)**: Add CDN stylesheet `` to `` and ` -``` - -#### npm Method — New Project / Dedicated File (EXCEPTION) - -Create component (`ShareButton.vue`) ONLY for new projects or explicit requests: - -```vue - - - ``` -#### CDN Method - -Add CDN `` to `` and ` ``` - **NPM Method**: Install dependency (`npm i @aossie-org/social-share-button`, `pnpm add`, `yarn add`, or `bun add`). ### 4. Ask User Placement & Style + - **Method Preference**: Always recommend **CDN** over NPM. - **Placement Prompting**: Ask the user explicitly: - Which file they want to import/place the Social Share button in. @@ -39,6 +46,7 @@ Integrate `@aossie-org/social-share-button` into a client web project with minim - **Style Options**: Prompt for preferred button style (`default` | `round` | `square`). ### 5. Inject Integration Code into Existing Files + - 🛑 **No New Files**: Inject directly into target existing file (e.g., `Header`, `Footer`, `page.tsx`). - **ESM Import**: `import SocialShareButton from "@aossie-org/social-share-button";` - **CSS Import**: `@aossie-org/social-share-button/css` @@ -49,23 +57,24 @@ Integrate `@aossie-org/social-share-button` into a client web project with minim ## Framework Integration Guides ### ⚛️ React / Next.js (NPM Method) + ```jsx "use client"; import { useEffect, useRef } from "react"; import SocialShareButton from "@aossie-org/social-share-button"; import "@aossie-org/social-share-button/css"; -export default function Header() { +export default function Header({ style = "default" }) { const shareContainerRef = useRef(null); useEffect(() => { if (!shareContainerRef.current) return; const shareInstance = new SocialShareButton({ container: shareContainerRef.current, - buttonStyle: "default", // default | round | square + buttonStyle: style, // selected style from Step 4 ("default" | "round" | "square") }); return () => shareInstance.destroy?.(); - }, []); + }, [style]); return (
@@ -80,27 +89,33 @@ export default function Header() { --- ### 🟣 Preact (NPM Method) + ```jsx import { useEffect, useRef } from "preact/hooks"; import SocialShareButton from "@aossie-org/social-share-button"; import "@aossie-org/social-share-button/css"; -export default function Footer() { +export default function Footer({ style = "default" }) { const containerRef = useRef(null); useEffect(() => { if (!containerRef.current) return; - const instance = new SocialShareButton({ container: containerRef.current, buttonStyle: "default" }); + const instance = new SocialShareButton({ container: containerRef.current, buttonStyle: style }); return () => instance.destroy?.(); - }, []); + }, [style]); - return
; + return ( +
+ +
+ ); } ``` --- ### 🟢 Vue 3 (NPM Method) + ```vue