Popup インターフェース設計と Options 保存状態

ユーザーが拡張機能をインストールした後、最も頻繁に操作する場所はブラウザの右上にあるアイコンです。このアイコンをクリックして表示される小さなウィンドウを Popup と呼びます。また、ユーザーが高度なアカウント連携やパラメータ調整が必要な場合、通常は独立したフルスクリーンのウェブページに誘導します。これを Options Page と呼びます。

このレッスンでは、これら2つの最も重要なUIインターフェースを設計し、ユーザーの設定を記憶させる方法を学びます。

1. 美しい Popup ウィンドウの作成

manifest.json では、action.default_popup を使用してポップアップウィンドウのHTMLファイルを指定します。

このHTMLファイルは通常のウェブ開発と全く同じです。CSSフレームワーク(Tailwind CSSのCDNやバンドルされたファイル)を導入したり、React/Vueなどのフロントエンドフレームワークを使用して記述することもできます。

[!WARNING] CSP (コンテンツセキュリティポリシー) 制限 Chrome Extension には非常に厳しいセキュリティ制限があります。HTMLに直接 <script> alert(1); </script> のようなインラインスクリプトを記述することはできません。すべてのJavaScriptは外部ファイル (<script src="popup.js"></script>) として導入する必要があります。

現在のタブ情報の動的取得

Popup の最も一般的な機能は、「ユーザーが現在見ているウェブページ」を操作することです。現在のタブ情報を取得するには、chrome.tabs APIを使用できます:

// popup.js
document.addEventListener('DOMContentLoaded', async () => {
  // 現在アクティブで現在のウィンドウにあるタブをクエリ
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
  
  if (tab) {
    const urlDisplay = document.getElementById('url-display');
    urlDisplay.innerText = tab.url; // ポップアップインターフェースにURLを表示
  }
});

注意:このAPIを呼び出すには、manifestで "activeTab" または "tabs" 権限を申請する必要があります。

2. Options 設定ページの実装

拡張機能でユーザーにAPIキーの入力、カラーテーマの選択、またはブラックリストの設定が必要な場合、小さなPopupでは不十分です。専用の設定ページを作成する必要があります。

まず、manifest.json でOptionsページを宣言します:

{
  "options_ui": {
    "page": "options.html",
    "open_in_tab": true
  }
}

open_in_tab: true を設定すると、このページは新しい大きなタブで開かれ、体験が大幅に向上します。

3. chrome.storage を使用したユーザー設定の保存

PopupやOptionsページでユーザーが設定を変更した場合、これらの設定を保存して、次回ブラウザを開いたときに設定が消えないようにする必要があります。

拡張機能では、localStorage使用しません。なぜなら、ブラウザデータをクリアする際に簡単に削除されてしまうためです。また、異なるコンテキスト(Popup、Content Script、Background)間で共有するのが難しいためです。

代わりに、chrome.storage APIを使用する必要があります。主に2つのモードがあります:

  • chrome.storage.local:データはこのコンピュータにのみ存在します。容量上限は5MB(無制限に申請可能)。
  • chrome.storage.sync:データはユーザーのGoogleアカウントに自動的に同期され、他のコンピュータでも利用可能です!容量上限は小さい(100KB)ため、APIキーや簡単なブール値設定に最適です。

実践:APIキーの保存と読み取り

以下は、簡単なOptionsページのロジック例です:

データの保存(Sync Storageへの書き込み):

// options.js
const saveBtn = document.getElementById('save-btn');
const apiKeyInput = document.getElementById('api-key-input');

saveBtn.addEventListener('click', () => {
  const userApiKey = apiKeyInput.value;
  
  // データをsync storageに保存
  chrome.storage.sync.set({ openAiApiKey: userApiKey }, () => {
    console.log('設定が保存されました!');
    // ユーザーに通知メッセージを表示
    const status = document.getElementById('status-msg');
    status.innerText = '保存成功!';
    setTimeout(() => { status.innerText = ''; }, 2000);
  });
});

ページ初期化時のデータ読み取り:

// オプションページの読み込み時に、以前保存したキーを取得して入力ボックスに表示
document.addEventListener('DOMContentLoaded', () => {
  chrome.storage.sync.get(['openAiApiKey'], (result) => {
    if (result.openAiApiKey) {
      document.getElementById('api-key-input').value = result.openAiApiKey;
    }
  });
});

Storageの変更を監視

このAPIの最も強力な点は、他のコンポーネント(例えばContent Script)が設定の変更をリアルタイムで監視できることです!

ユーザーがOptionsページで「ダークモード」スイッチを切り替えた場合、Content Scriptはすぐに通知を受け取り、ウェブページの色を変更できます:

// content.js で
chrome.storage.onChanged.addListener((changes, namespace) => {
  for (let [key, { oldValue, newValue }] of Object.entries(changes)) {
    if (key === 'darkMode') {
      console.log(`ダークモードの状態が ${oldValue} から ${newValue} に変更されました`);
      // 色変更ロジックを実行
      toggleDarkModeUI(newValue);
    }
  }
});

UIインターフェースと chrome.storage を完璧に組み合わせることで、拡張機能は完全な製品の原型を備えます。

最後の章では、最もエキサイティングな部分に入ります:この拡張機能を収益化し、全世界のChrome Web Storeに正式に公開する方法です!

完全なチュートリアルをロック解除

このチャプターは有料コンテンツです。プロジェクトに参加して、10以上の神レベルのPromptや実際のソースコード例を含む、5000字以上の深い分析をロック解除してください!