📋

【Arc】Arc Windowsでnavigator.clipboard.writeTextが動かない時の対処法

に公開

TL;DR

  • Arc Browser(Windows版)で navigator.clipboard.writeText が正常に動作しない問題に遭遇
  • コンソールでは正しく値が取れているのに、クリップボードには一部しかコピーされない
  • document.execCommand('copy') を使うことで解決

はじめに

Arc Browser(Windows版)を使ってブックマークレット or スクリプトを作成してみようかなと思っていたときに、クリップボード周りで予期しない動作に遭遇したので、その備忘録です。
Arcはブックマークの概念が存在しないため、最終的にコンソールからのスクリプト実行に落ち着きました。よりよい方法・問題点があればご指摘ください。

遭遇した問題

Webページから複数の情報を取得してクリップボードにコピーするブックマークレットを作成しました。

(function(){
  const text1 = document.querySelector('.some-class')?.innerText?.trim() || '取得失敗';
  const text2 = window.location.href;
  const result = `情報1: ${text1}\n情報2: ${text2}`;
  
  navigator.clipboard.writeText(result).then(() => {
    alert('コピー完了!\n\n' + result);
  });
})();

症状

  • コンソールで console.log(result) すると正しく全ての情報が表示される
  • アラートでも全文が表示される
  • しかし実際にクリップボードにコピーされるのは最初の1行だけ
  • エラーは出ない
# 期待する結果
情報1: サンプルテキスト
情報2: https://example.com/page

# 実際にコピーされた内容
情報1: サンプルテキスト

デバッグプロセス

1. 変数の中身を確認

(function(){
  const text1 = document.querySelector('.some-class')?.innerText?.trim() || '取得失敗';
  const text2 = window.location.href;
  const result = `情報1: ${text1}\n情報2: ${text2}`;
  
  console.log('--- デバッグ情報 ---');
  console.log('text1:', text1);
  console.log('text2:', text2);
  console.log('result:', result);
  console.log('result length:', result.length);
  console.log('改行を含む:', result.includes('\n'));
})();

結果:

text1: サンプルテキスト
text2: https://example.com/page
result: 情報1: サンプルテキスト
情報2: https://example.com/page
result length: 73
改行を含む: true

変数には正しく全文が入っている → Clipboard APIの問題???

2. 改行コードを変更してみる

Windows環境では \r\n が必要かと思い試してみましたが、改善せず。

const result = '情報1: ' + text1 + '\r\n情報2: ' + text2;

解決方法:document.execCommand を使う

Arc WindowsのClipboard API実装に問題があるようなので、古い方式の document.execCommand('copy') を使うことで解決しました。

修正後のコード

(function(){
  const text1 = document.querySelector('.some-class')?.innerText?.trim() || '取得失敗';
  const text2 = window.location.href;
  const result = '情報1: ' + text1 + '\r\nURL: ' + text2;
  
  // 一時的なtextarea要素を作成
  const textarea = document.createElement('textarea');
  textarea.value = result;
  textarea.style.position = 'fixed';
  textarea.style.opacity = '0';
  document.body.appendChild(textarea);
  textarea.select();
  
  try {
    const success = document.execCommand('copy');
    if (success) {
      alert('コピー完了!\n\n' + result);
    } else {
      prompt('以下を手動でコピーしてください:', result);
    }
  } catch (err) {
    prompt('以下を手動でコピーしてください:', result);
  } finally {
    document.body.removeChild(textarea);
  }
})();

ポイント

  1. 非表示のtextarea要素を作成

    • position: fixedopacity: 0 で画面に表示させない
  2. select() でテキストを選択状態にする

    • これがないとコピーできない
  3. execCommand('copy') で確実にコピー

    • 戻り値で成功/失敗を判定できる
  4. 最後に要素を削除

    • finally で確実にクリーンアップ

より堅牢な実装:両方試す

Clipboard APIが使える環境では使い、ダメならフォールバックする方式:

