Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@page-speed/social-share

Package Overview
Dependencies
Maintainers
2
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@page-speed/social-share

Performance-optimized social sharing component with inline, sticky, and combo variants for React applications.

latest
Source
npmnpm
Version
0.1.7
Version published
Maintainers
2
Created
Source

@page-speed/social-share

Performance-optimized social sharing component for React applications. Supports inline buttons, a scroll-aware sticky sidebar, or both combined with automatic native Web Share API integration on supported devices. Utilized extensively throughout the OpenSite Site Builder Platform.

Opensite Social Sharing React Component


npm version npm downloads TypeScript

Installation

pnpm add @page-speed/social-share
# or
npm install @page-speed/social-share

Peer dependencies

PackageVersion
react>=18.0.0
react-dom>=18.0.0
@opensite/hooks>=2.0.0

Quick start

import { SocialShare } from "@page-speed/social-share";

export default function BlogPost() {
  return (
    <SocialShare
      postTitle="My Blog Post"
      shareUrl="https://example.com/my-post"
      summaryContent="A short summary of the article for email sharing."
      imgUrls={["https://example.com/og-image.jpg"]}
      hashtags={["react", "webdev"]}
    />
  );
}

Exports

The package exposes four sub-path entry points for tree-shaking:

// Main entry -- everything
import { SocialShare, useMobileShare } from "@page-speed/social-share";
import type { SocialShareProps, ShareParams, ShareResult } from "@page-speed/social-share";

// Sub-path imports for smaller bundles
import { SocialShare } from "@page-speed/social-share/core";
import { useMobileShare } from "@page-speed/social-share/hooks";
import type { SocialShareProps } from "@page-speed/social-share/types";
Entry pointContents
.SocialShare, useMobileShare, all types
./coreSocialShare component + re-exported SocialShareProps type
./hooksuseMobileShare hook
./typesSocialShareProps, ShareParams, ShareResult type definitions

Component: SocialShare

The primary export. Renders social share buttons for X (Twitter), Facebook, Pinterest, LinkedIn, Email, and the native Web Share API.

Props (SocialShareProps)

