Reviving the lastTab Chrome Extension: Manifest Configuration and Core Logic
This article details the revival of the lastTab Chrome extension, explaining the manifest v3 setup, background scripts, and event listeners that ensure each window retains at least two tabs, while providing full source code snippets and implementation notes.
Chrome is a dominant desktop browser, and many users rely on extensions to enhance its functionality. The author recounts the frustration of losing the last tab when closing a window and how the now‑defunct lastTab extension solved this problem.
After the original extension disappeared—likely due to Chrome’s upgrade from version 2 to 3—the author obtained an older version and installed it offline. Inspired by recent learning of Chrome extension development basics, they decided to resurrect the tool.
manifest configuration
The following manifest.json (manifest_version 3) defines the extension’s metadata, permissions, icons, background service worker, and content scripts:
{
"manifest_version": 3,
"version": "1.0",
"action": {
"default_icon": "funtester.png",
"default_popup": "popup.html"
},
"background": {
"service_worker": "background.js"
},
"description": "hello,FunTester !!!",
"icons": {
"48": "funtester.png",
"128": "funtester128.png"
},
"name": "FunTester Tab",
"offline_enabled": true,
"content_scripts": [{
"matches": ["
"],
"js": ["content.js"],
"run_at": "document_end",
"all_frames": true
}],
"host_permissions": ["
"],
"permissions": ["tabs", "storage", "contextMenus", "scripting", "activeTab"]
}Some permissions are unrelated to the core lastTab functionality and remain for other project features.
background
The background script implements the core logic that guarantees each window has at least two tabs. The first tab (index 0) is created by the extension, while the second is the user’s default page. When the penultimate tab is closed, a new tab is opened using the browser’s default newTab page.
Installation
On installation the extension sets a badge text "Fun", defines a red badge background, and opens a page caption.html that lists original articles:
chrome.runtime.onInstalled.addListener(function () {
chrome.action.setBadgeText({text: "Fun"});
chrome.action.setBadgeBackgroundColor({color: [255,0,0,255]});
chrome.tabs.create({url: "caption.html", active: true});
});The installation listener performs three actions: badge text, badge color, and opening the article list.
Initialization
After installation the script retrieves all windows, checks each one, and creates the first tab if it is missing:
chrome.windows.getAll({populate: true}, initialCheck);
function initialCheck(windows) {
for (let index = 0; index < windows.length; ++index) {
let window = windows[index];
checkWinowClose(window);
if (!checkIfFirstTabIsOurs(window)) createTabInWindow(windows[index]);
}
}New Window Handling
chrome.windows.onCreated.addListener(createNewWindow);
function createNewWindow(window) {
if (typeof window !== "undefined" && window.type === "normal" && !checkIfFirstTabIsOurs(window)) {
createTabInWindow(window);
}
}The listener ensures a new normal window also contains the required tab.
Tab Removal
chrome.tabs.onRemoved.addListener(tabRemoved);
function tabRemoved(tabId, removeInfo) {
console.info("Tab removed", tabId, removeInfo);
if (typeof removeInfo.windowId != 'undefined') {
chrome.windows.get(removeInfo.windowId, {"populate": true}, function (window) {
if (typeof window !== 'undefined' && window.type === "normal") {
setTimeout(function () {
if (!checkTabIsOurs(window.tabs[0])) {
createTabInWindow(window);
} else if (window.tabs.length === 1) {
createSecondTabInWindow(window);
}
}, 400);
}
});
}
}After a 400 ms delay the script restores a missing tab or adds a second tab when only one remains.
Tab Detach
chrome.tabs.onDetached.addListener(tabDetached);
function tabDetached(tabId, detachInfo) {
console.info("Tab detached", tabId, detachInfo);
setTimeout(function () {
chrome.windows.getAll({populate: true}, initialCheck);
}, 1000);
console.info("Checking windows...");
}A 1 second delay triggers a full window check to re‑establish the required tabs.
Tab Activation
chrome.tabs.onActivated.addListener(tabActivated);
function tabActivated(activeInfo) {
console.info("Tab activated", activeInfo);
if (typeof activeInfo.windowId !== 'undefined') {
chrome.windows.get(activeInfo.windowId, {"populate": true}, function (window) {
if (window.tabs[0].active === true && window.tabs.length > 1) {
setTimeout(function () {
chrome.tabs.update(window.tabs[1].id, {active: true});
}, 200);
}
});
}
}If the first tab becomes active while other tabs exist, the script switches focus to the second tab after 200 ms.
Tab Creation
chrome.tabs.onCreated.addListener(checkTab);
function checkTab(tab) {
console.info("Tab created", tab);
setTimeout(function () {
chrome.windows.get(tab.windowId, {"populate": true}, function (window) {
checkWinowClose(window);
});
}, 300);
}When a new tab appears, the extension waits 300 ms then validates the window’s tab set.
Other Utilities
Additional helper functions ( createTabInWindow , createSecondTabInWindow , checkIfFirstTabIsOurs , checkTabIsOurs , checkWinowClose ) implement the actual tab creation, URL matching via regular expressions, and cleanup of duplicate extension tabs.
The author notes that many features suffer from timeout issues; retry loops increase complexity and contradict the original design intent. Interested readers can contact the author for a revived version of the lastTab extension.
FunTester
10k followers, 1k articles | completely useless
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.