diff --git a/src/__stories__/useSearchParam.story.tsx b/src/__stories__/useSearchParam.story.tsx
new file mode 100644
index 0000000000..dc6cbb5466
--- /dev/null
+++ b/src/__stories__/useSearchParam.story.tsx
@@ -0,0 +1,27 @@
+import { storiesOf } from '@storybook/react';
+import * as React from 'react';
+import { useSearchParam } from '..';
+import ShowDocs from './util/ShowDocs';
+
+const Demo = () => {
+ const foo = useSearchParam('foo');
+
+ return (
+
+
foo: {foo || '🤷♂️'}
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+storiesOf('Sensors|useSearchParam', module)
+ // .add('Docs', () => )
+ .add('Demo', () => );
diff --git a/src/index.ts b/src/index.ts
index 9fc6319435..74a7dd311e 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -63,6 +63,7 @@ export { default as useRafLoop } from './useRafLoop';
* @deprecated This hook is obsolete, use `useMountedState` instead
*/
export { default as useRefMounted } from './useRefMounted';
+export { default as useSearchParam } from './useSearchParam';
export { default as useScroll } from './useScroll';
export { default as useScrolling } from './useScrolling';
export { default as useSessionStorage } from './useSessionStorage';
diff --git a/src/useSearchParam.ts b/src/useSearchParam.ts
new file mode 100644
index 0000000000..b7107e3f32
--- /dev/null
+++ b/src/useSearchParam.ts
@@ -0,0 +1,29 @@
+import { useState, useEffect } from 'react';
+
+const getValue = (search: string, param: string) => new URLSearchParams(search).get(param);
+
+export type UseQueryParam = (param: string) => string | null;
+
+const useSearchParam: UseQueryParam = param => {
+ const [value, setValue] = useState(() => getValue(location.search, param));
+
+ useEffect(() => {
+ const onChange = () => {
+ setValue(getValue(location.search, param));
+ };
+
+ window.addEventListener('popstate', onChange);
+ window.addEventListener('pushstate', onChange);
+ window.addEventListener('replacestate', onChange);
+
+ return () => {
+ window.removeEventListener('popstate', onChange);
+ window.removeEventListener('pushstate', onChange);
+ window.removeEventListener('replacestate', onChange);
+ };
+ }, []);
+
+ return value;
+};
+
+export default useSearchParam;