Copied!
It's on your clipboard.
You’ve been offline for 0 second. Please check your Internet connection.

Help Us Improve

Found an issue or have an idea? Let us know.
Select all that apply...
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Change Page Title When User Switches Tabs
Preview
Overview

This script is a small attention-grabber for browser tabs. It changes the tab title to fun custom messages when a user switches away, lets you control how they appear (random or in order), keeps them in sync across tabs, and restores the original title when they return.

Documentation
Code Setup
Walkthrough

Copy To Elementor
Option A: Change Title On Exit

Add this code with a snippets plugin right before the closing </body> tag.

Language
Copy
(function () {
  if (/Mobi|Android/i.test(navigator.userAgent)) return;

  const originalTitle = document.title;
  const awayMessage   = "👀 Miss me?"; // message
  const startDelay    = 2000;          // wait before showing (ms)
  const returnDelay   = 1000;          // wait before restoring (ms)

  let startTimer = null;
  let returnTimer = null;

  function showMessage() {
    document.title = awayMessage;
    localStorage.setItem("site_tab_message", awayMessage);
  }

  function restoreMessage() {
    document.title = originalTitle;
    localStorage.removeItem("site_tab_message");
  }

  function handleVisibility() {
    if (document.hidden) {
      clearTimeout(startTimer);
      startTimer = setTimeout(showMessage, startDelay);
    } else {
      clearTimeout(returnTimer);
      returnTimer = setTimeout(restoreMessage, returnDelay);
    }
  }

  window.addEventListener("storage", (e) => {
    if (e.key === "site_tab_message") {
      if (e.newValue) {
        document.title = e.newValue;
      } else {
        document.title = originalTitle;
      }
    }
  });

  document.addEventListener("visibilitychange", handleVisibility);
})();
Option B: Rotate Page Titles on Exit

Add this code with a snippets plugin right before the closing </body> tag.

Language
Copy
// Messages (add as many as you like)
const tabMessages = [
  "👀 Miss me?",
  "✨ Still waiting…",
  "😏 Don’t ghost me.",
  "🔥 Come back 😉",
  "💋 Miss your clicks."
];

// Settings
const startDelay     = 2000;   // Wait before showing message (ms)
const rotateSpeed    = 2000;   // How fast to switch (ms)
const returnDelay    = 1000;   // Delay before title resets (ms)
const useRandom      = true;   // true = random order, false = rotate in order
const rotateMessages = true;   // true = keep rotating, false = show one only
const syncMessages   = true;   // true = sync all tabs to same message, false = independent

(function () {
  if (/Mobi|Android/i.test(navigator.userAgent)) return;

  let originalTitle = document.title;
  let index = 0;
  let lastRandom = -1;
  let interval = null;
  let startTimer = null;
  let returnTimer = null;

  function clearTimers() {
    clearInterval(interval);
    clearTimeout(startTimer);
  }

  function getMessage() {
    if (tabMessages.length === 0) return originalTitle;

    if (useRandom && tabMessages.length > 1) {
      let i;
      do { i = Math.floor(Math.random() * tabMessages.length); } while (i === lastRandom);
      lastRandom = i;
      return tabMessages[i];
    }

    const msg = tabMessages[index];
    index = (index + 1) % tabMessages.length;
    return msg;
  }

  function setMessage(msg) {
    document.title = msg;
    if (syncMessages) {
      localStorage.setItem("site_tab_message", msg);
    }
  }

  function startEffect() {
    clearTimers();

    if (tabMessages.length === 1) {
      setMessage(tabMessages[0]);
      return;
    }

    setMessage(getMessage());

    if (rotateMessages) {
      interval = setInterval(() => {
        setMessage(getMessage());
      }, rotateSpeed);
    }
  }

  function restore() {
    clearTimers();
    clearTimeout(returnTimer);
    returnTimer = setTimeout(() => {
      document.title = originalTitle;
      if (syncMessages) {
        localStorage.removeItem("site_tab_message");
      }
    }, returnDelay);
  }

  function queueStart() {
    clearTimers();
    clearTimeout(startTimer);
    startTimer = setTimeout(startEffect, startDelay);
  }

  function setActive(state) {
    localStorage.setItem("site_tab_active", state ? "1" : "0");
  }

  function isAnyTabActive() {
    return localStorage.getItem("site_tab_active") === "1";
  }

  function handleVisibility() {
    if (document.hidden) {
      if (!isAnyTabActive()) queueStart();
      setActive(false);
    } else {
      setActive(true);
      restore();
    }
  }

  window.addEventListener("storage", (e) => {
    if (e.key === "site_tab_active") {
      if (isAnyTabActive()) {
        restore();
      } else {
        queueStart();
      }
    }
    if (syncMessages && e.key === "site_tab_message" && e.newValue) {
      document.title = e.newValue;
    }
  });

  document.addEventListener("visibilitychange", handleVisibility);
  window.addEventListener("blur", handleVisibility);
  window.addEventListener("focus", handleVisibility);

  if (!document.hidden) setActive(true);
})();

Language
Copy

Language
Copy

Language
Copy

Language
Copy
Publish and preview live

Some solutions only work on the live site. Always publish and test after each change, as results may not appear in the editor.

Absolutely Codefree
If you were expecting some fancy snippet, sorry. This one runs just fine on its own.
C’mon, You Got This
Do we really need to spell this one out? It’s as straightforward as it gets.
Resorce Details
Collection
Basics
Category
Category
Interactions
Interaction
Builder
Last Updated
September 16, 2025