Source Code

<div class="shm-page">
  <button type="button" class="shm-open" id="shmOpen">
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.6" y1="13.5" x2="15.4" y2="17.5"/><line x1="15.4" y1="6.5" x2="8.6" y2="10.5"/></svg>
    Share
  </button>
</div>

<div class="shm-backdrop" id="shmBackdrop"></div>
<div class="shm-modal" id="shmModal" role="dialog" aria-modal="true" aria-label="Share">
  <div class="shm-head">
    <h3>Share this article</h3>
    <button type="button" class="shm-close" id="shmClose" aria-label="Close">✕</button>
  </div>

  <div class="shm-targets" id="shmTargets"></div>

  <label class="shm-copy-label" for="shmLink">Or copy link</label>
  <div class="shm-copy">
    <input type="text" id="shmLink" readonly value="https://acme.io/blog/scaling-postgres">
    <button type="button" id="shmCopy">Copy</button>
  </div>

  <button type="button" class="shm-native" id="shmNative" hidden>
    <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"/><polyline points="16 6 12 2 8 6"/><line x1="12" y1="2" x2="12" y2="15"/></svg>
    More options…
  </button>
</div>

Share Modal — Social Share Sheet HTML CSS JS

Share Modal · Modals · Plain HTML, CSS & JS · Live preview

What's included

Features

Eight social share targets
Correct pre-filled intent URLs for X, Facebook, LinkedIn, WhatsApp, Reddit, Telegram, email, and Messenger.
Proper URL encoding per network
shareUrl() builds each network's specific format with correctly encoded url, title, and text.
Copy-link with fallback
A read-only link field copies via the Clipboard API with an execCommand fallback and a confirmation state.
Native Web Share enhancement
On supporting devices, a "More options…" button reveals the OS share sheet — shown only when available.
Sized share popups
Social links open in a 600×540 popup with noopener, the standard share-window behavior.
Data-driven targets
Networks come from a TARGETS array — add, remove, or reorder them with a data edit.
Single share-data source
One SHARE object (url, title, text) configures every target and the native sheet.
Accessible, animation-safe modal
role="dialog" with aria-modal, Escape/backdrop/close dismissal, and opacity/transform-only transitions.

About this UI Snippet

Share Modal — Social Share Sheet with Copy Link & Native Share Fallback

Screenshot of the Share Modal snippet rendered live

When a user wants to share your article, product, or page, a share modal gives them every option in one place — the social networks they actually use, a copy-link field, and on capable devices the native OS share sheet. This snippet builds that complete share dialog in plain HTML, CSS, and vanilla JavaScript: a grid of share targets with correct intent URLs, a one-click copy field, and progressive enhancement to the Web Share API.

Correct share URLs for every network

Each social target opens a pre-filled share intent — and every network has its own URL format with its own parameters. shareUrl() builds the right one for X, Facebook, LinkedIn, WhatsApp, Reddit, Telegram, email, and Messenger, properly URL-encoding the page URL, title, and text. Getting these formats exactly right (which parameter carries the URL vs the text, how each expects them encoded) is the tedious part that this snippet handles, so you don't have to look up eight different sharing endpoints. The links open in a sized popup window (width=600,height=540) with noopener for safety — the standard share-popup behavior.

A copy-link field for everything else

Not every share happens through a social button — people paste links into Slack, Notes, DMs, and a hundred other places. A read-only link field with a copy button covers all of that. The copy uses the modern navigator.clipboard API with a document.execCommand fallback for older or insecure-context browsers, and confirms with a green "✓ Copied" state so the user knows it worked. This is often the most-used option in a share modal, so it's given prominent placement rather than buried.

Native Web Share, progressively enhanced

On devices that support it (most mobile browsers and some desktop), the native OS share sheet is the best option — it offers the user's actual installed apps and contacts, which a fixed grid of web links can't. The snippet checks navigator.share and, only when present, reveals a "More options…" button that invokes the native sheet with the title, text, and URL. This is progressive enhancement done right: the web-link grid and copy field work everywhere, and the superior native option appears as a bonus exactly where it's available, never showing a broken button on browsers that lack it.

A polished, accessible modal

The dialog is role="dialog" with aria-modal="true", dims the page behind a backdrop, and closes via the ✕, a backdrop click, or Escape — all through one close(). It animates in with opacity and transform only, keeping it smooth across every framework export. The share targets are a responsive four-column grid of circular branded icons that scale slightly on hover, so the modal reads as a deliberate, app-quality share sheet rather than a row of plain links.

Data-driven targets

The share networks come from a TARGETS array (id, name, brand color, icon), so adding, removing, or reordering them — or matching the set to your audience — is a data edit. Pair that with the SHARE object (url, title, text) as the single source of what's being shared, and the whole modal is configured from two small pieces of data. Swap in your real page metadata and it's ready.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't need to look up eight different social share intent formats yourself. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why shareUrl builds a different query-parameter shape for each network, or how the navigator.share feature check hides the native share button entirely on devices that lack it rather than showing a broken control. The same assistant can help optimize it, for example checking whether the clipboard fallback path (execCommand) is still worth keeping given current browser support, or whether the eight-network TARGETS array should be trimmed for a specific audience. It's also useful for extending the feature: ask it to add a QR code target for sharing to a phone, track which network gets clicked most via an analytics event, or generate the SHARE object automatically from the page's own meta tags instead of a hardcoded object. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a share modal with social targets, a copy-link field, and native share fallback in plain HTML, CSS, and JavaScript, no framework, no libraries.

Requirements:
- A single SHARE object holding the url, title, and text being shared, used as the one source of truth for every share target and the copy field.
- A data-driven TARGETS array (id, display name, brand color, inline SVG icon) rendered into a grid of circular branded buttons via a single template-building function — adding a network must be a one-line data addition, not new markup.
- A function that builds the correct pre-filled share URL for at least six real networks (for example X/Twitter, Facebook, LinkedIn, WhatsApp, Reddit, email), with each network's URL and text parameters properly URL-encoded and assembled in that network's own specific query-string shape.
- Clicking a target must open its share URL in a new popup window sized roughly 600 by 540 pixels with the noopener flag set, not a full-tab navigation.
- A read-only text input showing the share URL plus a copy button that uses the Clipboard API (navigator.clipboard.writeText) with a document.execCommand fallback for browsers or contexts where the Clipboard API is unavailable, showing a temporary confirmation state on success.
- Feature-detect navigator.share and only reveal a native "more options" share button when it exists, wiring it to call navigator.share with the title, text, and url when present, and keeping it fully hidden (not just disabled) otherwise.
- The modal itself must be a real dialog: role="dialog", aria-modal="true", dismissible via a close button, a backdrop click, and the Escape key, animated only with opacity and transform so the transition works identically across every export target.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA "Share" button renders. Click it to open the share modal with social targets and a copy-link field.
  2. 2
    Share to a networkClick a social icon — a pre-filled share window opens for X, LinkedIn, WhatsApp, and the rest.
  3. 3
    Copy the linkClick Copy to copy the page URL; the button confirms with a green "✓ Copied" state.
  4. 4
    Try native shareOn a supporting device, a "More options…" button appears and opens the OS share sheet.
  5. 5
    Set what you're sharingEdit the SHARE object (url, title, text) and the link field value with your real page metadata.
  6. 6
    Customize the networksAdd, remove, or reorder entries in the TARGETS array to match your audience's platforms.

Real-world uses

Common Use Cases

Blog and article sharing
The share button under a post — pair with a helpful feedback widget to learn what resonates.
Product and listing pages
Let shoppers share a product across networks or copy the link to send directly.
Referral and invite flows
Share a referral link to social or copy it, complementing a waitlist signup referral loop.
Event and content promotion
Make it one tap to spread an event page or announcement.
Media and video pages
Offer share targets plus a copy link for embedding or sending privately.
Learning share-intent patterns
A reference for per-network share URLs and Web Share progressive enhancement — compare with a social share bar for the inline version.

Got questions?

Frequently Asked Questions

Edit the SHARE object — url is the page being shared, title is its headline, and text is an optional description. shareUrl() encodes these into each network's parameters, and the native Web Share call uses them directly. Also set the copy field's value to the same url. For dynamic pages, populate SHARE from your page metadata (og:title, canonical URL) when the modal opens.

navigator.share() opens the device's built-in share sheet — the same one native apps use — giving access to the user's installed apps and contacts. It's supported on most mobile browsers and some desktops. The snippet checks for it and only reveals the "More options…" button when present, so browsers without it never show a broken control. The web-link grid is the universal fallback.

Social share intents are designed to appear in a small popup window rather than a full tab — opening them with window.open(url, '_blank', 'width=600,height=540') matches each network's expected share dialog size and keeps the user's original page open behind it. Adding noopener prevents the opened page from accessing your window for security.

Use navigator.clipboard.writeText() (the modern async API) with a fallback that selects the input and calls document.execCommand('copy') for older browsers or insecure (non-HTTPS) contexts where the Clipboard API is unavailable. Always show a visual confirmation ("✓ Copied") so the user knows it succeeded regardless of which path ran.

In React, hold the open state in useState, render targets from the TARGETS array with .map(), and feature-detect navigator.share in a useEffect; in Vue, use ref() and v-for; in Angular, use a component field and *ngFor. The shareUrl() builder, clipboard logic, and Web Share detection are framework-agnostic — only the open/close state moves into the framework.