diff --git a/src/useTitle.ts b/src/useTitle.ts index 6d3af7e2..9e421b2d 100644 --- a/src/useTitle.ts +++ b/src/useTitle.ts @@ -1,11 +1,22 @@ -import { useRef } from 'react'; - -function useTitle(title: string) { - const t = useRef(); - - if (t.current !== title) { - document.title = t.current = title; - } +import { useRef, useEffect } from 'react'; +export interface UseTitleOptions { + restoreOnUnmount?: boolean; +} +const DEFAULT_USE_TITLE_OPTIONS: UseTitleOptions = { + restoreOnUnmount: false, +}; +function useTitle(title: string, options: UseTitleOptions = DEFAULT_USE_TITLE_OPTIONS) { + const prevTitleRef = useRef(document.title); + document.title = title; + useEffect(() => { + if (options && options.restoreOnUnmount) { + return () => { + document.title = prevTitleRef.current; + }; + } else { + return; + } + }, []); } export default typeof document !== 'undefined' ? useTitle : (_title: string) => {}; diff --git a/tests/useTitle.test.tsx b/tests/useTitle.test.ts similarity index 51% rename from tests/useTitle.test.tsx rename to tests/useTitle.test.ts index 4ab4b902..d2ec53af 100644 --- a/tests/useTitle.test.tsx +++ b/tests/useTitle.test.ts @@ -13,4 +13,16 @@ describe('useTitle', () => { hook.rerender('My other page title'); expect(document.title).toBe('My other page title'); }); + + it('should restore document title on unmount', () => { + renderHook(props => useTitle(props), { initialProps: 'Old Title' }); + expect(document.title).toBe('Old Title'); + + const hook = renderHook(props => useTitle(props.title, { restoreOnUnmount: props.restore }), { + initialProps: { title: 'New Title', restore: true }, + }); + expect(document.title).toBe('New Title'); + hook.unmount(); + expect(document.title).toBe('Old Title'); + }); });