diff --git a/README.md b/README.md
index cc1728fafd..8c27a9bb07 100644
--- a/README.md
+++ b/README.md
@@ -101,6 +101,7 @@
- [`useCookie`](./docs/useCookie.md) — provides way to read, update and delete a cookie. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/side-effects-usecookie--demo)
- [`useCopyToClipboard`](./docs/useCopyToClipboard.md) — copies text to clipboard.
- [`useDebounce`](./docs/useDebounce.md) — debounces a function. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/side-effects-usedebounce--demo)
+ - [`useDocumentTitle`](./docs/useDocumentTitle.md) — changes document title.
- [`useError`](./docs/useError.md) — error dispatcher. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/side-effects-useerror--demo)
- [`useFavicon`](./docs/useFavicon.md) — sets favicon of the page.
- [`useLocalStorage`](./docs/useLocalStorage.md) — manages a value in `localStorage`.
diff --git a/docs/useDocumentTitle.md b/docs/useDocumentTitle.md
new file mode 100644
index 0000000000..d5c10fa108
--- /dev/null
+++ b/docs/useDocumentTitle.md
@@ -0,0 +1,31 @@
+# `useDocumentTitle`
+
+React hook that updates the `document.title` when the component mounts or when the title changes.
+It also restores the previous title on unmount.
+
+## Usage
+
+```jsx
+import { useDocumentTitle } from 'react-use';
+
+const Demo = () => {
+ const [count, setCount] = React.useState(0);
+
+ useDocumentTitle(`Clicked ${count} times`);
+
+ return (
+
+
Click the button to update document title
+
+
+ );
+};
+```
+
+## Reference
+
+```ts
+useDocumentTitle(title);
+```
diff --git a/src/index.ts b/src/index.ts
index 62b69356b7..04407fbfbc 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -18,6 +18,7 @@ export { default as useCustomCompareEffect } from './useCustomCompareEffect';
export { default as useDebounce } from './useDebounce';
export { default as useDeepCompareEffect } from './useDeepCompareEffect';
export { default as useDefault } from './useDefault';
+export { default as useDocumentTitle } from './useDocumentTitle';
export { default as useDrop } from './useDrop';
export { default as useDropArea } from './useDropArea';
export { default as useEffectOnce } from './useEffectOnce';
diff --git a/src/useDocumentTitle.ts b/src/useDocumentTitle.ts
new file mode 100644
index 0000000000..62ce639b8f
--- /dev/null
+++ b/src/useDocumentTitle.ts
@@ -0,0 +1,12 @@
+import { useEffect } from 'react';
+
+export default function useDocumentTitle(title: string) {
+ useEffect(() => {
+ const previousTitle = document.title;
+ document.title = title;
+
+ return () => {
+ document.title = previousTitle;
+ };
+ }, [title]);
+}
diff --git a/stories/useDocumentTitle.story.tsx b/stories/useDocumentTitle.story.tsx
new file mode 100644
index 0000000000..1a01527ca2
--- /dev/null
+++ b/stories/useDocumentTitle.story.tsx
@@ -0,0 +1,22 @@
+import { storiesOf } from '@storybook/react';
+import * as React from 'react';
+import { useDocumentTitle } from '../src';
+import ShowDocs from './util/ShowDocs';
+
+const Demo = () => {
+ const [count, setCount] = React.useState(0);
+
+ // Update document title whenever count changes
+ useDocumentTitle(`Clicked ${count} times`);
+
+ return (
+
+
Click the button to update document title
+
+
+ );
+};
+
+storiesOf('SideEffects/useDocumentTitle', module)
+ .add('Docs', () => )
+ .add('Demo', () => );
diff --git a/tests/useDocumentTitle.test.ts b/tests/useDocumentTitle.test.ts
new file mode 100644
index 0000000000..f487978b2d
--- /dev/null
+++ b/tests/useDocumentTitle.test.ts
@@ -0,0 +1,22 @@
+import { renderHook } from '@testing-library/react-hooks';
+import { useDocumentTitle } from '../src';
+
+it('should set the document title on mount', () => {
+ const title = 'Doc Title';
+
+ renderHook(() => useDocumentTitle(title));
+
+ expect(document.title).toBe(title);
+});
+
+it('should update the title when argument changes', () => {
+ const { rerender } = renderHook(({ title }) => useDocumentTitle(title), {
+ initialProps: { title: 'First Title' },
+ });
+
+ expect(document.title).toBe('First Title');
+
+ rerender({ title: 'Second Title' });
+
+ expect(document.title).toBe('Second Title');
+});