招待コードのコピー、共有 URL のワンクリックコピー、コードブロックのコピーボタンなど、クリップボードにテキストをコピーする機能はモダンな Web アプリで広く使われています。JavaScript では Clipboard API を使うのが推奨される方法です。
・Clipboard API(navigator.clipboard.writeText)の基本
・execCommand の旧方式とフォールバック
・HTTPS / localhost 制限と対処法
・コピー成功時のユーザーフィードバック(ボタン変更・トースト通知)
・readText でクリップボードから読み取る方法
・ClipboardItem でリッチコンテンツ(HTML・画像)をコピーする方法
・コードブロックのコピーボタン・共有 URL・招待コードの実務パターン
Clipboard API でテキストをコピーする(推奨)
navigator.clipboard.writeText() は、テキストをクリップボードにコピーするためのモダンで推奨される方法です。非同期(Promise)で動作し、エラーハンドリングも容易です。
async function copyToClipboard(text) {
try {
await navigator.clipboard.writeText(text);
console.log("コピーしました:", text);
} catch (err) {
console.error("コピーに失敗しました:", err);
}
}
// ボタンクリックでコピー
document.getElementById("copyBtn").addEventListener("click", () => {
copyToClipboard("コピーするテキスト");
});
input / textarea の値をコピーする
document.getElementById("copyBtn").addEventListener("click", async () => {
const text = document.getElementById("inputField").value;
await navigator.clipboard.writeText(text);
});
要素のテキストをコピーする
document.getElementById("copyBtn").addEventListener("click", async () => {
const text = document.getElementById("codeBlock").textContent;
await navigator.clipboard.writeText(text);
});
HTTPS / localhost 制限
Clipboard API はセキュリティ上の理由から、以下の条件でのみ動作します。
| 環境 | 動作 | 備考 |
|---|---|---|
| HTTPS | ○ 動作する | 本番環境の標準 |
| localhost | ○ 動作する | 開発環境 |
| HTTP(非 localhost) | × 動作しない | navigator.clipboard が undefined |
| file:// プロトコル | × 動作しない | ローカルファイルを直接開いた場合 |
navigator.clipboard が undefined になる場合は、後述の execCommand フォールバックを使ってください。execCommand によるフォールバック(旧方式)
document.execCommand("copy") は非推奨ですが、Clipboard API が使えない環境へのフォールバックとして有用です。
function fallbackCopyText(text) {
const textarea = document.createElement("textarea");
textarea.value = text;
// 画面外に配置(ちらつき防止)
textarea.style.position = "fixed";
textarea.style.left = "-9999px";
textarea.style.top = "-9999px";
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand("copy");
console.log("コピーしました(fallback)");
} catch (err) {
console.error("コピーに失敗しました:", err);
}
document.body.removeChild(textarea);
}
Clipboard API + フォールバックの統合関数
async function copyText(text) {
if (navigator.clipboard && window.isSecureContext) {
// Clipboard API が使える環境
await navigator.clipboard.writeText(text);
} else {
// フォールバック
fallbackCopyText(text);
}
}
window.isSecureContext で安全なコンテキスト(HTTPS / localhost)かどうかを判定できます。Clipboard API の可用性チェックに使いましょう。コピー成功時のユーザーフィードバック
コピーが成功したことをユーザーに伝えるフィードバックは UX の観点で重要です。
ボタンのテキストを一時的に変更する
const copyBtn = document.getElementById("copyBtn");
copyBtn.addEventListener("click", async () => {
const text = document.getElementById("code").textContent;
try {
await navigator.clipboard.writeText(text);
// ボタンテキストを変更
const original = copyBtn.textContent;
copyBtn.textContent = "コピーしました!";
copyBtn.disabled = true;
// 2秒後に元に戻す
setTimeout(() => {
copyBtn.textContent = original;
copyBtn.disabled = false;
}, 2000);
} catch (err) {
copyBtn.textContent = "コピー失敗";
}
});
トースト通知を表示する
function showToast(message, duration = 2000) {
const toast = document.createElement("div");
toast.className = "toast";
toast.textContent = message;
document.body.appendChild(toast);
// フェードインのため少し遅延
requestAnimationFrame(() => toast.classList.add("show"));
setTimeout(() => {
toast.classList.remove("show");
toast.addEventListener("transitionend", () => toast.remove());
}, duration);
}
.toast {
position: fixed;
bottom: 24px;
left: 50%;
transform: translateX(-50%) translateY(20px);
background: #333;
color: #fff;
padding: 12px 24px;
border-radius: 8px;
opacity: 0;
transition: opacity 0.3s ease, transform 0.3s ease;
z-index: 9999;
}
.toast.show {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
クリップボードから読み取る(readText)
navigator.clipboard.readText() でクリップボードの内容を読み取れます。ただし、ユーザーの許可ダイアログが表示されます。
async function pasteFromClipboard() {
try {
const text = await navigator.clipboard.readText();
console.log("クリップボードの内容:", text);
return text;
} catch (err) {
console.error("読み取りに失敗:", err);
return null;
}
}
readText はユーザーの許可が必要です。ユーザーが拒否した場合は DOMException: Read permission denied エラーが発生します。writeText(コピー)は許可なしで動作します。ClipboardItem でリッチコンテンツをコピーする
navigator.clipboard.write() と ClipboardItem を使うと、プレーンテキスト以外の形式(HTML、画像など)もクリップボードにコピーできます。
async function copyHTML(htmlString) {
const blob = new Blob([htmlString], { type: "text/html" });
const item = new ClipboardItem({ "text/html": blob });
await navigator.clipboard.write([item]);
}
// 太字テキストとしてコピー
copyHTML("<strong>重要なお知らせ</strong>");
// → Word や Gmail に貼り付けると太字で表示される
| メソッド | コピー対象 | 用途 |
|---|---|---|
writeText(text) |
プレーンテキスト | 一般的なテキストコピー |
write([ClipboardItem]) |
HTML・画像・複数形式 | リッチテキスト・スクリーンショット |
実務でよく使うパターン
コードブロックにコピーボタンを追加する
document.querySelectorAll("pre").forEach(pre => {
const btn = document.createElement("button");
btn.className = "copy-btn";
btn.textContent = "コピー";
btn.addEventListener("click", async () => {
await navigator.clipboard.writeText(pre.textContent);
btn.textContent = "コピー済み";
setTimeout(() => btn.textContent = "コピー", 2000);
});
// pre の親要素に相対配置を設定してボタンを右上に配置
pre.style.position = "relative";
btn.style.cssText = "position:absolute;top:8px;right:8px;";
pre.appendChild(btn);
});
現在のページ URL をコピーする
document.getElementById("shareBtn").addEventListener("click", async () => {
await navigator.clipboard.writeText(window.location.href);
showToast("URLをコピーしました");
});
招待コード / クーポンコードをコピーする
<div class="coupon"> <span id="couponCode">SAVE20OFF</span> <button id="copyCoupon">コピー</button> </div>
document.getElementById("copyCoupon").addEventListener("click", async () => {
const code = document.getElementById("couponCode").textContent;
await navigator.clipboard.writeText(code);
const btn = document.getElementById("copyCoupon");
btn.textContent = "コピー済み ✓";
setTimeout(() => btn.textContent = "コピー", 2000);
});
関連記事
- クリックイベントの設定方法 — addEventListener・イベント委任
- setTimeout の使い方 — 遅延実行
- HTML 要素を追加・削除する方法
- getAttribute の使い方
- classList の使い方完全ガイド
よくある質問
navigator.clipboard が undefined になります。window.isSecureContext で判定し、非安全な環境では execCommand フォールバックを使ってください。writeText はプレーンテキスト専用で簡単に使えます。write は ClipboardItem を使って HTML や画像などリッチコンテンツもコピーできます。通常のテキストコピーには writeText で十分です。まとめ
JavaScript でクリップボードにコピーする方法を整理しました。
- 推奨:
navigator.clipboard.writeText(text)(非同期・シンプル) - フォールバック:
execCommand("copy")(HTTP 環境向け・非推奨) - 統合関数:
isSecureContextで判定して自動切り替え - HTTPS 制限: Clipboard API は安全なコンテキストでのみ動作
- フィードバック: ボタンテキスト変更 or トースト通知
- リッチコンテンツ:
ClipboardItemで HTML・画像もコピー可能
コードブロックのコピーボタンや共有 URL のコピーは、ユーザー体験を大きく向上させる定番機能です。Clipboard API + フォールバックの統合関数を用意しておけば、あらゆる環境に対応できます。