“Cannot read property of undefined” when using chrome.tabs or other chrome API in content script

chrome.tabs returns undefined despite the fact I set tabs in the permissions block.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>"permissions": [
"tabs",
"http://*/*",
"https://*/*"
],
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"js": [
"js/myScript.js"
],
"all_frames": true
}
],
</code>
<code>"permissions": [ "tabs", "http://*/*", "https://*/*" ], "content_scripts": [ { "matches": [ "http://*/*", "https://*/*" ], "js": [ "js/myScript.js" ], "all_frames": true } ], </code>
"permissions": [
    "tabs",
    "http://*/*",
    "https://*/*"
],
"content_scripts": [
    {
        "matches": [
            "http://*/*",
            "https://*/*"
        ],
        "js": [
            "js/myScript.js"
        ],
        "all_frames": true
    }
],

But in myScript.js, chrome.tabs is undefined.

2

Content script can only use chrome.i18n, chrome.dom, chrome.storage, and a subset of chrome.runtime/chrome.extension.

Most chrome APIs such as chrome.tabs are only available the background script (service worker in MV3), popup script, etc.

Solution

Pass a message from the content script to the background script and use the API there.

6

Content scripts have only limited access to Chrome APIs. This access does not include the API you are trying to use (e.g. chrome.tabs). If you need to use that API, you will have to do so in a background script1.

As listed in Chrome’s content scripts documentation, the APIs available to a content script are [I have placed deprecated methods in strikethrough format]:

They can access the following extension APIs directly:

  • dom
  • i18n
  • storage
  • runtime.connect()
  • runtime.getManifest()
  • runtime.getURL()
  • runtime.id
  • runtime.onConnect
  • runtime.onMessage
  • runtime.sendMessage()

Extra confusion specifically for chrome.tabs

There’s additional confusion for chrome.tabs. People often assume that because it’s .tabs and content scripts are in tabs that chrome.tabs is available in content scripts, but it’s not.

The top banner on the chrome.tabs documentation page says:

Note: The Tabs API can be used by the service worker and extension pages, but not content scripts.

Particular confusion for chrome.tabs.getCurrent()

The confusion for chrome.tabs.getCurrent() is enhanced, as the documentation says:

Gets the tab that this script call is being made from. Returns undefined if called from a non-tab context (for example, a background page or popup view).

Many people make the assumption that mentioning “non-tab context (for example, a background page or popup view)” it means a non-background context, but the documentation is specifically meaning an actual background page, not anything in the background context. What it’s meaning is that in order to return the tab it needs to be called from a script that is both in the background context and a tab context. If it’s called from a script that’s in the background context that’s not also in a tab context, then it will return undefined. It is not available from a content script context. Attempting to call chrome.tabs.getCurrent() from a content script context will result in a

Uncaught TypeError: Cannot read properties of undefined

which is the error this question is asking about.

Partition your extension into background scripts and content scripts

You are going to need to separate your code into what needs to be in a background script and what needs to be in content scripts, based on the capabilities available to each type of script. Content scripts have access to the DOM of the web page into which they are injected, but limited access to extension APIs. Background scripts have full access to the extension APIs, but no access to web page content. You should read the Chrome extension overview, and the pages linked from there, to get a feel for what functionality should be located in which type of script.

It is common to need to communicate between your content scripts and background scripts. To do so you can use message passing. This allows you to communicate information between the two scripts to accomplish things which are not possible using only one type of script.
For instance, in your content script, you may need information which is only available from one of the other Chrome APIs, or you need something to happen which can most appropriately (or only) be done through one of the other Chrome extension APIs. In these cases, you will need to send a message to your background script, using chrome.runtime.sendMessage(), to tell it what needs to be done, while providing enough informaiton for it to be able to do so. Your background script can then return the desired information, if any, to your content script. Alternately, you will have times when the processing will primarily be done in the background script. The background script may inject a content script, or just message an already injected script, to obtain information from a page, or make changes to the web page.


  1. Background script means any script that is in the background context. In addition to actual background scripts, this includes popups and options pages, etc. However, the only page that you can be sure to have consistently available to receive messages from a content script are your actual background scripts defined in manifest.json. Other pages may be available at some times as a result of the user’s interaction with the browser, but they are not available consistently.

This answer was moved from a duplicate question, and then modified.

5

https://developer.chrome.com/extensions/tabs#method-getSelected shows

getSelected

chrome.tabs.getSelected(integer windowId, function
callback)
Deprecated since Chrome 33. Please use tabs.query {active: true}.
Gets the tab that is selected in the specified window.

Maybe, you should use chrome.tabs.query in popup.js like this

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
console.log(tabs[0].url);
});
</code>
<code>chrome.tabs.query({active: true, currentWindow: true}, function(tabs){ console.log(tabs[0].url); }); </code>
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
    console.log(tabs[0].url);
});

, reload your extension and check the result in the inspect element of your extension.

result image

code image

https://developer.chrome.com/extensions/tabs#type-Tab shows that
The URL the tab is displaying. This property is only present if the extension’s manifest includes the “tabs” permission.(Just for remind someone forgot. I was forgot it when I just test it.)

1

Check this answer also /a/6718277/449345
This one worked for me

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>chrome.tabs.getSelected(null, function(tab){
console.log(tab);
});
</code>
<code>chrome.tabs.getSelected(null, function(tab){ console.log(tab); }); </code>
chrome.tabs.getSelected(null, function(tab){
    console.log(tab);
});

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật