JavaScript | Web API:クリップボード・共有 - UX 改善パターン

JavaScript JavaScript
スポンサーリンク

クリップボード・共有の UX は「技術」より「気づかい」で差がつく

コピー・ペースト・共有って、
コード的にはどれも数行で書けます。

でも、「使っていて気持ちいいかどうか」
その数行の周りにある“気づかい”でほぼ決まります。

ここでは、初心者でもすぐ真似できて、
プロっぽい仕上がりになる UX 改善パターンを
具体例付きでまとめていきます。


パターン1:コピー後は「ちゃんと終わった」と分かるフィードバックを出す

無言で終わらせない。「コピーしました」を必ず見せる

コピー処理で一番多い悪いパターンは、

ボタンを押しても何も起きていないように見える

ことです。

ユーザーは

「本当にコピーされた?」
「押せてない?」

と不安になります。

なので、コピー成功時のフィードバックは必須です。

HTML:

<div id="code">npm install awesome-lib</div>
<button id="copyBtn">コピー</button>
<span id="copyMessage"></span>

JavaScript:

const codeEl = document.querySelector("#code");
const copyBtn = document.querySelector("#copyBtn");
const copyMessage = document.querySelector("#copyMessage");

copyBtn.addEventListener("click", async () => {
  if (!navigator.clipboard) {
    copyMessage.textContent = "コピー機能が使えません";
    return;
  }

  try {
    await navigator.clipboard.writeText(codeEl.textContent);
    copyMessage.textContent = "コピーしました";
    setTimeout(() => {
      copyMessage.textContent = "";
    }, 1500);
  } catch {
    copyMessage.textContent = "コピーに失敗しました";
  }
});
JavaScript

ここでの UX 的なポイントは、

押した瞬間に「コピーしました」と返す
短時間でメッセージを消して画面をすっきり保つ
失敗時はちゃんと「失敗した」と伝える

この 3 つです。

「押した → 反応が返ってきた」
この往復があるだけで、体感はかなり変わります。


パターン2:コピー対象を「視覚的に」分かりやすくする

どこがコピーされるのかを一目で分かるようにする

UX が悪いコピー機能の典型は、

「何がコピーされるのか分からないボタン」

です。

例えば、ページのどこかに「コピー」ボタンだけ置いてあって、
どのテキストが対象なのか分からない、という状態。

これを避けるには、

コピー対象のテキストを枠で囲む
背景色を変える
ボタンをすぐ横に置く

など、「ここがコピーされます」と
視覚的に示してあげるのが効果的です。

HTML:

<div style="border:1px solid #ccc;padding:8px;border-radius:4px;">
  <code id="snippet">git clone https://example.com/repo.git</code>
  <button id="copySnippetBtn" style="margin-left:8px;">コピー</button>
</div>
<span id="snippetMessage"></span>

JavaScript はさっきと同じように writeText を呼ぶだけですが、
「見た目の設計」が UX を大きく変えます。

コード的には小さな差でも、
ユーザー体験としてはかなり大きな差になります。


パターン3:環境に応じて「最適な共有手段」を出し分ける

スマホならネイティブ共有、PC なら URL コピー

同じ「共有」でも、
スマホと PC では“気持ちいいやり方”が違います。

スマホ:ネイティブ共有(Share API)が自然
PC:URL コピーして好きなアプリに貼るのが自然

これをコードで素直に表現すると、こうなります。

HTML:

<button id="shareBtn">共有</button>
<button id="copyUrlBtn" style="display:none;">URL をコピー</button>
<div id="status"></div>

JavaScript:

const shareBtn = document.querySelector("#shareBtn");
const copyUrlBtn = document.querySelector("#copyUrlBtn");
const status = document.querySelector("#status");

if (!navigator.share && navigator.clipboard) {
  // Share API がない環境では「URL コピー」ボタンを見せる
  shareBtn.style.display = "none";
  copyUrlBtn.style.display = "inline-block";
}

shareBtn.addEventListener("click", async () => {
  if (!navigator.share) return;

  try {
    await navigator.share({
      title: document.title,
      text: "このページ、よかったら見てみて!",
      url: location.href
    });
    status.textContent = "共有ダイアログを開きました";
  } catch {
    status.textContent = "共有はキャンセルされました";
  }
});

copyUrlBtn.addEventListener("click", async () => {
  if (!navigator.clipboard) {
    status.textContent = "コピー機能が使えません";
    return;
  }

  try {
    await navigator.clipboard.writeText(location.href);
    status.textContent = "URL をコピーしました";
  } catch {
    status.textContent = "コピーに失敗しました";
  }
});
JavaScript

「どの API が使えるか」を見て、
ユーザーにとって一番自然な手段を出す——
これだけで「ちゃんと考えられている感」が一気に出ます。


パターン4:失敗したときの“逃げ道”を用意しておく

API が使えなくても「何もできない」で終わらせない

Clipboard API や Share API は、
ブラウザや環境によっては使えないことがあります。

そのときに

「このブラウザでは使えません」

で終わると、ユーザーは詰みます。

代わりに、

「コピーできなかったので、下の URL を選択してコピーしてください」

といった“逃げ道”を用意しておくと、
UX はかなり優しくなります。

HTML:

<button id="copyUrlBtn">URL をコピー</button>
<div id="status"></div>
<div id="fallback" style="margin-top:8px;display:none;">
  コピーできない場合は、次の URL を選択してコピーしてください:<br>
  <code id="fallbackUrl"></code>
</div>

JavaScript:

const copyUrlBtn = document.querySelector("#copyUrlBtn");
const status = document.querySelector("#status");
const fallback = document.querySelector("#fallback");
const fallbackUrl = document.querySelector("#fallbackUrl");

fallbackUrl.textContent = location.href;

copyUrlBtn.addEventListener("click", async () => {
  if (!navigator.clipboard) {
    status.textContent = "自動コピーは使えません。手動でコピーしてください。";
    fallback.style.display = "block";
    return;
  }

  try {
    await navigator.clipboard.writeText(location.href);
    status.textContent = "URL をコピーしました";
  } catch {
    status.textContent = "自動コピーに失敗しました。手動でコピーしてください。";
    fallback.style.display = "block";
  }
});
JavaScript

「できません」で終わらせず、
「じゃあこうしてください」まで書く——
これが UX 的にはめちゃくちゃ効きます。


パターン5:ユーザーの“今の文脈”に合わせたメッセージを添える

「何を共有するのか」「なぜ共有するのか」を一言で伝える

共有ボタンの UX でよくある残念パターンは、

「共有」だけ書いてあって、何を共有するのか分からない

というものです。

例えば記事ページなら、

「この記事を共有」
「このレシピを共有」
「この結果を共有」

のように、対象を言葉にするだけで伝わり方が変わります。

さらに、Share API に渡す text
「なぜ送るのか」が伝わると気持ちいいです。

await navigator.share({
  title: "JavaScript 入門:クリップボード UX 編",
  text: "コピー・共有の UX 改善パターンがまとまっていたので共有します。",
  url: location.href
});
JavaScript

「ただのリンク」ではなく、
「こういう理由で送っている」という一言があるだけで、
受け取った側の理解度が全然違います。


まとめ:クリップボード・共有の UX を一段上げるチェックリスト

最後に、あなたの実装を見直すときの視点を整理します。

コピーしたとき、ユーザーは「成功した」と分かるか。
何がコピー/共有されるのか、見た目で一目で分かるか。
スマホと PC で、最適な手段(ネイティブ共有/URL コピー)を出し分けているか。
API が使えない・失敗したときに、「じゃあどうすればいいか」まで案内しているか。
ボタンのラベルや共有メッセージが、「何を」「なぜ」共有するかをちゃんと語っているか。

どれも難しいテクニックではなく、
「ユーザーの立場で 5 秒だけ想像してみる」 ところから生まれる工夫です。

まずは、あなたが今書いているコピー/共有ボタンを、
上のパターンを意識して 1 つだけでも改善してみてください。

同じ API を使っていても、
「雑な実装」と「気持ちいい実装」の差が、
自分の目でもはっきり見えてくるはずです。

タイトルとURLをコピーしました