PropTypeDefaultRequiredDescription
postTitlestring--YesTitle text used in share intents (tweet text, email subject, Pinterest description).
shareUrlstring--YesThe canonical URL to share.
summaryContentstring--YesShort summary included in the email body.
imgUrlsstring[]undefinedNoImage URLs. The first image is used for Pinterest media param. All images are attached to native share payloads when supported. Pinterest button only appears when at least one image is provided.
hashtagsstring[][]NoHashtags for X/Twitter (rendered without #, comma-separated).
variant"standard" | "sticky" | "combo""standard"NoLayout variant (see Variants below).
inlineSizenumber42NoWidth and height in pixels for each inline (standard) button. Icon size is automatically derived as half this value.
containerClassNamestring""NoAdditional CSS class applied to the outer <section> wrapper of the standard variant.
disableImageAttachmentsbooleanfalseNoWhen true, skips image fetching/conversion and does not attach images to native share payloads. Useful when images are behind auth or CORS restrictions.

Variants

"standard" (default)

Renders a horizontal row of circular share buttons inline with your content.

<SocialShare
  variant="standard"
  postTitle="My Post"
  shareUrl="https://example.com/post"
  summaryContent="Post summary"
/>

"sticky"

Renders a vertical floating sidebar on the right edge of the viewport. The bar appears after the user scrolls past 200px (or past a triggerRef element) and hides when a <footer> element comes into view. Rendered via ReactDOM.createPortal to avoid layout conflicts.

<SocialShare
  variant="sticky"
  postTitle="My Post"
  shareUrl="https://example.com/post"
  summaryContent="Post summary"
/>

"combo"

Renders both the standard inline buttons and the sticky sidebar simultaneously.

<SocialShare
  variant="combo"
  postTitle="My Post"
  shareUrl="https://example.com/post"
  summaryContent="Post summary"
/>

Adaptive behavior

The component automatically adapts to the device:

ContextBehavior
Mobile/tablet + touch + Web Share APIShows a single native share button (opens the OS share sheet).
Desktop + Web Share APIShows all social buttons plus a native share button at the end.
Desktop without Web Share APIShows social buttons only (X, Facebook, Pinterest, LinkedIn, Email).

Hook: useMobileShare

Low-level hook that wraps the Web Share API. Use this directly if you need custom share UI.

Parameters (ShareParams)

ParamTypeDefaultDescription
titlestring--Share title (required).
urlstringundefinedURL to share.
imageUrlsstring[]undefinedImage URLs to fetch, convert to base64, and attach as files.
imagesstring[]undefinedPre-converted base64 image strings (fallback when imageUrls is empty).
attachImagesbooleantrueWhen false, skips all image processing and never attaches files.

Return value (ShareResult)

FieldTypeDescription
share() => Promise<void>Trigger the native share dialog. Gracefully falls back to sharing without files if file sharing is unsupported.
canSharebooleantrue when navigator.share is available on the current device.
errorstring | nullError message from the last failed share attempt, or null.

Example

import { useMobileShare } from "@page-speed/social-share/hooks";

function CustomShareButton() {
  const { share, canShare, error } = useMobileShare({
    title: "Check this out",
    url: "https://example.com",
    imageUrls: ["https://example.com/photo.jpg"],
  });

  if (!canShare) return null;

  return (
    <>
      <button onClick={share}>Share</button>
      {error && <p>Error: {error}</p>}
    </>
  );
}

Supported platforms

Social share URL endpoints

PlatformEndpointParameters
X (Twitter)https://twitter.com/intent/tweettext, url, hashtags
Facebookhttps://www.facebook.com/sharer.phpu (URL only)
Pinteresthttps://pinterest.com/pin/create/buttonurl, media, description
LinkedInhttps://www.linkedin.com/sharing/share-offsite/url (title/description read from page OG tags)
Emailmailto:subject, body

Web Share API browser compatibility

BrowserSupport
Chrome 128+Full
Edge 104+Full
Safari 12.1+ (macOS), 12.2+ (iOS)Full
Samsung Internet 8.2+Full
Opera 114+Full
Firefox Android 147+Full
Firefox DesktopNot supported (experimental flag only)

When the Web Share API is unavailable, the component gracefully falls back to showing only the URL-based social buttons.

Styling

The component uses Tailwind CSS 4 with semantic design tokens from the @theme configuration. All styling is done via utility classes -- there are no inline <style> tags or CSS files to import.

Design tokens used

TokenUsage
bg-cardSticky bar background
text-card-foregroundIcon hover color
bg-mutedInline button background, sticky button hover pseudo-element
text-muted-foregroundIcon default color
border-borderSticky bar border

To customize the appearance, override these CSS custom properties in your theme. The component inherits all colors dynamically, making it compatible with light/dark mode and custom brand themes.

Performance

Bundle size

EntryRawGzipped
index.js (ESM)26.39 KB6.02 KB
core/index.js26.35 KB6.01 KB
hooks/index.js4.49 KB1.48 KB

Optimizations

  • Module-level constants -- All CSS class strings and share URL constants are hoisted outside components to eliminate per-render allocations.
  • useCallback throughout -- getSocialUrl, handleSocialShare, handleNativeShare, and the share function in useMobileShare are all stabilized with useCallback.
  • Pure utility extraction -- fetchBlob, urlToBase64, and dataURLtoFile are defined at module scope (not inside hooks), so they are never recreated.
  • Passive scroll listeners -- The sticky variant uses { passive: true } scroll event listeners for zero scroll-jank.
  • Portal rendering -- The sticky sidebar renders via ReactDOM.createPortal to avoid triggering parent re-layouts.
  • Image preloading -- Images are preloaded into the browser cache on mount so they are ready when the user clicks share.
  • Graceful degradation -- If IntersectionObserver is unavailable, the sticky bar shows immediately rather than breaking.
  • Tree-shakable -- Sub-path exports allow consumers to import only what they need. The package is marked "sideEffects": false.

Image handling

When imgUrls is provided and disableImageAttachments is false:

  • Images are preloaded into the browser cache via new Image() on component mount.
  • For native sharing, images are fetched as blobs and converted to base64 File objects.
  • S3 URLs matching the allowed bucket are fetched through a CORS proxy (/media_proxy). All other URLs use a direct fetch with no-cors fallback.
  • If file sharing is not supported by the device (checked via navigator.canShare), the share falls back to URL-only sharing automatically.

Set disableImageAttachments={true} to skip all image processing when images are behind authentication or when you want faster share interactions.

Architecture

src/
  index.ts              Main barrel export
  core/
    index.ts            Re-exports SocialShare + SocialShareProps
    social-share.tsx    SocialShare component + StickyShareBar subcomponent
  hooks/
    index.ts            Re-exports useMobileShare
    useMobileShare.tsx  Web Share API hook + image proxy utilities
  types/
    index.ts            Re-exports all type definitions
    social-share.ts     SocialShareProps, ShareParams, ShareResult

Build

Built with tsup. Outputs ESM + CJS with TypeScript declarations and source maps.

pnpm build          # Production build
pnpm dev            # Watch mode
pnpm type-check     # TypeScript validation (tsc --noEmit)
pnpm bundle-analysis # Print raw + gzipped sizes
pnpm test           # Run tests with Vitest

License

BSD-3-Clause

Keywords

react

FAQs

Package last updated on 11 Mar 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts