Share Menu — Copy Link & Social Share Snippet

Share Menu with Copy Link and Social Options · Buttons · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Read-only input field for the URL, keeping it manually selectable even if the clipboard API fails
navigator.clipboard.writeText() with in-place button feedback — label and color change, no separate toast
Clipboard-unavailable fallback selects the URL text automatically for manual Ctrl/Cmd+C copying
Brand-colored social icons in a compact 2x2 grid for X, LinkedIn, Email, and WhatsApp
Centered dropdown positioning balanced under a compact trigger button
aria-haspopup and aria-expanded on the trigger for screen reader support
Closes on outside click and Escape via two independent listeners
Zero dependencies — pure HTML, CSS, and JavaScript

About this UI Snippet

Share Menu — Copy-Link Field with Clipboard Fallback and Social Options

Screenshot of the Share Menu with Copy Link and Social Options snippet rendered live

A share menu combines the two most common ways people actually share a link — copying the URL directly, and posting to a specific platform — into one compact dropdown, rather than the older pattern of a full row of always-visible social icons cluttering the page. This snippet builds both halves, plus the details that make each one work reliably.

The copy-link field

The URL sits in a read-only <input readonly>, not a plain <span> — using a real input means a user can still manually select and copy the text if the clipboard button fails for any reason, and readonly (rather than disabled) keeps it focusable and selectable while preventing edits. The Copy button calls navigator.clipboard.writeText(), which returns a promise, and on success swaps its own label to "Copied!" with a green background for 1.8 seconds before reverting — direct, in-place feedback rather than a separate toast notification.

The clipboard fallback

navigator.clipboard is only available in secure contexts (HTTPS or localhost) and can be blocked by browser permissions or older browsers entirely. The .catch() handler covers that case by calling input.select(), which highlights the URL text so the user can copy it manually with Ctrl/Cmd+C — a small status message explains what to do next. Skipping this fallback is a common reason "Copy" buttons silently do nothing for a subset of users.

Why the menu, not the whole page, holds the share options

Collapsing every share destination behind one "Share" trigger keeps the primary UI uncluttered, and it scales — adding a fifth or sixth platform to the grid costs one more .social-item button, not another permanently visible icon competing for space in the page header.

Centered dropdown positioning

Unlike a typical dropdown anchored to one edge, this menu centers itself under its trigger with left: 50%; transform: translateX(-50%), which looks more balanced for a compact, icon-led trigger button than a left- or right-anchored panel would.

Brand-colored social icons

Each platform's icon sits in a small rounded square using that platform's actual brand color (#000 for X, #0a66c2 for LinkedIn, #25d366 for WhatsApp) — consistent, recognizable brand colors help users find their preferred platform at a glance inside a 2×2 grid faster than uniformly-colored icons would.

Wiring real share URLs

The demo's shareTo() only logs which platform was clicked; a production version should open each platform's actual share-intent URL in a new tab or popup window. Common patterns: X is https://twitter.com/intent/tweet?url= + encoded URL + &text= + encoded message; LinkedIn is https://www.linkedin.com/sharing/share-offsite/?url= + encoded URL; Email is a plain mailto:?subject=...&body= link (no popup needed); WhatsApp is https://wa.me/?text= + encoded message with the URL included in the text.

Accessibility and dismissal

The trigger carries aria-haspopup="true" and aria-expanded, flipped by toggleMenu(). Two independent listeners close the menu — a document click check using closest('#shareWrap'), and an Escape keydown handler — the same dual dismissal pattern used by every other dropdown-style component in this library.

See also the copy button snippet for the standalone clipboard-copy pattern used here, and the download button for another action button with distinct idle/success feedback states.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Paste this share menu's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain why the copy button has a fallback path using input.select() rather than only relying on navigator.clipboard.writeText(), and in what real situations that fallback actually gets used. It's a strong candidate to hand to an assistant for real wiring — give it your page's actual URL source and a short share message, and have it fill in the real share-intent URLs for each platform button, opened via window.open() with sensible popup dimensions. Beyond that, ask it to add a check for navigator.share() so mobile browsers get the native OS share sheet instead of this custom menu when it's available, falling back to this component everywhere else.

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 button with a dropdown menu in plain HTML, CSS, and JavaScript, no framework, no libraries.

Requirements:
- A trigger button showing a share icon and label that toggles a dropdown menu below it, centered horizontally under the trigger rather than anchored to one edge, animated with an opacity and transform-based show/hide (not display:none, so it can transition smoothly) and reflecting its state via an aria-expanded attribute.
- Inside the dropdown, a read-only text input pre-filled with a URL, paired with a Copy button that uses the async clipboard API to copy the URL, gives in-place visual feedback on success (changing its own label and color temporarily before reverting), and falls back to selecting the input's text automatically if the clipboard API is unavailable or rejects, so the user always has a way to copy the value manually.
- Below the copy row, a 2x2 grid of at least four distinct social/share platform buttons, each with a small icon in that platform's real brand color and a text label, that when clicked would trigger sharing to that specific platform (a placeholder status message is sufficient for this demo, but the buttons must be individually distinguishable and clickable).
- The dropdown must close when the user clicks anywhere outside it and also when the Escape key is pressed, using two separate event listeners, and clicking any social share button must also close the dropdown.
- The whole component must be reachable and operable via keyboard alone: the trigger must be a real focusable button, and the copy and share buttons must be real buttons, not clickable divs.

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
    Copy the share-wrap structureThe .share-wrap holds the trigger button and the .menu dropdown containing the link-copy row and the social-icon grid.
  2. 2
    Set the real URLReplace the demo #linkInput value with your page's actual URL, generated dynamically from window.location.href if the menu is reused across many pages.
  3. 3
    Wire real share-intent URLsReplace the shareTo() logging with window.open() calls to each platform's share-intent URL, or a plain mailto: link for the Email option.
  4. 4
    Add or remove platformsEach platform is one .social-item button in the .social-grid — add a new one with its own brand-colored icon, or remove any that don't apply to your audience.
  5. 5
    Test the clipboard fallbackTry Copy in a non-HTTPS context or with clipboard permissions denied to confirm the input.select() fallback correctly highlights the URL for manual copying.

Real-world uses

Common Use Cases

Blog & Article Pages
Letting readers share a post directly to their preferred platform
Product & Landing Pages
Referral or word-of-mouth sharing, paired with a download button for the primary action
Snippet & Content Libraries
Sharing a specific item's permalink, similar to this share menu's own use on a UI snippets page
Event & Invite Pages
Sharing event details or invite links across social and messaging platforms

Got questions?

Frequently Asked Questions

It already does, via navigator.clipboard.writeText(input.value) — just replace the demo #linkInput value with your page's real URL, ideally set dynamically from window.location.href.

navigator.clipboard requires a secure context (HTTPS or localhost) and can be blocked by browser permission settings. The .catch() handler calls input.select() so the user can still copy the text manually, instead of the button silently failing with no feedback.

Replace the logging in shareTo() with window.open() calls to each platform's share-intent URL, built from your page URL and optionally a message — for example X uses https://twitter.com/intent/tweet?url=... and LinkedIn uses https://www.linkedin.com/sharing/share-offsite/?url=... Email can be a plain mailto: link.

navigator.share() is a good addition for mobile browsers that support it, since it opens the OS-native share sheet — check for its existence and offer it as an extra option, but keep this custom menu as the fallback for desktop browsers and platforms it does not cover.

Open the Export menu on the snippet page for a React component managing open state and clipboard copy as hooks, a React + Tailwind version, a Vue 3 SFC, or an Angular standalone component — all preserve the copy-fallback logic and outside-click/Escape dismissal.