新しいタブを開いたら資格勉強サイトに強制送還されるChrome拡張機能を作った

目次

こんにちは。ごえです。

皆様は勉強得意でしょうか。私は苦手です。小学生のころ、地理が嫌いで「山脈の名前なんか興味ないわ!」と教科書を自室の壁に投げつけたことがあります。(割と大きくなるまで名古屋県があると思っていたのは内緒です)

とは言っても、エンジニアたるもの日々勉強が必要です。AWSの業務に携わっているので資格勉強も積極的に取り組みたい気持ちもあります。

しかし、AWSに限らず資格勉強、、、始めるまでのハードルが高いと思いませんか?
私はハードルが高いと感じます。会員制のWebサイトで演習問題を解くサイトを見つけ少しずつ取り組んでいます。

しかし「今日は勉強しよう」と思っていても、ブラウザを開いたらメールを確認し、気づけば仕事をしている。勉強サイトを開くという、たった数クリックの操作すら面倒に感じることがあります。

そこで考えました。

新しいタブを開くたびに、強制的に資格勉強サイトを開けばいいのでは?

勉強を始めるまでの心理的なハードルを下げるため、新しいタブを開くと自動的に指定したURLへ遷移するChrome拡張機能を作りました。(標準の機能では実現できないため)

なお、実装コードは自分で一から書いたわけではなく、Claude AIに書いてもらいました。

この記事では、Claude AIに生成してもらったコードでChrome拡張機能を作った流れと、その中で遭遇したハマりポイントを紹介します。

やりたいこと

要件はシンプルです。

・新しいタブを開いたら、あらかじめ設定したURLに自動でアクセスする
・リダイレクト先は資格勉強サイトを想定

勉強する資格が変わっても使い回せるよう、URLはハードコードせず設定画面から変更できるようにしました。

コードはClaude AIに書いてもらった

今回は、実装の大部分をClaude AIにお願いしました。

やりたいこと自体は明確だったので、

「Chromeで新しいタブを開いたときに、設定したURLへ自動的にリダイレクトするManifest V3対応の拡張機能を作りたい」

という形で要件を伝え、必要なファイル一式を生成してもらいました。

生成AIを使うとかなり短時間で用意できます。

ただ、生成されたコードがそのまま動くとは限りません。
今回も、実際にChromeへ読み込んでみたところ、最初は正常に動作しませんでした。

実装方針

Chrome拡張機能には chrome_url_overrides という仕組みがあります。

これを使うと、ChromeのNew Tab Pageを拡張機能内のHTMLへ置き換えられます。

manifest.json は以下のような構成です。

{
  "manifest_version": 3,
  "name": "New Tab Redirect",
  "version": "1.0.0",
  "chrome_url_overrides": {
    "newtab": "newtab.html"
  },
  "permissions": ["storage"],
  "options_page": "options.html"
}

chrome_url_overrides の newtab に newtab.html を指定することで、新しいタブを開いた際にChrome標準の新規タブ画面ではなく、拡張機能側のHTMLが表示されます。

あとは、そのページから目的のURLへ遷移させるだけです。

リダイレクト処理は以下です。(以下のコードでは、www.google.comにリダイレクトされるよう記述されております)

// newtab.js
const DEFAULT_URL = "https://www.google.com";

chrome.storage.sync.get(["targetUrl"], (result) => {
  const url = result.targetUrl || DEFAULT_URL;
  location.replace(url);
});

chrome.storage.sync から設定済みのURLを取得し、location.replace() で移動します。

今回の場合は、この targetUrl に資格勉強サイトのURLを設定します。

つまり、

新しいタブを開く

newtab.html が開く

newtab.js が実行される

資格勉強サイトへリダイレクト

という流れです。

リダイレクト先を設定画面から変更する

毎回コードを書き換えるのは面倒なので、URLは設定画面から変更できるようにしています。

設定画面側のJavaScriptは以下のような形です。

// options.js
saveBtn.addEventListener("click", () => {
  let url = urlInput.value.trim();
  if (!url) return;

  if (!/^https?:\/\//i.test(url)) {
    url = "https://" + url;
  }

  chrome.storage.sync.set({ targetUrl: url });
});

入力されたURLに http:// または https:// が付いていなければ、https:// を補完して保存します。

資格勉強を完全に諦めた場合はGoogleの検索画面に戻すこともできます。

ハマったポイント:インラインスクリプトが動かない

Claude AIに生成してもらったコードをChromeに読み込み、新しいタブを開いてみました。

すると、

「リダイレクトしています...」

という表示は出るものの、一向にページ遷移しません。

最初の newtab.html では、リダイレクト処理のJavaScriptがHTML内に直接書かれていました。

<!-- 動かなかった書き方 -->
<script>
  chrome.storage.sync.get(["targetUrl"], (result) => {
    location.replace(result.targetUrl || DEFAULT_URL);
  });
</script>


Manifest V3ではこの書き方が問題になります。

原因は **CSP(Content Security Policy)** でした。

Manifest V3の拡張機能ページでは、デフォルトで script-src 'self' という制約が適用されます。

【参考】
https://developer.chrome.com/docs/extensions/reference/manifest/content-security-policy?hl=ja


そのため、拡張機能パッケージ内に置いたJavaScriptファイルは読み込めますが、HTML内に直接記述したインラインスクリプトは実行できません。

XSSなどの攻撃リスクを減らすためのセキュリティ上の制約です。

JavaScriptを別ファイルに分離する

対処方法はシンプルです。

JavaScriptを newtab.js として外部ファイルへ切り出し、HTMLから読み込むように変更します。

<div id="msg">リダイレクトしています...</div>
<script src="newtab.js"></script>

そして、処理本体は newtab.js に記述します。

const DEFAULT_URL = "https://www.google.com";

chrome.storage.sync.get(["targetUrl"], (result) => {
  const url = result.targetUrl || DEFAULT_URL;
  location.replace(url);
});

これでCSPにブロックされることなく、正常に資格勉強サイトへリダイレクトされるようになりました。

まとめ

資格勉強を始めるまでの心理的ハードルを下げるため、新しいタブを開くたびに指定した勉強サイトへ自動アクセスするChrome拡張機能を作りました。

生成AIを使えば、こうした小さなツールを思いついてから形にするまでのハードルはかなり下がっています。

では実際、この拡張機能によって資格勉強ができるようになったのでしょうか。

この記事を書いている時点で、邪魔になって拡張機能を無効化していました。

勉強のハードルを下げることには成功しましたが、新しいタブを普通に使うハードルが上がりすぎたようです。