Skip to content
ilinxa/pro-ui

Share Bar

alphav0.2.0

Social share button row — nine built-in platforms, custom targets, and copy-link with success feedback.

Category: MarketingUpdated: 2026-08-11Created: 2026-05-02Author: ilinxa

Context

Reach for it on news article footers, blog post footers, product page social rows, video player share clusters, doc page share affordances. Built-in URL templates for Twitter / Facebook / LinkedIn / Reddit / WhatsApp / Telegram / Email / Threads / Bluesky. Copy-link button uses navigator.clipboard with execCommand fallback for older / insecure-context browsers; success/error feedback is visual (icon flip) + audible (aria-live). Custom targets via 'kind: custom' with arbitrary onClick. Analytics hook via onShare(targetKind). SSR-safe — window.location.href read at click time, not render time.

Installation

Initialize shadcn (once per project)Seeds lib/utils.ts and components.json. Skip if you've already used any shadcn component.
pnpm dlx shadcn@latest init
Register the @ilinxa namespace (once per project)Add to your components.json. Merge with existing config.
"registries": {
  "@ilinxa": "https://ui.ilinxa.com/r/{name}.json"
}
Install the component
pnpm dlx shadcn@latest add @ilinxa/share-bar

Add -fixtures for dummy data:

pnpm dlx shadcn@latest add @ilinxa/share-bar-fixtures

Preview

Share

Click Copy link — icon flips to a check for 2s.

Demo source

demo.tsxtsx

Usage

When to use

A horizontal cluster of social-share buttons + a copy-link button, typically at the bottom of an article (or pinned to the side as a share rail). Each social button opens the platform's share intent in a new window with the page's URL prefilled; the copy button writes the URL to the clipboard with a 2-second visual + audible success affordance.

Basic example

import { ShareBar } from "@/components/share-bar"

export function ArticleFooter() {
  return (
    <ShareBar
      url="https://example.com/news/sustainable-cities"
      title="Sustainable cities, then and now"
      headingAs="h4"
      divider
      targets={[
        { kind: "twitter" },
        { kind: "facebook" },
        { kind: "linkedin" },
        { kind: "copy" },
      ]}
    />
  )
}

Built-in platforms

Twitter / Facebook / LinkedIn / Reddit / WhatsApp / Telegram / Email / Threads / Bluesky — each ships with a share-intent URL template + a default Lucide icon + a default English aria-label. Override the icon or aria-label per target if you want a different look or different text.

Custom targets

import { Send } from "lucide-react"

<ShareBar
  url={article.canonicalUrl}
  targets={[
    { kind: "twitter" },
    { kind: "linkedin" },
    {
      kind: "custom",
      id: "send-to-teammate",
      icon: Send,
      ariaLabel: "Send to teammate",
      onClick: () => openInternalShareDialog(article.id),
    },
    { kind: "copy" },
  ]}
/>

Analytics hook

<ShareBar
  targets={[{ kind: "twitter" }, { kind: "facebook" }, { kind: "copy" }]}
  onShare={(target) => analytics.track("article.share", { id: article.id, target })}
/>

onShare(targetKind) fires after a successful share-intent open or successful copy. For granular hooks use onCopySuccess / onCopyError.

URL resolution

  • If urlis provided, that's what gets shared.
  • Otherwise, window.location.href is read at click time on the client — never during render. SSR-safe.
  • Pass title / text / via / hashtags for templates that accept them (Twitter, Email, WhatsApp, etc.).

Copy fallback

Copy uses navigator.clipboard.writeTextfirst; if that isn't available (older browsers, insecure HTTP context, embedded webviews), it falls back to the deprecated document.execCommand("copy") on a hidden textarea. Both paths are inside a try/catch so the error state surfaces to onCopyError + the icon flip.

Notes

  • External links open in a new window with noopener,noreferrer for safety.
  • Copy success/error feedback is dual-channel: visible icon flip + aria-live announcement (polite for success, alert for errors).
  • The 2-second success-reset timeout is cleared on unmount — no setState after unmount warning.
  • Threads + Bluesky icons fall back to Share2 from lucide-react until first-party icons land. Override via target.icon if you ship custom SVGs.
  • The component is exported as React.memo. Memoize the targets array (or use a module-level constant) for the memo to bite — inline arrays defeat it.
  • Don't reach for this if you need share-count metrics — pure action surface, no API calls.

Features

  • 9 built-in platforms with URL templates (Twitter / Facebook / LinkedIn / Reddit / WhatsApp / Telegram / Email / Threads / Bluesky)
  • Copy-link button with success/error feedback (icon flip + aria-live)
  • Clipboard fallback to document.execCommand for older / insecure browsers
  • Custom targets via 'kind: custom' (arbitrary icon + onClick)
  • Analytics hook via onShare(targetKind)
  • Configurable URL / title / text / via / hashtags
  • Optional section heading (h2 / h3 / h4) with i18n labels
  • Optional top divider (`pt-8 border-t border-border`)
  • External links use target=_blank rel=noopener,noreferrer
  • Memoized; SSR-safe; <ul>/<li> semantics

Tags

share-barsharesocialcopy-linktwitterfacebooklinkedinmarketing

Dependencies

shadcn primitives: button
npm peer deps: lucide-react@^1.11.0