Lonely Tab Title for React
Changes the page title to a custom message when the user switches away from the tab. Uses the Page Visibility API.
Component
<LonelyTabTitle /><LonelyTabTitle text="Come back! 😢" />"use client";
import { useEffect, useRef } from "react";
const DEFAULT_TEXT = "I am a lonely tab!!";
interface LonelyTabTitleProps {
text?: string;
}
export function LonelyTabTitle({
text = DEFAULT_TEXT,
}: LonelyTabTitleProps) {
const savedTitleRef = useRef("");
useEffect(() => {
function handleVisibilityChange() {
if (document.hidden) {
savedTitleRef.current = document.title;
document.title = text;
} else {
document.title =
savedTitleRef.current || document.title;
}
}
document.addEventListener(
"visibilitychange",
handleVisibilityChange,
);
return () =>
document.removeEventListener(
"visibilitychange",
handleVisibilityChange,
);
}, [text]);
return null;
}Installation
1. Copy the component file
"use client";
import { useEffect, useRef } from "react";
const DEFAULT_TEXT = "I am a lonely tab!!";
interface LonelyTabTitleProps {
text?: string;
}
export function LonelyTabTitle({
text = DEFAULT_TEXT,
}: LonelyTabTitleProps) {
const savedTitleRef = useRef("");
useEffect(() => {
function handleVisibilityChange() {
if (document.hidden) {
savedTitleRef.current = document.title;
document.title = text;
} else {
document.title =
savedTitleRef.current || document.title;
}
}
document.addEventListener(
"visibilitychange",
handleVisibilityChange,
);
return () =>
document.removeEventListener(
"visibilitychange",
handleVisibilityChange,
);
}, [text]);
return null;
}2. Import and add to layout
import { LonelyTabTitle } from "@/components/lonely-tab-title";
<LonelyTabTitle />;Usage
Import
Add the LonelyTabTitle import.
import { LonelyTabTitle } from "@/components/lonely-tab-title";Use
Add to your root layout.
<LonelyTabTitle />;Guidelines
- Add to root layout (e.g. app/layout.tsx) for site-wide effect.
- Renders nothing; only listens for visibilitychange events.
- Restores the original title when the user returns to the tab.
- Use the text prop to customize the message shown when the tab is hidden.
Props
All props are optional unless marked required. Use these to customize every aspect of the component.
| Prop | Type | Default | Description |
|---|---|---|---|
| text | string | "I am a lonely tab!!" | Title to show when the user switches away from the tab. |
Accessibility
- Headless utility that returns null, so it renders no DOM, no interactive controls, and nothing focusable or operable by keyboard.
- It only mutates document.title via the Page Visibility API, which screen readers may announce as a title change when the tab regains or loses focus.
- There are no ARIA attributes, roles, or labels because there is no rendered element to describe.
- No motion or animation is involved, so prefers-reduced-motion is not applicable to this component.
- Be mindful that overwriting the document title removes the page name from the title bar and history while the tab is hidden, which can momentarily reduce context for assistive technology users.
Performance
- Extremely lightweight: a single visibilitychange listener registered in a useEffect, with no rendering work, no animation, and no per-frame updates.
- It animates no CSS or JS properties and uses neither requestAnimationFrame nor IntersectionObserver, so there is zero compositor or layout cost.
- The original title is cached in a useRef, avoiding extra re-renders, and the only DOM write is the cheap document.title assignment on visibility change.
- The effect cleanup removes the visibilitychange listener on unmount and re-subscribes only when the text prop changes, preventing duplicate or leaked listeners.
Examples
Basic
Add to your root layout. When you switch tabs, the title becomes 'I am a lonely tab!!'.
<LonelyTabTitle /><LonelyTabTitle text="Come back! 😢" />import { LonelyTabTitle } from "@/components/lonely-tab-title";
<LonelyTabTitle />;Custom text
Custom message when the user leaves the tab.
<LonelyTabTitle /><LonelyTabTitle text="Come back! 😢" />import { LonelyTabTitle } from "@/components/lonely-tab-title";
<LonelyTabTitle text="Come back! 😢" />;Related reading
- When to Animate and When to Skip — Subtle attention cues versus distraction
Last updated on Jun 19