JavaScriptでページタイトルを扱う場面は意外と多くあります。アナリティクス計測・ブラウザタブへの通知バッジ表示・SPA(シングルページアプリケーション)でのルーティング管理など、「どうやってタイトルを取得・活用するか」を理解しておくと実装の幅が大きく広がります。
この記事ではタイトル取得の3つの方法の比較から始め、OGP・meta情報との連携、タブ通知の実装、MutationObserverによるリアルタイム監視、SPA対応まで体系的に解説します。
ページタイトルを取得する3つの方法
JavaScriptでページタイトルを取得する方法は3通りあります。
// 現在のページタイトルを取得する最標準的な方法 const title = document.title; console.log(title); // 例: "トップページ | codingls"
// <title> 要素を DOM として取得
const title = document.querySelector('title').textContent;
console.log(title);
// 旧来の書き方(IE時代の名残)
const title = document.getElementsByTagName('title')[0].innerText;
console.log(title);
| 方法 | 推奨度 | 戻り値 | 備考 |
|---|---|---|---|
document.title |
◎ | string | 標準的・null安全・書き込みも可 |
querySelector('title').textContent |
○ | string | 要素がない場合はnullエラー |
getElementsByTagName |
△ | string | 旧式・innerText はレイアウト依存 |
document.title を使う。querySelector は <title> 要素が存在しない場合に TypeError が発生するリスクがあります。document.title はその点も安全です。document.title の仕様と注意点
document.title が返す値には次の特徴があります。
// HTML: <title> コーディング ライフスタイル </title> console.log(document.title); // → "コーディング ライフスタイル"(先頭・末尾の空白は除去、内部空白は保持) // HTML: <title>codingls & WebDev</title> console.log(document.title); // → "codingls & WebDev"(HTMLエンティティは解決済みの状態で返る) // <title> が存在しない場合 console.log(document.title); // → ""(空文字列。エラーにならない)
& など)は解決済みの文字列で返ります。逆に、document.title に文字列を代入する際はエスケープ不要です(そのまま文字として扱われます)。meta情報(OGP・description)をまとめて取得する
ページのタイトルと同時に <meta> タグの情報(OGPタイトル・description・キーワードなど)を一括で取得したいケースがあります。
/**
* ページの主要なメタ情報をオブジェクトで返す
*/
function getPageMeta() {
const getMeta = (selector) => {
const el = document.querySelector(selector);
return el ? (el.getAttribute('content') ?? '') : '';
};
return {
title: document.title,
ogTitle: getMeta('meta[property="og:title"]'),
ogDesc: getMeta('meta[property="og:description"]'),
ogImage: getMeta('meta[property="og:image"]'),
description: getMeta('meta[name="description"]'),
keywords: getMeta('meta[name="keywords"]'),
twitterCard: getMeta('meta[name="twitter:card"]'),
};
}
// 使用例
const meta = getPageMeta();
console.log(meta.title); // ページタイトル
console.log(meta.ogTitle); // OGPタイトル(SNSシェア用)
console.log(meta.description); // metaディスクリプション
function sendPageView() {
const meta = getPageMeta();
gtag('event', 'page_view', {
page_title: meta.title,
page_location: location.href,
content_group: meta.keywords,
});
}
document.title(ブラウザタブ)とは異なる文字列が設定されている場合があります。タブ通知:未読メッセージをタイトルで知らせる
チャットやリアルタイム通知があるアプリで、ユーザーが別タブを操作しているときにタイトルを点滅させて未読を知らせる実装パターンです。document.visibilityState を使ってタブのアクティブ状態を検出します。
class TabNotifier {
#originalTitle = document.title;
#timerId = null;
/**
* タイトルを点滅させて通知する
* @param {string} message 通知メッセージ(例: "(3件) 新着メッセージ")
* @param {number} interval ミリ秒(デフォルト 1000)
*/
blink(message, interval = 1000) {
this.stop(); // すでに点滅中なら一旦止める
this.#timerId = setInterval(() => {
document.title =
document.title === this.#originalTitle
? message
: this.#originalTitle;
}, interval);
}
/** 点滅を止めてタイトルを元に戻す */
stop() {
if (this.#timerId !== null) {
clearInterval(this.#timerId);
this.#timerId = null;
}
document.title = this.#originalTitle;
}
/** 元のタイトルを更新(SPA でページ遷移後など) */
updateBase(title) {
this.#originalTitle = title;
document.title = title;
}
}
// 使用例
const notifier = new TabNotifier();
// 未読メッセージが届いたとき
function onNewMessage(count) {
if (document.visibilityState === 'hidden') {
notifier.blink(`(${count}件) 新着メッセージ`);
}
}
// ユーザーがタブに戻ったら通知を止める
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
notifier.stop();
}
});
MutationObserver でタイトル変化を監視する
SPA フレームワークや外部スクリプトが document.title を書き換えるのを検知したいときは、MutationObserver で DOM 変化を監視する方法が役に立ちます。
function watchTitle(callback) {
const titleEl = document.querySelector('title');
if (!titleEl) return null;
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
if (mutation.type === 'childList' || mutation.type === 'characterData') {
callback(document.title);
}
}
});
observer.observe(titleEl, {
childList: true, // テキストノードの追加・削除を検知
characterData: true, // テキスト内容の変化を検知
subtree: true, // 子孫ノードも対象
});
return observer; // 停止するときは observer.disconnect()
}
// 使用例
const titleObserver = watchTitle((newTitle) => {
console.log('タイトルが変わりました:', newTitle);
// ページビューを再送信するなどの処理
});
// 監視を止めるとき
// titleObserver.disconnect();
function watchTitleOnce(callback) {
const observer = watchTitle((newTitle) => {
callback(newTitle);
observer?.disconnect();
});
return observer;
}
SPA でのページタイトル管理
SPA(React・Vue・Svelte など)では URL が変わってもページは再読み込みされないため、手動で document.title を更新する必要があります。
// ページパスとタイトルのマッピング
const routeTitles = {
'/': 'トップページ | codingls',
'/about': 'このサイトについて | codingls',
'/articles': '記事一覧 | codingls',
};
function navigate(path, state = {}) {
history.pushState(state, '', path);
// ※ pushState の第2引数(title)はほぼ全ブラウザで無視されるため
// document.title に直接代入する
document.title = routeTitles[path] ?? 'codingls';
}
// ブラウザの「戻る / 進む」ボタン
window.addEventListener('popstate', () => {
document.title = routeTitles[location.pathname] ?? 'codingls';
});
// data-spa 属性付きリンクをSPAナビゲーションとして処理
document.addEventListener('click', (e) => {
const link = e.target.closest('a[data-spa]');
if (!link) return;
e.preventDefault();
navigate(link.pathname);
});
history.pushState(state, title, url) の第2引数について:仕様上はタイトルを指定できますが、現在ほぼすべてのブラウザが無視します。タイトルの変更には必ず document.title = を使ってください。実用スニペット集
タイトルをクリップボードにコピーする
async function copyPageTitle() {
try {
await navigator.clipboard.writeText(document.title);
console.log('コピーしました:', document.title);
} catch {
// フォールバック(Clipboard API 非対応ブラウザ)
const input = document.createElement('input');
input.value = document.title;
document.body.appendChild(input);
input.select();
document.execCommand('copy');
document.body.removeChild(input);
}
}
// <button onclick="copyPageTitle()">タイトルをコピー</button>
タイトル文字列を構造化する
タイトルに「記事名 | カテゴリ名 | サイト名」のような区切り文字がある場合、分割して構造化できます。
/**
* "記事名 | カテゴリ | サイト名" 形式のタイトルをオブジェクト化
*/
function parsePageTitle(separator = '|') {
const parts = document.title.split(separator).map((s) => s.trim());
return {
article: parts[0] ?? '',
category: parts[1] ?? '',
site: parts[2] ?? '',
all: parts,
};
}
const { article, site } = parsePageTitle();
console.log(article); // "【JavaScript】ページのタイトルを取得する方法..."
console.log(site); // "codingls"
よくある質問(FAQ)
document.title は先頭・末尾の余分な空白を除去するブラウザ実装が多く、厳密には微妙な差が出ることがあります。また、<title> 要素が存在しない場合、document.title は空文字列を返しますが querySelector は null を返すため TypeError が発生します。iframe.contentDocument.title で取得できます。ただし、クロスオリジン(異なるドメイン)の iframe は同一オリジンポリシーにより取得できません。<title> が最も確実にインデックスされます。SPA などで動的にタイトルを変えている場合、クロールタイミングによっては古いタイトルが評価される可能性もあるため、SSR(サーバーサイドレンダリング)や静的生成と組み合わせるのが理想です。setInterval の実行間隔が最低 1 秒以上に絞られることがあります。点滅間隔を 1000ms 以上に設定し、visibilitychange イベントでタブが非アクティブになったタイミングでインターバルを開始する設計にすると安定します。react-helmet、Next.js では metadata API(App Router)や <Head> コンポーネント(Pages Router)が定番です。Vue では @vueuse/head の useHead() を使います。いずれも内部では document.title への代入を行っています。まとめ
ページタイトルの取得・活用方法を整理します。
| 用途 | 使う API・手法 |
|---|---|
| タイトルを取得する(基本) | document.title |
| OGP・meta情報を取得する | document.querySelector('meta[property="og:title"]') |
| タブ通知(点滅) | document.title = + setInterval + visibilitychange |
| タイトル変化を監視する | MutationObserver(childList + characterData) |
| SPA でタイトルを同期 | document.title = + popstate |
document.title はシンプルながら、組み合わせ次第でユーザー体験の向上に直結する重要なプロパティです。タイトルの変更方法についてはWebサイトのページタイトルをJavaScriptで取得・変更する方法もあわせて参照してください。また、タブ通知と相性のよい一定時間操作がなかった場合に処理を実行する方法も実務でよく組み合わせて使われます。