Copy Shortcode that copies, across every browser, including the old ones
A small copy button with a not-small browser-compatibility story. Clipboard API where it works, execCommand fallback where it does not, a friendly message when the table is so new the shortcode does not exist yet.
- Clipboard API detection with automatic fallback
- execCommand("copy") fallback for browsers without Clipboard API
- New tables show "Save table to generate shortcode" instead of an invalid ID
- Works in HTTP contexts where Clipboard API is silently disabled
Some bugs are flashy. Others are this kind:
“Hey, the copy button on the shortcode just… doesn’t do anything in Safari sometimes?”
That report kicked off a small investigation that ended up touching three browser APIs and a small UX win.
What was happening#
The Copy shortcode button used navigator.clipboard.writeText(...). That’s the modern, correct API. It works everywhere… that meets two conditions:
- The page is served over HTTPS (or localhost)
- The browser supports the API
Condition 1 catches more sites than people expect. Plenty of staging environments, intranet setups, and self-hosted WordPress installs run on HTTP. On those, navigator.clipboard is silently undefined, no error, no warning, just a button that does nothing.
Condition 2 catches a long tail of older browsers, including some WordPress admin scenarios where the embedded browser context isn’t quite a real browser.
What 4.1.2 ships#
Three layers of compatibility:
async function copyShortcode(text) {
// Layer 1: Modern Clipboard API (HTTPS + modern browser)
if (navigator.clipboard?.writeText) {
try {
await navigator.clipboard.writeText(text);
return true;
} catch {
// fall through to layer 2
}
}
// Layer 2: Legacy execCommand (works on HTTP, older browsers)
const ta = document.createElement('textarea');
ta.value = text;
ta.style.position = 'fixed';
ta.style.left = '-9999px';
document.body.appendChild(ta);
ta.select();
const ok = document.execCommand('copy');
document.body.removeChild(ta);
if (ok) return true;
// Layer 3: Show the user the text and ask them to copy manually
prompt('Copy this shortcode (Ctrl/Cmd+C):', text);
return false;
}
That’s the whole pattern. Not glamorous. Universally functional.
The bonus UX win#
While we were in the copy code, we noticed something silly. Brand new tables have no ID until they’re saved. The shortcode generator was rendering [gravity_table id=""], a syntactically valid but semantically nonsensical thing.
We changed it to: “Save table to generate shortcode” with the copy button disabled.
Tiny change. Stops new users from confidently copying a shortcode that does nothing.
What’s still on the roadmap#
The 4.2 line will replace the entire shortcode-builder UX with the visual shortcode builder that ships in TableCrafter (our sibling plugin). Live preview as you toggle features, click-to-copy, and a “use in Gutenberg” button. The 4.1.2 work is the foundation, once the new builder lands, every browser will copy correctly out of the gate.
Why the name “execCommand” survives#
document.execCommand("copy") is technically deprecated. Major browsers have committed to keeping it working forever, because the alternative, breaking copy on millions of HTTP-served sites, is unthinkable. The deprecation is a “we won’t add features” promise, not a “we’ll remove it” threat.
For Gravity Tables’ purposes, that’s perfect: a stable API that works in every context Clipboard API doesn’t. A reasonable architecture caters to both, that’s what 4.1.2 does.