-
-
Notifications
You must be signed in to change notification settings - Fork 41
feat: intelligent content auto-detection for SocialShareButton #102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 12 commits
d0c006e
9d1915d
cc978f9
b945be5
791cb88
3af667b
d9711f6
8514bc4
8ef5c06
3a16f90
c8362a6
f6623be
f0ef976
0557ea4
ebd693a
ee0366b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,51 +1,54 @@ | ||
| import { useEffect, useRef } from "react"; | ||
| 'use client'; | ||
|
|
||
| import { useEffect, useRef } from 'react'; | ||
|
|
||
| // Import SocialShareButton directly for ESM bundles, fall back to window for CDN | ||
| import SocialShareButtonCore from './social-share-button.js'; | ||
|
|
||
| export const SocialShareButton = ({ | ||
| url, | ||
| title, | ||
| description = "", | ||
| description, | ||
| hashtags = [], | ||
| via = "", | ||
| platforms = [ | ||
| "whatsapp", | ||
| "facebook", | ||
| "twitter", | ||
| "linkedin", | ||
| "telegram", | ||
| "reddit", | ||
| ], | ||
| theme = "dark", | ||
| buttonText = "Share", | ||
| customClass = "", | ||
| via = '', | ||
| platforms = ['whatsapp', 'facebook', 'twitter', 'linkedin', 'telegram', 'reddit'], | ||
| theme = 'dark', | ||
| buttonText = 'Share', | ||
| customClass = '', | ||
| onShare = null, | ||
| onCopy = null, | ||
| buttonStyle = "default", | ||
| modalPosition = "center", | ||
| buttonStyle = 'default', | ||
| modalPosition = 'center', | ||
| // Content auto-detection β set to false when all props are always provided. | ||
| autoDetect = true, | ||
| // Analytics props β the library itself never collects data. | ||
| // Provide any combination to connect your own analytics tools. | ||
| analytics = true, // set to false to disable all event emission | ||
| onAnalytics = null, // (payload) => void β direct callback hook | ||
| analyticsPlugins = [], // array of adapter instances (see social-share-analytics.js) | ||
| componentId = null, // optional string identifier for this instance | ||
| debug = false, // log events to console during development | ||
| analytics = true, // set to false to disable all event emission | ||
| onAnalytics = null, // (payload) => void β direct callback hook | ||
| analyticsPlugins = [], // array of adapter instances (see social-share-analytics.js) | ||
| componentId = null, // optional string identifier for this instance | ||
| debug = false, // log events to console during development | ||
| }) => { | ||
| const containerRef = useRef(null); | ||
| const shareButtonRef = useRef(null); | ||
|
|
||
| // Auto-detect current URL and title if not provided | ||
| const currentUrl = | ||
| url || (typeof window !== "undefined" ? window.location.href : ""); | ||
| const currentTitle = | ||
| title || (typeof document !== "undefined" ? document.title : ""); | ||
| // Resolve URL β fall back to current page URL but leave title/description | ||
| // undefined when not provided so the core SocialShareButton auto-detection | ||
| // priority chain (og:title β twitter:title β h1 β document.title etc.) runs. | ||
| const currentUrl = url || (typeof window !== 'undefined' ? window.location.href : ''); | ||
|
|
||
| useEffect(() => { | ||
| if (containerRef.current && !shareButtonRef.current) { | ||
| if (typeof window !== "undefined" && window.SocialShareButton) { | ||
| shareButtonRef.current = new window.SocialShareButton({ | ||
| // Use imported class for ESM bundles, fall back to window for CDN script tags | ||
| const ShareButtonConstructor = | ||
| SocialShareButtonCore || (typeof window !== 'undefined' ? window.SocialShareButton : null); | ||
|
|
||
| if (ShareButtonConstructor) { | ||
| // Only include title/description in the options object when explicitly | ||
| // provided β omitting them lets the core detector's priority chain run. | ||
| const initOptions = { | ||
| container: containerRef.current, | ||
| url: currentUrl, | ||
| title: currentTitle, | ||
| description, | ||
| hashtags, | ||
| via, | ||
| platforms, | ||
|
|
@@ -56,12 +59,16 @@ export const SocialShareButton = ({ | |
| onCopy, | ||
| buttonStyle, | ||
| modalPosition, | ||
| autoDetect, | ||
| analytics, | ||
| onAnalytics, | ||
| analyticsPlugins, | ||
| componentId, | ||
| debug, | ||
| }); | ||
| }; | ||
| if (title !== undefined) initOptions.title = title; | ||
| if (description !== undefined) initOptions.description = description; | ||
| shareButtonRef.current = new ShareButtonConstructor(initOptions); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -73,13 +80,29 @@ export const SocialShareButton = ({ | |
| }; | ||
| }, []); | ||
|
|
||
| // Update options when props change (including URL from route changes) | ||
| // Update options when props change (including URL from route changes). | ||
| // Also bust the content-detection cache so the new page's metadata is used. | ||
| useEffect(() => { | ||
| if (shareButtonRef.current) { | ||
| shareButtonRef.current.updateOptions({ | ||
| // Invalidate detection cache on every route/prop change so the new | ||
| // page content is picked up when autoDetect is enabled. | ||
| if (autoDetect) { | ||
| const ShareButtonConstructor = | ||
| SocialShareButtonCore || | ||
| (typeof window !== 'undefined' ? window.SocialShareButton : null); | ||
|
|
||
| if ( | ||
| ShareButtonConstructor && | ||
| typeof ShareButtonConstructor.clearContentCache === 'function' | ||
| ) { | ||
| // Pass the current URL so only this page's cache entry is cleared, | ||
| // rather than wiping the entire global cache shared across instances. | ||
| ShareButtonConstructor.clearContentCache(currentUrl); | ||
| } | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
Comment on lines
+83
to
+102
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cache clearing before The intent here is good: clear the cache so fresh page metadata can be detected on route changes. However, as noted in the This means:
This should be addressed in π€ Prompt for AI Agents |
||
|
|
||
| const updateOpts = { | ||
| url: currentUrl, | ||
| title: currentTitle, | ||
| description, | ||
| hashtags, | ||
| via, | ||
| platforms, | ||
|
|
@@ -90,16 +113,20 @@ export const SocialShareButton = ({ | |
| onCopy, | ||
| buttonStyle, | ||
| modalPosition, | ||
| autoDetect, | ||
| analytics, | ||
| onAnalytics, | ||
| analyticsPlugins, | ||
| componentId, | ||
| debug, | ||
| }); | ||
| }; | ||
| if (title !== undefined) updateOpts.title = title; | ||
| if (description !== undefined) updateOpts.description = description; | ||
| shareButtonRef.current.updateOptions(updateOpts); | ||
| } | ||
| }, [ | ||
| currentUrl, | ||
| currentTitle, | ||
| title, | ||
| description, | ||
| hashtags, | ||
| via, | ||
|
|
@@ -111,6 +138,7 @@ export const SocialShareButton = ({ | |
| onCopy, | ||
| buttonStyle, | ||
| modalPosition, | ||
| autoDetect, | ||
| analytics, | ||
| onAnalytics, | ||
| analyticsPlugins, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.