Greasy Fork is available in English.
Replaces generic Facebook tab title with the actual page or group name
// ==UserScript==
// @name FBTitle Fix
// @namespace https://github.com/2u841r/FBTitle-Fix
// @version 1.0.1
// @description Replaces generic Facebook tab title with the actual page or group name
// @author Zubair Ibn Zamir
// @license MIT
// @match *://*.facebook.com/*
// @grant none
// @run-at document-idle
// ==/UserScript==
(function () {
'use strict';
function getPageName() {
// Primary: h1 button div (old page/group name header)
const h1btn = document.querySelector('h1 div[role="button"]');
if (h1btn) {
const text = h1btn.childNodes[0]?.textContent?.trim();
if (text) return text;
}
// Fallback: h1 text (groups: h1 > span). Skip hidden/junk h1s like the
// visually-hidden "Facebook" logo heading.
for (const h1 of document.querySelectorAll('h1')) {
const text = h1.textContent?.trim();
if (!text || text === 'Facebook') continue;
if (h1.getBoundingClientRect().width === 0) continue;
return text;
}
// Fallback: 2026-07 layout, page header has no h1 anymore.
// Tail of the header container path; atomic class hashes may break on FB redesigns.
const span = document.querySelector('div.x1cy8zhl.x1614ocl > div > div > span > div');
if (span) {
const text = span.textContent?.trim();
if (text) return text;
}
// Last resort: structural walk, no classes. First short standalone text
// block inside main content, above the fold (header area).
const main = document.querySelector('div[role="main"]');
if (main) {
const candidates = main.querySelectorAll('span > div');
for (const el of candidates) {
if (el.children.length > 0) continue;
if (el.getBoundingClientRect().top > 600) break;
const text = el.textContent?.trim();
if (text && text.length >= 2 && text.length <= 100) return text;
}
}
return null;
}
function updateTitle() {
const name = getPageName();
if (name && !document.title.startsWith(name)) {
document.title = name + ' | Facebook';
}
}
const observer = new MutationObserver(() => updateTitle());
observer.observe(document.body, { childList: true, subtree: true });
const _pushState = history.pushState.bind(history);
history.pushState = function (...args) {
_pushState(...args);
setTimeout(updateTitle, 500);
};
window.addEventListener('popstate', () => setTimeout(updateTitle, 500));
updateTitle();
})();