'Chrome Extension I can't get the tab title correctly in my custom extension history

I'm developing a plugin for Chrome and it has History feature in the plugin. For example, clicking the button creates a new tab and saves the URL address in the history. So this function works fine. But I want to get the document.title data of the tab that was opened in the past instead of the URL address. I tried doing this with tabs[tabs.length-1].title but it didn't get the title of the opened tab. Instead it got the title of the last tab that was already open. I guess this is the problem because the tab is not open yet. How can I solve this? Can you help me please?

This is my create tab function (If the tab is already open, don't open it again.):

function openTab(tab_url) {
    var isTabActive = false;
    var tabId = 0;
    var tabTitle = "";
    totalHistoryContent++;
    chrome.tabs.query({}, function(tabs) { 
        for(var i=0;i<tabs.length;i++) {
            if(tabs[i].url.toLowerCase().includes(tab_url.toLowerCase()) == true) {
                isTabActive = true;
                tabId = tabs[i].id;
                tabTitle = tabs[i].title; // WORKING NICE
                break;
            }
        }

        if(isTabActive == false) {
            chrome.tabs.create({ url:tab_url });
            tabTitle = tabs[tabs.length - 1].title; // NOT WORKING CORRECTLY
        } else{
            chrome.tabs.update(tabId, {selected: true});
            chrome.tabs.reload(tabId);
        }
        alert(tabTitle);
    });

    if(tab_url !== "chrome-extension://" + chrome.runtime.id + "/popup.html" && tab_url !== "chrome://extensions/?id=" + chrome.runtime.id) {
        setHistory(tabTitle,49); //THIS FUNCTION SAVE TITLE TO HISTORY
    }
}


Solution 1:[1]

One of the ways that you can handle this problem is sending an ajax request to the page's url

    var xmlHttp = new XMLHttpRequest();
xmlHttp.open('GET', 'tab_url', true);
xmlHttp.onreadystatechange = function () {
    if (
        this.readyState == 4 &&
        ((this.status >= 200 && this.status < 300) ||
            this.status == 304)
    ) {
        var data = this.responseText;
        var contentType = this.getResponseHeader("Content-Type"); //no i18n
        if (contentType && contentType.match('text/html')) {
            var doc = new DOMParser().parseFromString(data, "text/html");
            console.log(doc.title);
        }
    }
};
xmlHttp.send();

Note: This may throw CORS error at most pages, so don't forget to add "<all_urls>" in permissions in manifest(assuming you are using manifest V2).

"permissions": [
    "<all_urls>"
],

If you are using manifest V3, which is recommended, refer this documentation regarding permission

Other way is to send a message from chrome.tabs.create success callback to content script, if you don't use content script you have to inject code. In message response you can send the document's title using document.title.

Either way both will be asynchronous...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1