Skip to content
Gravity Tables
patch v4.1.2 · · 2 min read

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:

  1. The page is served over HTTPS (or localhost)
  2. 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.

#copy-button#browser-compat#shortcode