useDocumentTitle
zyeon/use-document-titleFreeHook
Sets document.title for as long as a component is mounted and restores the pre-mount title on unmount.
Install it
npx shadcn@latest add https://ui.zyeon.ai/r/use-document-title.jsonSource
1"use client"23import * as React from "react"45export interface UseDocumentTitleOptions {6 /** Restore `document.title` to the snapshot taken at mount when unmounting. Defaults to `true`. */7 restoreOnUnmount?: boolean8}910/**11 * Sets `document.title` to `title` and keeps it in sync on every change. At mount12 * the title as it stands **at that instant** is snapshotted into a ref; at unmount13 * it is restored from that snapshot when `restoreOnUnmount` (default `true`), and14 * left at the last title this hook wrote when `false`.15 *16 * `document` is only read and written inside effects — never during render or on17 * the server — so the hook is safe in server-rendered components.18 *19 * Nested instances (say a route layout and a page component that both call it):20 * each instance only remembers the title that was on the page when *it* mounted,21 * and knows nothing about the others. Mount order decides what you see — the one22 * that mounts last writes `document.title` last, so it wins. But if unmount order23 * isn't strictly last-in-first-out (an outer instance unmounting before an inner24 * one), the snapshot the outer instance restores is older than the title the inner25 * one set, and the title "jumps back" further than expected instead of to the26 * enclosing title. That is deliberate, simplified semantics, not a bug — when you27 * genuinely need strict restore ordering across levels, use one shared title stack28 * rather than several independent hook instances (see Customization levers in the29 * docs).30 */31export function useDocumentTitle(32 title: string,33 options: UseDocumentTitleOptions = {},34): void {35 const { restoreOnUnmount = true } = options36 const restoreOnUnmountRef = React.useRef(restoreOnUnmount)37 const previousTitleRef = React.useRef<string | null>(null)3839 // Keep restoreOnUnmountRef on the latest option — the unmount cleanup runs once40 // and must read the current value, not the one closed over at mount.41 React.useEffect(() => {42 restoreOnUnmountRef.current = restoreOnUnmount43 }, [restoreOnUnmount])4445 // Snapshot the title at mount and restore it at unmount; empty deps so it fires46 // once on a real mount/unmount instead of re-snapshotting on every title change.47 React.useEffect(() => {48 previousTitleRef.current = document.title49 return () => {50 if (restoreOnUnmountRef.current && previousTitleRef.current !== null) {51 document.title = previousTitleRef.current52 }53 }54 }, [])5556 React.useEffect(() => {57// … truncated
Files it writes
More from zyeon
All 893 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| useAsyncuse-async | zyeon | Hooks | Free | no deps | |
| useBatteryuse-battery | zyeon | Hooks | Free | no deps | |
| useBroadcastChanneluse-broadcast-channel | zyeon | Hooks | Free | no deps | |
| useClickOutsideuse-click-outside | zyeon | Hooks | Free | no deps | |
| useClipboardPasteuse-clipboard-paste | zyeon | Hooks | Free | no deps | |
| useControllableStateuse-controllable-state | zyeon | Hooks | Free | no deps | |
| useCookieuse-cookie | zyeon | Hooks | Free | no deps | |
| useCopyToClipboarduse-copy-to-clipboard | zyeon | Hooks | Free | no deps |
