ReactでChromeのExtension開発をしている際に、開いているページ(タブ)のURLとタイトルを取得します。
検証した環境
1 | react | 16.13.1 |
2 | Google Chrome | 87.0.4280.67 |
Extension開発でタブのURLを取得する
ページでタブの値を取得する
componentDidMount
のようなコンポーネントがマウントされた後に chrome.tabs.getSelected
関数を呼ば出せばOK!
chrome.tabs.getSelected(null, (tab) => {
console.log(tab.url) //開いているページのURL
console.log(tab.title) //開いているページのタイトル
})
chrome.tabs
のように書けるのがExtension開発ならでは、ですね。
TypeScript + functionalでフックAPIを使うと以下のようになります
import React, { useEffect } from 'react'
const HogePage = () => {
useEffect(() => {
// @ts-ignore
chrome.tabs.getSelected(null, (tab) => {
console.log(tab)
})
}, [])
・・・
}
export default HogePage
@ts-ignore
を付けているのは Cannot find name 'chrome'
と表示されてしまうから。
そりゃReact的には chrome
なんてグローバル変数知らないから当然か。
.d.ts
ファイルを用意したり、tsconfigを工夫すればどうにか出来そうですが、時間優先でここでは無視しちゃいます!
さて console.log(tab)
の内容を見てみると
残念ながらまだ title
や url
がとれていません。
title
や url
を取るためには 「manifest.json」 への追記が必要になります
manifest.jsonにpermissionsの設定を追加
manifest.jsonのpermissionsに tabs
を設定します。
permissionsに項目を追加する事で chrome.*
APIを使う事が出来るようになります。
例えば、 chrome.bookmarks
APIも使うような場合だと以下のように記載します
"permissions": [
"tabs",
"bookmarks"
],
permissionsに記載出来る項目は公式に載っています
ここでは chrome.tabs
APIが使用出来ればよいためmanifest.jsonは以下のようになります
{
"name": "hogehoge",
"manifest_version": 2,
"version": "0.1.0",
"icons": {
"16": "images/icon.png",
"48": "images/icon.png",
"128": "images/icon.png"
},
"browser_action": {
"default_icon":{
"19": "images/icon.png"
},
"default_title": "hogehoge",
"default_popup": "index.html"
},
"permissions": [
"tabs"
],
これで先程のコードを実行すると、
無事 title
url
が取れるようになりました!
あとは useState
等と組み合わせれば良いので、
以下のように書けば開いているタブのタイトルやURLが取得し使う事が出来ます。
import React, { useEffect, useState } from 'react'
const HogePage = () => {
const [title, setTitle] = useState('')
const [articleUrl, setArticleUrl] = useState('')
useEffect(() => {
// @ts-ignore
chrome.tabs.getSelected(null, (tab) => {
setTitle(tab.title)
setArticleUrl(tab.url)
})
}, [])
return (
<>
<p>{title}</p>
<p>{articleUrl}</p>
</>
)
}
export default HogePage