mailto-copy: How a Tiny Extension Beats `mailto:` at the Capture Phase

A no-framework Chrome extension that intercepts email links before the browser opens your mail app, then copies the address with a fallback-safe clipboard flow.

6 min read • View on GitHub • More from T3-Content

A cursor clicks an underlined email link while the path splits into two directions. One route heads toward a desktop mail client icon, while the other is cut off early and redirected into a clipboard, showing how the extension intercepts the click before the default handler can act.
The extension does not replace `mailto:` after the fact. It gets there first.
Key Takeaways

The click never reaches the mail client

The clever part of mailto-copy is not that it copies text. It is that it intercepts the click before the browser can hand the event to the system’s mail handler. The extension registers early, listens in capture mode, and turns a default action into a clipboard action without asking the page for permission.

That sounds small because it is small. But small tools can solve big annoyances when they hit the exact layer where the annoyance lives. In this case, the layer is the browser event chain.

Why `mailto:` feels wrong in a web-first workflow

`mailto:` made sense when desktop mail was the default and browsers were just windows into the web. Today, plenty of people live in Gmail, Outlook.com, or a workflow where the right move is to copy an address, not launch an app they never meant to use.

That mismatch is why a tiny extension can earn its keep. It does not try to redesign email links. It just changes the first response to them.

ApproachWhat happens on clickWho controls the behaviorWorks across arbitrary sites?Clipboard-first?Maintainer complexity
Default `mailto:`Browser opens the registered mail appThe OS and browser default handlerYesNoNone
`mailto-copy`The address is copied, and the browser stays putThe extensionYesYesLow
Site-specific custom handlingThe site rewires its own email linksEach website authorOnly where implementedMaybeMedium to high
Manual copy and pasteThe user selects and copies the address by handThe userYesYesHigh friction

The contrast is useful because it shows the extension is not competing with another product so much as with inertia. It replaces a hardwired assumption with a deliberate choice.

How the extension wins the race

A close-up cross-section of browser event propagation shows a document-level net catching a click before it reaches the anchor below. The image explains why capture phase matters, because the listener sees the event before the browser or page script can react.
Capture phase is the whole trick. If you listen late, you are already behind.

An interactive event-race diagram shows how capture-phase listeners stop a `mailto:` click before it bubbles to the anchor’s default behavior.

The repo listens for `click`, `auxclick`, and keyboard activation on `document`, then uses capture mode so the extension sees the event before the anchor or the page script can handle it. That is why the extension works on more than a single narrow path. It catches mouse clicks, middle clicks, and keyboard-triggered activation with the same early interception.

Once it has the target, it uses the anchor’s `href`, strips the `mailto:` scheme, and ignores query strings like `subject=` when extracting the address. Then it tries the modern clipboard API first, and falls back to a hidden textarea plus `execCommand('copy')` if the modern path fails. That is not flashy. It is just careful.

Two clipboard mechanisms are shown hand to hand. The modern clipboard API stands in the foreground, while a hidden textarea and classic copy command wait behind it as a backup path. The image explains that the extension prefers modern APIs but still survives older or restricted environments.
The primary path is modern. The backup path keeps the tool usable when conditions are less friendly.

It is not just fast. It is careful.

The polish is easy to miss because the extension stays out of the way. But it is there in the details: keyboard support, toast feedback, timer cleanup, and a very high `zIndex` so the message sits above the site instead of inside it. Those are tiny choices that keep a tiny tool from feeling fragile.

It also defends against messy real-world click targets. The code uses `closest()` so an icon or span inside the link still resolves to the right anchor. That is the kind of thing that separates a demo from something you would actually install.

A minimal toolchain with a surprisingly complete finish

A single SVG logo enters a small hand-built assembly line and emerges as several icon sizes before being packed into an extension zip. The scene explains that the repo uses a minimal build script to generate assets and package the release without a framework.
The build is narrow, but it is complete. One source asset becomes a finished extension.

The build script reflects the same instinct as the runtime code. It reads the version from `manifest.json`, generates icons from a single `logo.svg`, and packages the extension with shell tooling instead of a JavaScript build stack. That choice is not just minimalism for its own sake. It keeps the repository legible.

That legibility matters because the project’s audience is not only end users. It is also anyone who wants to see how far native browser APIs can go before a framework enters the room.

What `mailto-copy` beats, and what it does not

OptionWhat it solves wellWhere it falls short
Default `mailto:`Launches the configured mail client immediatelyBad fit for people who want to copy addresses or use webmail
`mailto-copy`Turns an email click into a clipboard action across sitesOnly solves one narrow interaction
Site-specific email handlingCan be tailored to one product or workflowDoes not help on the rest of the web
Manual copy and pasteRequires no extension or site changeAdds friction every time

That narrowness is a feature. The project does not pretend to be an email platform, an inbox, or a UI framework. It solves one friction point cleanly, and that restraint is why it feels finished.