diff --git a/addons/queryparams/README.md b/addons/queryparams/README.md
new file mode 100644
index 00000000000..8f340200437
--- /dev/null
+++ b/addons/queryparams/README.md
@@ -0,0 +1,32 @@
+# storybook-addon-queryparams
+
+This storybook addon can be helpful if your components need special query parameters to work the way you want them.
+
+## Getting started
+
+First, install the addon.
+
+```sh
+$ yarn add @storybook/addon-queryparams --dev
+```
+
+import the `withQuery` decorator so the url will be changed before rendering stories.
+
+```js
+import React from 'react';
+import { storiesOf, addDecorator } from '@storybook/react';
+import { withQuery } from '@storybook/addon-queryparams';
+
+storiesOf('button', module)
+ .addDecorator(withQuery)
+ .addParameters({
+ query: {
+ mock: true,
+ }
+ })
+ .add('Prints the document.search', () => (
+
+ This is the current document.search: {document.search}, it includes `mock`!
+
+ ));
+```
diff --git a/addons/queryparams/package.json b/addons/queryparams/package.json
new file mode 100644
index 00000000000..1434411e868
--- /dev/null
+++ b/addons/queryparams/package.json
@@ -0,0 +1,44 @@
+{
+ "name": "@storybook/addon-queryparams",
+ "version": "5.1.1",
+ "description": "parameter addon for storybook",
+ "keywords": [
+ "addon",
+ "storybook",
+ "query"
+ ],
+ "homepage": "https://github.com/storybooks/storybook#readme",
+ "bugs": {
+ "url": "https://github.com/storybooks/storybook/issues"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/storybooks/storybook.git",
+ "directory": "addons/addon-queryparams"
+ },
+ "license": "MIT",
+ "main": "dist/index.js",
+ "types": "dist/index.d.ts",
+ "scripts": {
+ "prepare": "node ../../scripts/prepare.js"
+ },
+ "dependencies": {
+ "@storybook/addons": "5.1.1",
+ "@storybook/api": "5.1.1",
+ "@storybook/client-logger": "5.1.1",
+ "@storybook/components": "5.1.1",
+ "@storybook/core-events": "5.1.1",
+ "@storybook/theming": "5.1.1",
+ "common-tags": "^1.8.0",
+ "core-js": "^2.6.5",
+ "global": "^4.3.2",
+ "qs": "^6.6.0",
+ "react": "^16.8.3"
+ },
+ "devDependencies": {
+ "@types/common-tags": "^1.8.0"
+ },
+ "publishConfig": {
+ "access": "public"
+ }
+}
diff --git a/addons/queryparams/src/constants.ts b/addons/queryparams/src/constants.ts
new file mode 100755
index 00000000000..d8fc643d74b
--- /dev/null
+++ b/addons/queryparams/src/constants.ts
@@ -0,0 +1,3 @@
+export const ADDON_ID = 'storybook/queryparams';
+export const PANEL_ID = `${ADDON_ID}/panel`;
+export const PARAM_KEY = `query`;
diff --git a/addons/queryparams/src/index.ts b/addons/queryparams/src/index.ts
new file mode 100644
index 00000000000..bdcc8854569
--- /dev/null
+++ b/addons/queryparams/src/index.ts
@@ -0,0 +1,30 @@
+import { document, history } from 'global';
+import qs from 'qs';
+
+import { makeDecorator, StoryContext, StoryGetter } from '@storybook/addons';
+
+import { PARAM_KEY } from './constants';
+
+export const withQuery = makeDecorator({
+ name: 'withQuery',
+ parameterName: PARAM_KEY,
+ wrapper: (getStory: StoryGetter, context: StoryContext, { parameters }) => {
+ const { location } = document;
+ const currentQuery = qs.parse(location.search, { ignoreQueryPrefix: true });
+ const additionalQuery =
+ typeof parameters === 'string'
+ ? qs.parse(parameters, { ignoreQueryPrefix: true })
+ : parameters;
+
+ const newQuery = qs.stringify(Object.assign({}, currentQuery, additionalQuery));
+ const newLocation = location.href.replace(location.search, `?${newQuery}`);
+
+ history.replaceState({}, document.title, newLocation);
+
+ return getStory(context);
+ },
+});
+
+if (module && module.hot && module.hot.decline) {
+ module.hot.decline();
+}
diff --git a/addons/queryparams/src/typings.d.ts b/addons/queryparams/src/typings.d.ts
new file mode 100644
index 00000000000..e2d982c525c
--- /dev/null
+++ b/addons/queryparams/src/typings.d.ts
@@ -0,0 +1,2 @@
+declare module 'global';
+declare module 'react-sizeme';
diff --git a/addons/queryparams/tsconfig.json b/addons/queryparams/tsconfig.json
new file mode 100644
index 00000000000..8876bb6737a
--- /dev/null
+++ b/addons/queryparams/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "rootDir": "./src",
+ "types": ["webpack-env"]
+ },
+ "include": [
+ "src/**/*"
+ ],
+ "exclude": [
+ "src/__tests__/**/*"
+ ]
+}
diff --git a/examples/official-storybook/package.json b/examples/official-storybook/package.json
index 4a507728e34..62e8a708a09 100644
--- a/examples/official-storybook/package.json
+++ b/examples/official-storybook/package.json
@@ -28,6 +28,7 @@
"@storybook/addon-links": "5.1.1",
"@storybook/addon-notes": "5.1.1",
"@storybook/addon-options": "5.1.1",
+ "@storybook/addon-queryparams": "5.1.1",
"@storybook/addon-storyshots": "5.1.1",
"@storybook/addon-storyshots-puppeteer": "5.1.1",
"@storybook/addon-storysource": "5.1.1",
diff --git a/examples/official-storybook/stories/__snapshots__/addon-queryparams.stories.storyshot b/examples/official-storybook/stories/__snapshots__/addon-queryparams.stories.storyshot
new file mode 100644
index 00000000000..95433107590
--- /dev/null
+++ b/examples/official-storybook/stories/__snapshots__/addon-queryparams.stories.storyshot
@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Storyshots Addons|QueryParams mock is 4 1`] = `
+
+ This story should have an extra url query param: ?mock=4
+
+`;
+
+exports[`Storyshots Addons|QueryParams mock is true 1`] = `
+
+ This story should have an extra url query param: ?mock=truehttp://localhost/
+
+`;
diff --git a/examples/official-storybook/stories/addon-queryparams.stories.js b/examples/official-storybook/stories/addon-queryparams.stories.js
new file mode 100644
index 00000000000..7c32fca677e
--- /dev/null
+++ b/examples/official-storybook/stories/addon-queryparams.stories.js
@@ -0,0 +1,22 @@
+import { document } from 'global';
+import React from 'react';
+import { storiesOf } from '@storybook/react';
+import { withQuery } from '@storybook/addon-queryparams';
+
+// debugger;
+
+storiesOf('Addons|QueryParams', module)
+ .addDecorator(withQuery)
+ .addParameters({
+ query: {
+ mock: true,
+ },
+ })
+ .add('mock is true', () => (
+ This story should have an extra url query param: {document.location.search}
+ ))
+ .add(
+ 'mock is 4',
+ () => This story should have an extra url query param: {document.location.search}
,
+ { query: { mock: 4 } }
+ );