ページに新しい要素を挿入する最初の拡張機能を作成します。
概要
このチュートリアルでは、Chrome 拡張機能と Chrome ウェブストアのドキュメント ページに推定読書時間を追加する拡張機能を作成します。
![拡張機能の [ようこそ] ページの読み上げ時間の拡張機能](https://chrome-dot-google-developers.gonglchuangl.net/static/docs/extensions/get-started/tutorial/scripts-on-every-tab/image/reading-extension-the-e-0070620f12665.png?hl=ja)
このガイドでは、次のコンセプトについて説明します。
- 拡張機能のマニフェスト。
- 拡張機能で使用するアイコンのサイズ。
- コンテンツ スクリプトを使用してページにコードを挿入する方法。
- マッチパターンの使用方法。
- 拡張機能の権限。
始める前に
このガイドは、基本的なウェブ開発の経験があることを前提としています。拡張機能の開発ワークフローの概要については、Hello World チュートリアルをご覧ください。
拡張機能をビルドする
まず、拡張機能のファイルを格納する reading-time
という新しいディレクトリを作成します。必要に応じて、GitHub から完全なソースコードをダウンロードできます。
ステップ 1: 拡張機能に関する情報を追加する
必要なファイルはマニフェスト JSON ファイルのみです。拡張機能に関する重要な情報が含まれています。プロジェクトのルートに manifest.json
ファイルを作成し、次のコードを追加します。
{
"manifest_version": 3,
"name": "Reading time",
"version": "1.0",
"description": "Add the reading time to Chrome Extension documentation articles"
}
これらのキーには、拡張機能の基本的なメタデータが含まれています。拡張機能の [拡張機能] ページと、公開された場合は Chrome ウェブストアでの表示方法を制御します。詳しくは、マニフェストの概要ページで "name"
、"version"
、"description"
キーをご覧ください。
💡 拡張機能マニフェストに関するその他の事実
- プロジェクトのルートに配置する必要があります。
- 必須のキーは
"manifest_version"
、"name"
、"version"
のみです。 - 開発中はコメント(
//
)をサポートしていますが、Chrome ウェブストアにコードをアップロードする前に削除する必要があります。
ステップ 2: アイコンを提供する
では、アイコンが必要な理由は何でしょうか。アイコンは開発中は省略可能ですが、Chrome ウェブストアで拡張機能を配布する場合は必須です。また、拡張機能の管理ページなど、他の場所にも表示されます。
images
フォルダを作成して、アイコンを配置します。アイコンは GitHub からダウンロードできます。次に、ハイライト表示されたコードをマニフェストに追加して、アイコンを宣言します。
{
"icons": {
"16": "images/icon-16.png",
"32": "images/icon-32.png",
"48": "images/icon-48.png",
"128": "images/icon-128.png"
}
}
PNG ファイルを使用することをおすすめしますが、SVG ファイル以外のファイル形式も使用できます。
💡 サイズの異なるアイコンはどこに表示されますか?
アイコンのサイズ | アイコンの使用 |
---|---|
16x16 | 拡張機能のページとコンテキスト メニューのファビコン。 |
32x32 | Windows パソコンでは、このサイズが必要になることが多いです。 |
48x48 | [拡張機能] ページに表示されます。 |
128x128 | インストール時と Chrome ウェブストアに表示されます。 |
ステップ 3: コンテンツ スクリプトを宣言する
拡張機能は、ページのコンテンツを読み取って変更するスクリプトを実行できます。これらはコンテンツ スクリプトと呼ばれます。拡張機能の JavaScript は分離された環境で動作するため、ホストページや他の拡張機能のコンテンツ スクリプトと競合することなく、JavaScript 環境を変更できます。
manifest.json
に次のコードを追加して、content.js
というコンテンツ スクリプトを登録します。
{
"content_scripts": [
{
"js": ["scripts/content.js"],
"matches": [
"https://developer.chrome.com/docs/extensions/*",
"https://developer.chrome.com/docs/webstore/*"
]
}
]
}
"matches"
フィールドには、1 つ以上のマッチパターンを指定できます。これにより、ブラウザはコンテンツ スクリプトを挿入するサイトを特定できます。マッチパターンは次の 3 つの部分で構成されます。
<scheme>://<host><path>
*
文字を含めることができます。
💡 この拡張機能は権限に関する警告を表示しますか?
ユーザーが拡張機能をインストールすると、ブラウザは拡張機能の機能についてユーザーに通知します。コンテンツ スクリプトは、一致パターンの条件を満たすサイトで実行する権限をリクエストします。
この例では、ユーザーに次の権限に関する警告が表示されます。

拡張機能の権限について詳しくは、権限を宣言してユーザーに警告するをご覧ください。
ステップ 4: 読み上げ時間を計算して挿入する
コンテンツ スクリプトでは、標準のドキュメント オブジェクト モデル(DOM)を使用して、ページのコンテンツを読み取って変更できます。拡張機能はまず、ページに <article>
要素が含まれているかどうかを確認します。次に、この要素内のすべての単語をカウントし、合計読み上げ時間を表示する段落を作成します。
scripts
というフォルダ内に content.js
というファイルを作成し、次のコードを追加します。
function renderReadingTime(article) {
// If we weren't provided an article, we don't need to render anything.
if (!article) {
return;
}
const text = article.textContent;
const wordMatchRegExp = /[^\s]+/g; // Regular expression
const words = text.matchAll(wordMatchRegExp);
// matchAll returns an iterator, convert to array to get word count
const wordCount = [...words].length;
const readingTime = Math.round(wordCount / 200);
const badge = document.createElement("p");
// Use the same styling as the publish information in an article's header
badge.classList.add("color-secondary-text", "type--caption");
badge.textContent = `⏱️ ${readingTime} min read`;
// Support for API reference docs
const heading = article.querySelector("h1");
// Support for article docs with date
const date = article.querySelector("time")?.parentNode;
(date ?? heading).insertAdjacentElement("afterend", badge);
}
renderReadingTime(document.querySelector("article"));
💡 このコードで使用されている興味深い JavaScript
<article>
要素内の単語のみをカウントするために使用される正規表現。insertAdjacentElement()
要素の後に読み上げ時間ノードを挿入するために使用されます。- classList プロパティは、要素のクラス属性に CSS クラス名を追加するために使用します。
- 未定義または null の可能性があるオブジェクト プロパティにアクセスするために使用されるオプトイン チェーン。
- Nullish coalescing は、
<date>
が null または未定義の場合に<heading>
を返します。
ステップ 5: 変更をリッスンする
現在のコードでは、左側のナビゲーションを使用して記事を切り替えると、新しい記事に読書時間が追加されません。これは、History API を使用してソフト ナビゲーションを実行するシングルページ アプリケーション(SPA)としてサイトが実装されているためです。
これを修正するには、MutationObserver
を使用して変更をリッスンし、新しい記事に読み上げ時間を追加します。
そのためには、content.js
の末尾に次のコードを追加します。
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
// If a new article was added.
for (const node of mutation.addedNodes) {
if (node instanceof Element && node.tagName === 'ARTICLE') {
// Render the reading time for this particular article.
renderReadingTime(node);
}
}
}
});
// https://developer.chrome.com/ is a SPA (Single Page Application) so can
// update the address bar and render new content without reloading. Our content
// script won't be reinjected when this happens, so we need to watch for
// changes to the content.
observer.observe(document.querySelector('devsite-content'), {
childList: true
});
動作をテストする
プロジェクトのファイル構造が次のようになっていることを確認します。
拡張機能をローカルに読み込む
デベロッパー モードでパッケージ化されていない拡張機能を読み込むには、開発の基本の手順に沿って操作します。
拡張機能または Chrome ウェブストアのドキュメントを開く
以下のページを開くと、各記事の読み上げにかかる時間を確認できます。
次のようになります。

🎯 改善の可能性
本日の学習内容に基づいて、次のいずれかを実装してみてください。
- Chrome DevTools や Workbox など、他の Chrome デベロッパー ページをサポートするには、manifest.json に別のマッチパターンを追加します。
- お気に入りのブログやドキュメント サイトの読み上げ時間を計算する新しいコンテンツ スクリプトを追加します。
構築を継続する
このチュートリアルを完了しました 🎉。このシリーズの他のチュートリアルを完了して、スキルをさらに磨きましょう。
広告表示オプション | 学習内容 |
---|---|
フォーカス モード | 拡張機能のアクションをクリックした後に、現在のページでコードを実行する。 |
タブ マネージャー | ブラウザのタブを管理するポップアップを作成する。 |
引き続き探求を
この Chrome 拡張機能の作成をお楽しみいただけたでしょうか。Chrome 開発の学習を続けていただければ幸いです。次の学習パスをおすすめします。
- デベロッパー ガイドには、高度な拡張機能の作成に関連するドキュメントへのリンクが多数あります。
- 拡張機能は、オープンウェブで利用できる以上の強力な API にアクセスできます。Chrome APIs のドキュメントでは、各 API について説明しています。