(function(){
  const text1 = document.querySelector('.some-class')?.innerText?.trim() || '取得失敗';
  const text2 = window.location.href;
  const result = '情報1: ' + text1 + '\r\n情報2: ' + text2;
  
  // 方法1: Clipboard API(モダン)
  if (navigator.clipboard && navigator.clipboard.writeText) {
    navigator.clipboard.writeText(result)
      .then(() => {
        alert('コピー完了!\n\n' + result);
      })
      .catch(() => {
        fallbackCopy();
      });
  } else {
    // 方法2: execCommand(古いが確実)
    fallbackCopy();
  }
  
  function fallbackCopy() {
    const textarea = document.createElement('textarea');
    textarea.value = result;
    textarea.style.position = 'fixed';
    textarea.style.opacity = '0';
    document.body.appendChild(textarea);
    textarea.select();
    
    try {
      document.execCommand('copy');
      alert('コピー完了!\n\n' + result);
    } catch (err) {
      prompt('以下を手動でコピーしてください:', result);
    } finally {
      document.body.removeChild(textarea);
    }
  }
})();

ブックマークレット化

Arc Windowsのブックマークレットの設定方法が分かりません。今回は趣味程度だったので、ここまで。時間があったら調査してみようと思います。
他のブラウザでは、使用可能かもしれません。

上記のコードを1行に圧縮してブックマークのURLに設定:

javascript:(function(){const text1=document.querySelector('.some-class')?.innerText?.trim()||'取得失敗';const text2=window.location.href;const result='情報1: '+text1+'\r\n情報2: '+text2;const textarea=document.createElement('textarea');textarea.value=result;textarea.style.position='fixed';textarea.style.opacity='0';document.body.appendChild(textarea);textarea.select();try{const success=document.execCommand('copy');if(success){alert('✅ コピー完了!\n\n'+result);}else{prompt('以下を手動でコピーしてください:',result);}}catch(err){prompt('以下を手動でコピーしてください:',result);}finally{document.body.removeChild(textarea);}})();

応用例

このテクニックは様々な場面で使えます(参考程度にどうぞ):

例1:ページタイトルとURLをコピー

javascript:(function(){const title=document.title;const url=window.location.href;const text=title+'\n'+url;const t=document.createElement('textarea');t.value=text;t.style.position='fixed';t.style.opacity='0';document.body.appendChild(t);t.select();document.execCommand('copy');document.body.removeChild(t);alert('コピー完了!\n\n'+text);})();

例2:選択したテキストにURLを追加

javascript:(function(){const selected=window.getSelection().toString();const url=window.location.href;const text=selected+'\n\n出典: '+url;const t=document.createElement('textarea');t.value=text;t.style.position='fixed';t.style.opacity='0';document.body.appendChild(t);t.select();document.execCommand('copy');document.body.removeChild(t);alert('引用をコピーしました');})();

例3:複数の要素を一括コピー

javascript:(function(){const items=Array.from(document.querySelectorAll('.item-title')).map(el=>el.innerText).join('\n');const t=document.createElement('textarea');t.value=items;t.style.position='fixed';t.style.opacity='0';document.body.appendChild(t);t.select();document.execCommand('copy');document.body.removeChild(t);alert(items.split('\n').length+'件コピーしました');})();

なぜこの問題が起きるのか

【確認方法】Clipboard APIが使えるブラウザか?

コンソールにて実行してみました。

'navigator.clipboard' in navigator // → true/false

結果→false

Clipboard APIの仕様

navigator.clipboard.writeText は比較的新しいAPIで、ブラウザによって実装が異なります。

  • 権限管理が厳格:ユーザーの明示的な操作が必要
  • セキュリティ制約:HTTPS必須、一部の環境では制限あり
  • 実装の差:ブラウザごとに挙動が異なる

Arc Browser(特にWindows版)は独自のセキュリティポリシーにより、Clipboard APIの動作が標準と異なる可能性があります。
(Chromiumのフォークの具合もある??)

execCommandの利点

  • 古い技術:ほぼ全てのブラウザで動作
  • 権限不要:ユーザー操作なしでも動作
  • 確実性:戻り値で成功/失敗を判定可能

ただし、execCommandは 非推奨(deprecated) なので、将来的には使えなくなる可能性があります。

まとめ

  • Arc Windowsでは navigator.clipboard.writeText が正常に動作しないケースがある
  • document.execCommand('copy') を使えば確実にコピーできる
  • 両方を組み合わせてフォールバックする実装が最も堅牢
  • ブックマークレットとして活用すれば、様々な作業を効率化できる

現在Arcの後継であるDiaがMacのみしか使えないので、Windows版も使用してみたいですね。

参考

Discussion