Repository: styleguidist/react-styleguidist
Pull request #1063 (2018-07-23 18:48:35)

Update Readme.md
Hello, I though changing 'Lick me' to 'Click me' was good.

sapegin: Why do you think so? Did you find “lick me” offensive? I'm find to change it if there's any reason to do so ;-)

Patch:
diff --git a/bin/styleguidist.js b/bin/styleguidist.js
index b704d679..5ea721e2 100755
--- a/bin/styleguidist.js
+++ b/bin/styleguidist.js
@@ -2,7 +2,7 @@
 /* eslint-disable no-console */
 
 const minimist = require('minimist');
-const chalk = require('chalk');
+const kleur = require('kleur');
 const ora = require('ora');
 const stringify = require('q-i').stringify;
 const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
@@ -28,7 +28,7 @@ process.on('uncaughtException', err => {
 			consts.DOCS_CONFIG
 		);
 	} else if (err instanceof StyleguidistError) {
-		console.error(chalk.bold.red(err.message));
+		console.error(kleur.bold.red(err.message));
 		logger.debug(err.stack);
 	} else {
 		console.error(err.toString());
@@ -170,26 +170,26 @@ function commandServer() {
 function commandHelp() {
 	console.log(
 		[
-			chalk.underline('Usage'),
+			kleur.underline('Usage'),
 			'',
 			'    ' +
-				chalk.bold('styleguidist') +
+				kleur.bold('styleguidist') +
 				' ' +
-				chalk.cyan('<command>') +
+				kleur.cyan('<command>') +
 				' ' +
-				chalk.yellow('[<options>]'),
+				kleur.yellow('[<options>]'),
 			'',
-			chalk.underline('Commands'),
+			kleur.underline('Commands'),
 			'',
-			'    ' + chalk.cyan('build') + '           Build style guide',
-			'    ' + chalk.cyan('server') + '          Run development server',
-			'    ' + chalk.cyan('help') + '            Display React Styleguidist help',
+			'    ' + kleur.cyan('build') + '           Build style guide',
+			'    ' + kleur.cyan('server') + '          Run development server',
+			'    ' + kleur.cyan('help') + '            Display React Styleguidist help',
 			'',
-			chalk.underline('Options'),
+			kleur.underline('Options'),
 			'',
-			'    ' + chalk.yellow('--config') + '        Config file path',
-			'    ' + chalk.yellow('--open') + '          Open Styleguidist in the default browser',
-			'    ' + chalk.yellow('--verbose') + '       Print debug information',
+			'    ' + kleur.yellow('--config') + '        Config file path',
+			'    ' + kleur.yellow('--open') + '          Open Styleguidist in the default browser',
+			'    ' + kleur.yellow('--verbose') + '       Print debug information',
 		].join('\n')
 	);
 }
@@ -200,9 +200,9 @@ function commandHelp() {
 function printServerInstructions(urls) {
 	console.log(`You can now view your style guide in the browser:`);
 	console.log();
-	console.log(`  ${chalk.bold('Local:')}            ${urls.localUrlForTerminal}`);
+	console.log(`  ${kleur.bold('Local:')}            ${urls.localUrlForTerminal}`);
 	if (urls.lanUrlForTerminal) {
-		console.log(`  ${chalk.bold('On your network:')}  ${urls.lanUrlForTerminal}`);
+		console.log(`  ${kleur.bold('On your network:')}  ${urls.lanUrlForTerminal}`);
 	}
 	console.log();
 }
@@ -211,7 +211,7 @@ function printServerInstructions(urls) {
  * @param {object} config
  */
 function printBuildInstructions(config) {
-	console.log('Style guide published to:\n' + chalk.underline(config.styleguideDir));
+	console.log('Style guide published to:\n' + kleur.underline(config.styleguideDir));
 }
 
 /**
@@ -220,7 +220,7 @@ function printBuildInstructions(config) {
  * @param {string} linkUrl
  */
 function printErrorWithLink(message, linkTitle, linkUrl) {
-	console.error(`${chalk.bold.red(message)}\n\n${linkTitle}\n${chalk.underline(linkUrl)}\n`);
+	console.error(`${kleur.bold.red(message)}\n\n${linkTitle}\n${kleur.underline(linkUrl)}\n`);
 }
 
 /**
@@ -244,11 +244,11 @@ function printErrors(header, errors, originalErrors, type) {
  */
 function printStatus(text, type) {
 	if (type === 'success') {
-		console.log(chalk.inverse.bold.green(' DONE ') + ' ' + text);
+		console.log(kleur.inverse.bold.green(' DONE ') + ' ' + text);
 	} else if (type === 'error') {
-		console.error(chalk.reset.inverse.bold.red(' FAIL ') + ' ' + chalk.reset.red(text));
+		console.error(kleur.inverse.bold.red(' FAIL ') + ' ' + kleur.red(text));
 	} else {
-		console.error(chalk.reset.inverse.bold.yellow(' WARN ') + ' ' + chalk.reset.yellow(text));
+		console.error(kleur.inverse.bold.yellow(' WARN ') + ' ' + kleur.yellow(text));
 	}
 }
 
@@ -334,5 +334,5 @@ function printNoLoaderError(errors) {
  * @param {object} object
  */
 function verbose(header, object) {
-	logger.debug(chalk.bold(header) + '\n\n' + stringify(object));
+	logger.debug(kleur.bold(header) + '\n\n' + stringify(object));
 }
diff --git a/docs/CLI.md b/docs/CLI.md
index 2ec329f2..6e55f2dc 100644
--- a/docs/CLI.md
+++ b/docs/CLI.md
@@ -1,13 +1,36 @@
 # CLI commands and options
 
-These commands are supposed to be placed in `package.json` `scripts` (see [Getting Started](GettingStarted.md)). If you want to run them directly, use `./node_modules/.bin/styleguidist`.
+## Commands
 
-`styleguidist server`: Run dev server.
+- `styleguidist server`: Run dev server.
+- `styleguidist build`: Generate a static HTML style guide.
 
-`styleguidist build`: Generate a static HTML style guide.
+## Options
 
-CLI Options:
+| Option            | Description                              |
+| ----------------- | ---------------------------------------- |
+| `--config <file>` | Specify path to a config file            |
+| `--open`          | Open Styleguidist in the default browser |
+| `--verbose`       | Print debug information                  |
 
-- `--config <file>`: Specify path to a config file.
-- `--open`: Open Styleguidist in the default browser.
-- `--verbose`: Print debug information.
+## Usage
+
+Add these commands into your `package.json`’s `scripts` section:
+
+```json
+{
+  "scripts": {
+    "styleguide": "styleguidist server",
+    "styleguide:build": "styleguidist build"
+  }
+}
+```
+
+Or run them directly from your terminal:
+
+```bash
+npx styleguidist server
+npx styleguidist build
+```
+
+**Note:** [npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) is a part of npm and will run locally-installed `styleguidist` package.
diff --git a/docs/Components.md b/docs/Components.md
index 78dea11e..a5ce3f70 100644
--- a/docs/Components.md
+++ b/docs/Components.md
@@ -57,7 +57,7 @@ In each of the following cases, the global identifier will be `Component`.
 | /whatever.js        | `export default function Component() { ... }`                                                                                          | displayName                |
 | /whatever.js        | `export default function SomeName() { ... }`<br>`SomeName.displayName = 'Component';`                                                  | displayName                |
 | /whatever.js        | `export default function Component() { ... }`<br>`Component.displayName = dynamicNamer();`                                             | displayName at declaration |
-| /component.js       | `const name = 'SomeName';`<br>`const componentMap = {`<br>`[name]: function() { ... }`<br>`};`<br>`export default componentMap[name];` | File name                  |
+| /component.js       | `const name = 'SomeName';`<br>`const componentMap = {`<br>`[name]: function() { ... }`<br>`};`<br>`export default componentMap[name];` | Filename                   |
 | /component/index.js | `const name = 'SomeName';`<br>`const componentMap = {`<br>`[name]: function() { ... }`<br>`};`<br>`export default componentMap[name];` | Folder name                |
 
 ### Default vs named exports
@@ -96,7 +96,7 @@ export function Component() { ... }
 // will be exposed globally as Component
 ```
 
-If you export several React components as named exports from a single module, Styleguidist is likely to behave unreliably. If it cannot understand which named export to expose, you may not be able to access that export.
+**Warning:** If you export several React components as named exports from a single module, Styleguidist is likely to behave unreliably. If it cannot understand which named export to expose, you may not be able to access that export.
 
 ## Sections
 
@@ -113,6 +113,8 @@ Each section consists of (all fields are optional):
 - `exampleMode` — Initial state of the code example tab, uses [exampleMode](Configuration.md#examplemode).
 - `usageMode` — Initial state of the props and methods tab, uses [usageMode](Configuration.md#usagemode).
 - `ignore` — string/array of globs that should not be included in the section.
+- `href` - an URL to navigate to instead of navigating to the section content
+- `external` - if set, the link will open in a new window
 
 Configuring a style guide with textual documentation section and a list of components would look like:
 
@@ -134,6 +136,11 @@ module.exports = {
         {
           name: 'Configuration',
           content: 'docs/configuration.md'
+        },
+        {
+          name: 'Live Demo',
+          external: true,
+          href: 'http://example.com'
         }
       ]
     },
diff --git a/docs/Configuration.md b/docs/Configuration.md
index bfa00e44..dbb2fd95 100644
--- a/docs/Configuration.md
+++ b/docs/Configuration.md
@@ -21,6 +21,7 @@ By default, Styleguidist will look for `styleguide.config.js` file in your proje
 - [`handlers`](#handlers)
 - [`ignore`](#ignore)
 - [`logger`](#logger)
+- [`mountPointId`](#mountpointid)
 - [`pagePerSection`](#pagepersection)
 - [`printBuildInstructions`](#printbuildinstructions)
 - [`printServerInstructions`](#printserverinstructions)
@@ -159,7 +160,7 @@ When writing your own default example file, `__COMPONENT__` will be replaced by
 
 #### `getComponentPathLine`
 
-Type: `Function`, default: component file name
+Type: `Function`, default: component filename
 
 Function that returns a component path line (displayed under the component name).
 
@@ -277,15 +278,21 @@ module.exports = {
 }
 ```
 
+#### `mountPointId`
+
+Type: `string`, defaults: `rsg-root`
+
+The ID of a DOM element where Styleguidist mounts.
+
 #### `pagePerSection`
 
 Type: `Boolean`, default: `false`
 
-Render one section or component per page, starting with the first.
+Render one section or component per page.
 
-If set to `true`, each section will be single page.
+If `true`, each section will be a single page.
 
-The value may be differ on each environment.
+The value may depends on a current environment:
 
 ```javascript
 module.exports = {
@@ -293,7 +300,7 @@ module.exports = {
 }
 ```
 
-If you want to isolate section's children as single pages (sub-routes), you can add `sectionDepth` in each section, which it is the number sub-routes for depth that it will have.
+To isolate section’s children as single pages (subroutes), add `sectionDepth` into each section with the number of subroutes (depth) to render as single pages.
 
 For example:
 
@@ -316,7 +323,8 @@ module.exports = {
           ]
         }
       ],
-      sectionDepth: 2 // It will show "Documentation" and "Files" as single pages, filtering his children.
+      // Will show "Documentation" and "Files" as single pages, filtering its children
+      sectionDepth: 2
     },
     {
       name: 'Components',
@@ -330,7 +338,8 @@ module.exports = {
           ]
         }
       ]
-      sectionDepth: 1, // It will show "Components" as single page, filtering his children.
+      // Will show "Components" as single page, filtering its children
+      sectionDepth: 1,
     },
     {
       name: 'Examples',
@@ -344,7 +353,8 @@ module.exports = {
           ]
         }
       ]
-      sectionDepth: 0, // There is not sub-routes, "Examples" will be show all his children on page.
+      // There is no subroutes, "Examples" will show all its children on a page
+      sectionDepth: 0,
     }
   ]
 }
@@ -456,17 +466,21 @@ module.exports = {
 
 Type: `Object`, optional
 
-Shows 'Fork Me' ribbon in the top-right corner. If `ribbon` key is present, then it's required to add `url` property; `text` property is optional. If you want to change styling of the ribbon, please, refer to the [theme section](#theme).
+Show “Fork Me” ribbon in the top right corner.
 
 ```javascript
 module.exports = {
   ribbon: {
+    // Link to open on the ribbon click (required)
     url: 'http://example.com/',
+    // Text to show on the ribbon (optional)
     text: 'Fork me on GitHub'
   }
 }
 ```
 
+Use [theme](#theme) config option to change ribbon style.
+
 #### `sections`
 
 Type: `Array`, optional
@@ -479,11 +493,11 @@ See examples of [sections configuration](Components.md#sections).
 
 Type: `String`, default: `0.0.0.0`
 
-Dev server host name.
+Dev server hostname.
 
 #### `serverPort`
 
-Type: `Number`, default: `process.env.NODE_ENV` or `6060`
+Type: `Number`, default: `6060`
 
 Dev server port.
 
@@ -503,7 +517,7 @@ Ignore components that don’t have an example file (as determined by [getExampl
 
 Type: `Object`, optional
 
-Override React components used to render the style guide.
+Override React components used to render the style guide:
 
 ```javascript
 module.exports = {
@@ -519,9 +533,9 @@ module.exports = {
 
 See an example of [customized style guide](https://github.com/styleguidist/react-styleguidist/tree/master/examples/customised).
 
-If you want to wrap, rather than replace a component, make sure to import the default implementation using the full path to `react-styleguidist`. See an example of [wrapping a Styleguidist component](https://github.com/styleguidist/react-styleguidist/tree/master/examples/customised/styleguide/components/Sections.js).
+To wrap, rather than replace a component, make sure to import the default implementation using the full path to `react-styleguidist`. See an example of [wrapping a Styleguidist component](https://github.com/styleguidist/react-styleguidist/blob/master/examples/customised/styleguide/components/Sections.js).
 
-**Note**: these components are not guaranteed to be safe from breaking changes in react-styleguidist updates.
+**Note**: these components are not guaranteed to be safe from breaking changes in React Styleguidist updates.
 
 #### `styleguideDir`
 
diff --git a/docs/Cookbook.md b/docs/Cookbook.md
index 4183396a..2867eae0 100644
--- a/docs/Cookbook.md
+++ b/docs/Cookbook.md
@@ -19,7 +19,6 @@
 - [How to debug my components and examples?](#how-to-debug-my-components-and-examples)
 - [How to debug the exceptions thrown from my components?](#how-to-debug-the-exceptions-thrown-from-my-components)
 - [How to use production or development build of React?](#how-to-use-production-or-development-build-of-react)
-- [Why does the style guide list one of my prop types as `unknown`?](#why-does-the-style-guide-list-one-of-my-prop-types-as-unknown)
 - [Why object references don’t work in example component state?](#why-object-references-dont-work-in-example-component-state)
 - [How to use Vagrant with Styleguidist?](#how-to-use-vagrant-with-styleguidist)
 - [How to add a favicon?](#how-to-add-a-favicon)
@@ -27,6 +26,7 @@
 - [How to add fonts from Google Fonts?](#how-to-add-fonts-from-google-fonts)
 - [How to reuse project’s webpack config?](#how-to-reuse-projects-webpack-config)
 - [How to use React Styleguidist with Redux, Relay or Styled Components?](#how-to-use-react-styleguidist-with-redux-relay-or-styled-components)
+- [How to change the names of components displayed in Styleguidist UI?](#how-to-change-the-names-of-components-displayed-in-styleguidist-ui)
 - [What’s the difference between Styleguidist and Storybook?](#whats-the-difference-between-styleguidist-and-storybook)
 - [Are there any other projects like this?](#are-there-any-other-projects-like-this)
 
@@ -53,7 +53,7 @@ let textarea
 
 ## How to exclude some components from style guide?
 
-Styleguidist will ignore tests (`__tests__` folder and file names containing `.test.js` or `.spec.js`) by default.
+Styleguidist will ignore tests (`__tests__` folder and filenames containing `.test.js` or `.spec.js`) by default.
 
 Use [ignore](Configuration.md#ignore) option to customize this behavior:
 
@@ -76,7 +76,7 @@ const Button = require('../common/Button')
 ;<Button>Push Me Tender</Button>
 ```
 
-Or, if you want to make these components available for all examples:
+Or, to make these components available for all examples:
 
 ```jsx
 // styleguide.config.js
@@ -102,12 +102,12 @@ Require these components in your examples:
 
 ## How to dynamically load other components in an example?
 
-Although examples don’t have direct access to webpack’s `require.context` feature, you _can_ use it in a separate helper file which you require in your example code. If you wanted to create an example to load and show all of your icon components, you could do this:
+Although examples don’t have direct access to webpack’s `require.context` feature, you _can_ use it in a separate helper file which you require in your example code. If you wanted to create an example to load and show all your icon components, you could do this:
 
-```jsx
+```js
 // load-icons.js
 const iconsContext = require.context('./icons/', true, /js$/)
-const icons = Object.keys(iconsContext).reduce((icons, file) => {
+const icons = iconsContext.keys().reduce((icons, file) => {
   const Icon = iconsContext(file).default
   const label = file.slice(2, -3) // strip './' and '.js'
   icons[label] = Icon
@@ -115,8 +115,12 @@ const icons = Object.keys(iconsContext).reduce((icons, file) => {
 }, {})
 
 export default icons
+```
 
+````markdown
 // IconGallery.md
+
+```jsx noeditor
 const icons = require('./load-icons').default
 
 const iconElements = Object.keys(icons).map(iconName => {
@@ -127,8 +131,9 @@ const iconElements = Object.keys(icons).map(iconName => {
     </span>
   )
 })
-;<div>{iconElements}</div>
+<div>{iconElements}</div>
 ```
+````
 
 ## How to display the source code of any file?
 
@@ -373,7 +378,7 @@ module.exports = {
 
 ## How to use production or development build of React?
 
-In some cases, you might need to use development build of React instead of the default [production one](https://reactjs.org/docs/optimizing-performance.html#use-the-production-build). For example, this might be needed if you use React Native and make references to a React Native component's PropTypes in your code. As React removes all PropTypes in its production build, your code will fail. By default, React Styleguidist uses the development build for the dev server, and the production one for static builds.
+In some cases, you might need to use development build of React instead of the default [production one](https://reactjs.org/docs/optimizing-performance.html#use-the-production-build). For example, this might be needed if you use React Native and make references to a React Native component’s PropTypes in your code. As React removes all PropTypes in its production build, your code will fail. By default, Styleguidist uses the development build for the dev server, and the production one for static builds.
 
 ```js
 import React from 'react'
@@ -382,14 +387,12 @@ import { TextInput } from 'react-native'
 const CustomInput = ({ value }) => <TextInput value={value} />
 
 CustomInput.propTypes = {
-  // will fail in a static build
+  // Will fail in a static build
   value: TextInput.value.isRequired
 }
 ```
 
-If you use code similar to this, you might encounter errors such as `Cannot read property 'isRequired' of undefined`.
-
-To avoid this, you need to tell React Styleguidist to use React’s development build. To do this, simply set the `NODE_ENV` variable to `development` in your npm script.
+If you use code like the example above, you might see a `Cannot read property 'isRequired' of undefined` error. To avoid it, you need to tell Styleguidist to use React’s development build. To do this, set the `NODE_ENV` variable to `development` in your npm script.
 
 ```json
 {
@@ -399,29 +402,11 @@ To avoid this, you need to tell React Styleguidist to use React’s development
 }
 ```
 
-The script above uses [cross-env](https://github.com/kentcdodds/cross-env) to make sure the environment variable is properly set on all platforms. Run `npm i -D cross-env` to add it.
-
-## Why does the style guide list one of my prop types as `unknown`?
-
-This occurs when you are assigning props via `getDefaultProps` that are not listed within the components `propTypes`.
-
-For example, the color prop here is assigned via `getDefaultProps` but missing from the `propTypes`, therefore the style guide is unable to display the correct prop type.
-
-```javascript
-Button.propTypes = {
-  children: PropTypes.string.isRequired,
-  size: PropTypes.oneOf(['small', 'normal', 'large'])
-}
-
-Button.defaultProps = {
-  color: '#333',
-  size: 'normal'
-}
-```
+**Note:** The script above uses [cross-env](https://github.com/kentcdodds/cross-env) to make sure the environment variable is properly set on all platforms. Run `npm i -D cross-env` to add it.
 
 ## Why object references don’t work in example component state?
 
-Object references will not work as expected in examples state due to how the examples code is evaluated:
+Object references may not work as expected in examples state:
 
 ```jsx
 const items = [{ id: 0 }, { id: 1 }]
@@ -527,6 +512,25 @@ See in [configuring webpack](Webpack.md#reusing-your-projects-webpack-config).
 
 See [working with third-party libraries](Thirdparties.md).
 
+## How to change the names of components displayed in Styleguidist UI?
+
+You might want to change your components’ names to be displayed differently, for example, for stylistic purposes or to give them a more descriptive names in your style guide.
+
+This can be done by adding [@visibleName](Documenting.md#defining-custom-component-names) tag to your component documentation.
+
+In case you want to change components’ names in bulk, for example, based on their current name, you can use [updateDocs](Configuration.md#updatedocs) config option:
+
+```javascript
+module.exports = {
+  updateDocs(docs) {
+    if (docs && docs.displayName) {
+      docs.visibleName = docs.displayName.toLowerCase()
+    }
+    return docs
+  }
+}
+```
+
 ## What’s the difference between Styleguidist and Storybook?
 
 Both tools are good and mature, they have many similarities but also some distinctions that may make you choose one or the other. For me the biggest distinction is how you describe component variations.
@@ -587,7 +591,7 @@ Another important distinction is that Storybook shows only one variation of one
 - [Atellier](https://github.com/scup/atellier), a React components emulator.
 - [Carte Blanche](https://github.com/carteb/carte-blanche), an isolated development space with integrated fuzz testing for your components.
 - [Catalog](https://github.com/interactivethings/catalog), create living style guides using Markdown or React.
-- [Cosmos](https://github.com/react-cosmos/react-cosmos), a tool for designing truly encapsulated React components.
+- [Cosmos](https://github.com/react-cosmos/react-cosmos), a tool for designing encapsulated React components.
 - [React BlueKit](http://bluekit.blueberry.io/), render React components with editable source and live preview.
 - [React Cards](https://github.com/steos/reactcards), devcards for React.
 - [React Styleguide Generator](https://github.com/pocotan001/react-styleguide-generator), a React style guide generator.
diff --git a/docs/Documenting.md b/docs/Documenting.md
index 55be05f1..2a3852f4 100644
--- a/docs/Documenting.md
+++ b/docs/Documenting.md
@@ -13,6 +13,7 @@ Styleguidist generates documentation for your components based on the comments i
 - [External examples using doclet tags](#external-examples-using-doclet-tags)
 - [Public methods](#public-methods)
 - [Ignoring props](#ignoring-props)
+- [Defining custom component names](#defining-custom-component-names)
 - [Using JSDoc tags](#using-jsdoc-tags)
 - [Writing code examples](#writing-code-examples)
 - [Limitations](#limitations)
@@ -91,7 +92,7 @@ Styleguidist will look for any `Readme.md` or `ComponentName.md` files in the co
 
 > **Note:** You can configure examples file name with the [getExampleFilename](Configuration.md#getexamplefilename) option.
 
-> **Note:** If you need to display some JavaScript code in your documentation that you don't want rendered as an interactive playground you can use the `static` modifier with a language tag (e.g. `js static`).
+> **Note:** If you need to display some JavaScript code in your documentation that you don’t want rendered as an interactive playground you can use the `static` modifier with a language tag (e.g. `js static`).
 
 ## External examples using doclet tags
 
@@ -143,6 +144,21 @@ MyComponent.propTypes = {
 }
 ```
 
+## Defining custom component names
+
+Use @visibleName JSDoc tag to define component names that are used in the Styleguidist UI:
+
+```javascript
+/**
+ * The only true button.
+ *
+ * @visibleName The Best Button Ever 🐙
+ */
+class Button extends React.Component {
+```
+
+The component will be displayed with a custom “The Best Button Ever 🐙” name and this will not change the name of the component used in code of your app or Styleguidist examples.
+
 ## Using JSDoc tags
 
 You can use the following [JSDoc](http://usejsdoc.org/) tags when documenting components, props and methods:
@@ -218,7 +234,7 @@ Code examples in Markdown use ES6+JSX syntax. All components covered by the styl
 
 > **Note:** Styleguidist uses [Bublé](https://buble.surge.sh/guide/) to run ES6 code on the frontend, it supports [most of the ES6 features](https://buble.surge.sh/guide/#unsupported-features).
 
-You can also `require()` other modules (e.g. mock data that you use in your unit tests):
+You can also `require()` other modules (like mock data for unit tests):
 
 ```jsx
 const mockData = require('./mocks')
diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md
index f388f2ce..96ab3106 100644
--- a/docs/GettingStarted.md
+++ b/docs/GettingStarted.md
@@ -2,7 +2,7 @@
 
 ## 1. Install Styleguidist
 
-Install webpack if you don’t have it already and aren't using Create React App:
+Install webpack if you don’t have it already and aren’t using Create React App:
 
 ```bash
 npm install --save-dev webpack
@@ -16,19 +16,21 @@ npm install --save-dev react-styleguidist
 
 ## 2. Configure your style guide
 
-**If you’re using [Create React App](https://github.com/facebookincubator/create-react-app) you can skip this step.**
+**If you’re using [Create React App](https://github.com/facebook/create-react-app) you can skip this step.**
 
-[Point Styleguidist to your React components](Components.md) and [tell it how to load your code](Webpack.md).
+- [Point Styleguidist to your React components](Components.md)
+- [Tell Styleguidist how to load your app’s code](Webpack.md)
 
 ## 3. Start your style guide
 
-Run **`npx styleguidist server`** to start a style guide dev server.
+- Run **`npx styleguidist server`** to start a style guide dev server.
+- Run **`npx styleguidist build`** to build a production HTML version.
 
-Run **`npx styleguidist build`** to build a static version.
+**Note:** We recommend [adding these commands to your `package.json`](CLI.md).
 
 ## 4. Start documenting your components
 
-See how to [document your components](Documenting.md)
+See how to [document your components](Documenting.md).
 
 ## Have questions?
 
diff --git a/docs/Maintenance.md b/docs/Maintenance.md
index b2752788..88092c5f 100644
--- a/docs/Maintenance.md
+++ b/docs/Maintenance.md
@@ -12,6 +12,7 @@
   - [Minor and major releases](#minor-and-major-releases)
 - [Change logs](#change-logs)
   - [What is a good change log](#what-is-a-good-change-log)
+  - [What should be in a change log](#what-should-be-in-a-change-log)
   - [Preparing a change log](#preparing-a-change-log)
 
 <!-- tocstop -->
@@ -68,7 +69,12 @@ We’re using [milestones](https://github.com/styleguidist/react-styleguidist/mi
 - Change log should explain how to migrate to a new versions if there are breaking changes.
 - Commit log **is not** a change log.
 
-Check out [Keep a Changelog](https://keepachangelog.com/) for more details on good change logs.
+Here’s a [good example of a change log](https://github.com/styleguidist/react-styleguidist/releases/tag/v7.1.0). Check out [Keep a Changelog](https://keepachangelog.com/) for more details on good change logs.
+
+### What should be in a change log
+
+- Information about pull request authors:<br> `(#1040 by @rafaesc)`
+- Open Collective link at the very top:<br> `👋 **[Support Styleguidist](https://opencollective.com/styleguidist) on Open Collective** 👋`
 
 ### Preparing a change log
 
diff --git a/docs/Thirdparties.md b/docs/Thirdparties.md
index f5182591..795df3f4 100644
--- a/docs/Thirdparties.md
+++ b/docs/Thirdparties.md
@@ -8,7 +8,8 @@
 - [Using Styleguidist with other libraries](#using-styleguidist-with-other-libraries)
   - [Redux](#redux)
   - [Relay](#relay)
-  - [Styled Components](#styled-components)
+  - [Styled-components](#styled-components)
+  - [Emotion](#emotion)
   - [Fela](#fela)
   - [CSS Modules with react-css-modules](#css-modules-with-react-css-modules)
   - [Styletron](#styletron)
@@ -39,7 +40,7 @@ export function Button({ color, size, children }) {
 export default CSSModules(Button, styles)
 ```
 
-Each example is rendered in an independent React root. You can control React context by defining a custom `Wrapper` component like this:
+Each example is rendered in an independent React root. You can control React context by defining a custom Wrapper component like this:
 
 ```javascript
 // styleguide.config.js
@@ -132,7 +133,7 @@ import Relay from 'real-react-relay'
 // Copy contents from https://gist.github.com/mikberg/07b4006e22aacf31ffe6
 ```
 
-**Second, provide sample data to your React components** to be able to message actual results from your GraphQL backend:
+**Second, provide sample data to your React components** to send actual results from your GraphQL backend:
 
 ```js
 // styleguide.config.js
@@ -160,9 +161,9 @@ module.exports = {
 
 _Based on @mikberg’s [blog post](https://medium.com/@mikaelberg/writing-simple-unit-tests-with-relay-707f19e90129)._
 
-### Styled Components
+### Styled-components
 
-The recommended way of using [Styled Components](https://www.styled-components.com/) is by using a special `@component` JSDoc annotation:
+The recommended way of using [styled-components](https://www.styled-components.com/) is by using a special `@component` JSDoc annotation:
 
 ```jsx
 import React from 'react'
@@ -178,11 +179,22 @@ const SalmonButton = styled.button`
 export default SalmonButton
 ```
 
-#### Adding Styled Components `ThemeProvider`
+**Warning:** object notation isn’t supported yet, use string literals instead:
 
-If your styled-components require a theme to render properly, you'll want to add a ThemeProvider Wrapper component to the docs.
+```diff
+- const Button = styled.button({
+-  color: 'tomato'
+- })
++ const Button = styled.button`
++  color: tomato;
++ `
+```
+
+#### Adding styled-components `ThemeProvider`
+
+If your styled-components require a theme to render properly, add a `ThemeProvider` to your style guide.
 
-First, you'll need to create your Wrapper component. For this example we'll put it in the `styleguide/` directory, but you can add it anywhere you want.
+First, create your `Wrapper` component. For this example we’ll put it in the `styleguide/` directory, but you can add it anywhere you want.
 
 ```jsx
 // styleguide/ThemeWrapper.js
@@ -202,7 +214,7 @@ export default class ThemeWrapper extends Component {
 }
 ```
 
-Next, you'll need to add ThemeWrapper to your `styleguide.config.js`.
+Next, add `ThemeWrapper` to your `styleguide.config.js`.
 
 ```javascript
 const path = require('path');
@@ -215,7 +227,11 @@ module.exports = {
 }
 ```
 
-This will automatically apply your theme to your styled-components. When you fire up the styleguide, `npx styleguidist server`, you should see your components render as expected.
+This will automatically apply your theme to your styled-components. When you fire up the style guide, `npx styleguidist server`, you should see your components render as expected.
+
+### Emotion
+
+The usage is similar to [styled-components](#styled-components).
 
 ### Fela
 
@@ -251,7 +267,7 @@ const { StyletronProvider } = require('styletron-react')
 </StyletronProvider>
 ```
 
-To use Styletron in every component, which is similar to [Redux](#redux), redefine the Wrapper component:
+To use Styletron in every component redefine the Wrapper component:
 
 ```javascript
 // styleguide.config.js
diff --git a/docs/Webpack.md b/docs/Webpack.md
index 90a6118a..609f898d 100644
--- a/docs/Webpack.md
+++ b/docs/Webpack.md
@@ -31,7 +31,7 @@ module.exports = {
 }
 ```
 
-Or if you want to merge it with other options:
+Or, merge it with other options:
 
 ```javascript
 module.exports = {
@@ -85,23 +85,22 @@ module.exports = {
 
 ## Create React App
 
-[Create React App](https://github.com/facebookincubator/create-react-app) is supported out of the box, you don’t even need to create a style guide config if your components could be found using a default pattern: all files with `.js` or `.jsx` extensions inside `src/components` or `src/Components` folders.
+[Create React App](https://github.com/facebook/create-react-app) is supported out of the box, you don’t even need to create a style guide config if your components could be found using a default pattern: all files with `.js` or `.jsx` extensions inside `src/components` or `src/Components` folders.
 
-## Create React App, TypeScript
+## Create React App with TypeScript
 
-If you're using [Create React App](https://github.com/facebookincubator/create-react-app) and Typescript, you need to:
+If you’re using [Create React App](https://github.com/facebook/create-react-app) and TypeScript:
 
-- Install [react-docgen-typescript](https://github.com/styleguidist/react-docgen-typescript)
-- Create a `styleguide.config.js`, see [this guide](Configuration.md)
-- Add a `components`, `webpackConfig` and `propsParser` section to your `styleguide.config.js`:
+1.  Install [react-docgen-typescript](https://github.com/styleguidist/react-docgen-typescript).
+2.  Create a `styleguide.config.js`, see [configuration](Configuration.md) reference.
+3.  Update your `styleguide.config.js`:
 
-```javascript
-module.exports = {
-  components: 'src/components/**/*.{ts,tsx}',
-  propsParser: require('react-docgen-typescript').parse,
-  webpackConfig: require('react-scripts-ts/config/webpack.config.dev.js')
-}
-```
+    ```javascript
+    module.exports = {
+      propsParser: require('react-docgen-typescript').parse,
+      webpackConfig: require('react-scripts-ts/config/webpack.config.dev')
+    }
+    ```
 
 ## Non-webpack projects
 
diff --git a/examples/basic/src/components/Button/Readme.md b/examples/basic/src/components/Button/Readme.md
index 16ebd3c9..a4538618 100644
--- a/examples/basic/src/components/Button/Readme.md
+++ b/examples/basic/src/components/Button/Readme.md
@@ -8,7 +8,7 @@ Big pink button:
 
 ```jsx
 <Button size="large" color="deeppink">
-  Lick Me
+  Click Me
 </Button>
 ```
 
diff --git a/examples/basic/src/components/CounterButton/CounterButton.js b/examples/basic/src/components/CounterButton/CounterButton.js
index 9dab6738..05c99717 100644
--- a/examples/basic/src/components/CounterButton/CounterButton.js
+++ b/examples/basic/src/components/CounterButton/CounterButton.js
@@ -16,10 +16,10 @@ export default class CounterButton extends Component {
 	 *
 	 * @public
 	 * @version 1.0.5
-	 * @param {Number} newValue New value for the counter
+	 * @param {Number} [newValue=0] New value for the counter
 	 * @returns {string} Test
 	 */
-	set(newValue) {
+	set(newValue = 0) {
 		this.setState({
 			value: parseInt(newValue, 10),
 		});
diff --git a/examples/basic/src/components/PushButton/PushButton.js b/examples/basic/src/components/PushButton/PushButton.js
index 48e60621..86884dbf 100644
--- a/examples/basic/src/components/PushButton/PushButton.js
+++ b/examples/basic/src/components/PushButton/PushButton.js
@@ -4,7 +4,8 @@ import PropTypes from 'prop-types';
 import './PushButton.css';
 
 /**
- * An example-less button.
+ * An example-less button with custom display name.
+ * @visibleName Push Button 🎉
  */
 export default function PushButton({ color, size, children }) {
 	const styles = {
diff --git a/examples/customised/styleguide.config.js b/examples/customised/styleguide.config.js
index b0fe6c04..967f8ef3 100644
--- a/examples/customised/styleguide.config.js
+++ b/examples/customised/styleguide.config.js
@@ -47,7 +47,7 @@ module.exports = {
 	styleguideComponents: {
 		LogoRenderer: path.join(__dirname, 'styleguide/components/Logo'),
 		StyleGuideRenderer: path.join(__dirname, 'styleguide/components/StyleGuide'),
-		SectionsRenderer: path.join(__dirname, 'styleguide/components/Sections'),
+		SectionsRenderer: path.join(__dirname, 'styleguide/components/SectionsRenderer'),
 	},
 	webpackConfig: {
 		module: {
diff --git a/examples/customised/styleguide/components/Sections.js b/examples/customised/styleguide/components/SectionsRenderer.js
similarity index 63%
rename from examples/customised/styleguide/components/Sections.js
rename to examples/customised/styleguide/components/SectionsRenderer.js
index 847708e1..39e9ffea 100644
--- a/examples/customised/styleguide/components/Sections.js
+++ b/examples/customised/styleguide/components/SectionsRenderer.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
 import Styled from 'rsg-components/Styled';
 import Heading from 'rsg-components/Heading';
 // Import default implementation from react-styleguidist using the full path
-import DefaultSections from 'react-styleguidist/lib/rsg-components/Sections/SectionsRenderer';
+import DefaultSectionsRenderer from 'react-styleguidist/lib/rsg-components/Sections/SectionsRenderer';
 
 const styles = ({ fontFamily, color, space }) => ({
 	headingSpacer: {
@@ -18,11 +18,12 @@ const styles = ({ fontFamily, color, space }) => ({
 export function SectionsRenderer({ classes, children }) {
 	return (
 		<div>
-			<div className={classes.headingSpacer}>
-				<Heading level={1}>Example Components</Heading>
-				<p className={classes.descriptionText}>These are the greatest components</p>
-			</div>
-			<DefaultSections>{children}</DefaultSections>
+			{!!children.length &&
+				<div className={classes.headingSpacer}>
+					<Heading level={1}>Example Components</Heading>
+					<p className={classes.descriptionText}>These are the greatest components</p>
+				</div>}
+			<DefaultSectionsRenderer>{children}</DefaultSectionsRenderer>
 		</div>
 	);
 }
diff --git a/examples/sections/docs/One.md b/examples/sections/docs/One.md
index d2eec9a8..07c3fd7a 100644
--- a/examples/sections/docs/One.md
+++ b/examples/sections/docs/One.md
@@ -66,3 +66,12 @@ console.log(eatFood(food))
 ```
 
 Some more text here.
+
+## Details
+
+<details>
+ <summary>Solution</summary>
+
+Some hidden text.
+
+</details>
diff --git a/examples/sections/styleguide.config.js b/examples/sections/styleguide.config.js
index 0e776ad4..46d364b6 100644
--- a/examples/sections/styleguide.config.js
+++ b/examples/sections/styleguide.config.js
@@ -25,6 +25,11 @@ module.exports = {
 						},
 					],
 				},
+				{
+					name: 'Online documentation',
+					href: 'https://github.com/styleguidist/react-styleguidist',
+					external: true,
+				},
 			],
 			sectionDepth: 2,
 		},
diff --git a/loaders/styleguide-loader.js b/loaders/styleguide-loader.js
index 390ee9c4..278b7f47 100644
--- a/loaders/styleguide-loader.js
+++ b/loaders/styleguide-loader.js
@@ -25,6 +25,7 @@ const CLIENT_CONFIG_OPTIONS = [
 	'editorConfig',
 	'ribbon',
 	'pagePerSection',
+	'mountPointId',
 ];
 
 module.exports = function() {};
diff --git a/loaders/utils/getProps.js b/loaders/utils/getProps.js
index f89cd529..dff4c006 100644
--- a/loaders/utils/getProps.js
+++ b/loaders/utils/getProps.js
@@ -11,6 +11,13 @@ const logger = require('glogg')('rsg');
 
 const examplesLoader = path.resolve(__dirname, '../examples-loader.js');
 
+const JS_DOC_METHOD_PARAM_TAG_SYNONYMS = ['param', 'arg', 'argument'];
+const JS_DOC_METHOD_RETURN_TAG_SYNONYMS = ['return', 'returns'];
+const JS_DOC_ALL_SYNONYMS = [
+	...JS_DOC_METHOD_PARAM_TAG_SYNONYMS,
+	...JS_DOC_METHOD_RETURN_TAG_SYNONYMS,
+];
+
 // HACK: We have to make sure that doclets is a proper object with correct prototype to
 // work around an issue in react-docgen that breaks the build if a component has JSDoc tags
 // like @see in its description, see https://github.com/reactjs/react-docgen/issues/155
@@ -33,6 +40,10 @@ const doesExternalExampleFileExist = (componentPath, exampleFile) => {
 	return doesFileExist;
 };
 
+const getMergedTag = (tags, names) => {
+	return names.reduce((params, name) => [...params, ...(tags[name] || [])], []);
+};
+
 /**
  * 1. Remove non-public methods.
  * 2. Extract doclets.
@@ -50,11 +61,30 @@ module.exports = function getProps(doc, filepath) {
 		return doclets && doclets.public;
 	});
 
-	// Parse the docblock of the remaining methods with doctrine to retrieve the JsDoc tags
+	// Parse the docblock of the remaining methods with doctrine to retrieve
+	// the JSDoc tags
 	doc.methods = doc.methods.map(method => {
-		return Object.assign(method, {
-			tags: getDoctrineTags(doctrine.parse(method.docblock)),
-		});
+		const allTags = getDoctrineTags(
+			doctrine.parse(method.docblock, { sloppy: true, unwrap: true })
+		);
+
+		// Merge with react-docgen information about arguments and return value
+		// with information from JSDoc
+
+		const paramTags = getMergedTag(allTags, JS_DOC_METHOD_PARAM_TAG_SYNONYMS);
+		const params =
+			method.params &&
+			method.params.map(param =>
+				Object.assign(param, paramTags.find(tagParam => tagParam.name === param.name))
+			);
+
+		const returnTags = getMergedTag(allTags, JS_DOC_METHOD_RETURN_TAG_SYNONYMS);
+		const returns = method.returns || returnTags[0];
+
+		// Remove tag synonyms
+		const tags = _.omit(allTags, JS_DOC_ALL_SYNONYMS);
+
+		return Object.assign(method, returns && { returns }, params && { params }, { tags });
 	});
 
 	if (doc.description) {
@@ -68,6 +98,7 @@ module.exports = function getProps(doc, filepath) {
 
 		let exampleFileExists = false;
 		let exampleFile = doc.doclets.example;
+
 		// doc.doclets.example might be a boolean or undefined
 		if (typeof doc.doclets.example === 'string') {
 			exampleFile = doc.doclets.example.trim();
@@ -87,7 +118,8 @@ module.exports = function getProps(doc, filepath) {
 		Object.keys(doc.props).forEach(propName => {
 			const prop = doc.props[propName];
 			const doclets = getDocletsObject(prop.description);
-			// when a prop is listed in defaultProps but not in props the prop.description is undefined
+
+			// When a prop is listed in defaultProps but not in props the prop.description is undefined
 			const documentation = doctrine.parse(prop.description || '');
 
 			// documentation.description is the description without tags
@@ -106,5 +138,16 @@ module.exports = function getProps(doc, filepath) {
 		doc.displayName = getNameFromFilePath(filepath);
 	}
 
+	if (doc.doclets && doc.doclets.visibleName) {
+		doc.visibleName = doc.doclets.visibleName;
+
+		// Custom tag is added both to doclets and tags
+		// Removing from both locations
+		delete doc.doclets.visibleName;
+		if (doc.tags) {
+			delete doc.tags.visibleName;
+		}
+	}
+
 	return doc;
 };
diff --git a/loaders/utils/getSections.js b/loaders/utils/getSections.js
index 22a4b772..05845ee0 100644
--- a/loaders/utils/getSections.js
+++ b/loaders/utils/getSections.js
@@ -68,8 +68,10 @@ function processSection(section, config, parentDepth) {
 		slug: slugger.slug(section.name),
 		sections: getSections(section.sections || [], config, sectionDepth),
 		filepath: contentRelativePath,
+		href: section.href,
 		components: getSectionComponents(section, config),
 		content,
+		external: section.external,
 	};
 }
 
diff --git a/package-lock.json b/package-lock.json
index 6936f223..516f7250 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8392,6 +8392,11 @@
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
       "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
     },
+    "kleur": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/kleur/-/kleur-2.0.1.tgz",
+      "integrity": "sha512-Zq/jyANIJ2uX8UZjWlqLwbyhcxSXJtT/Y89lClyeZd3l++3ztL1I5SSCYrbcbwSunTjC88N3WuMk0kRDQD6gzA=="
+    },
     "lazy-cache": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
@@ -8574,7 +8579,7 @@
         },
         "onetime": {
           "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+          "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
           "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
           "dev": true
         },
@@ -8734,7 +8739,7 @@
         },
         "onetime": {
           "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+          "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
           "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
           "dev": true
         },
@@ -8872,7 +8877,7 @@
         },
         "onetime": {
           "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+          "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
           "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
           "dev": true
         },
@@ -11250,13 +11255,11 @@
       }
     },
     "recast": {
-      "version": "0.12.9",
-      "resolved": "https://registry.npmjs.org/recast/-/recast-0.12.9.tgz",
-      "integrity": "sha512-y7ANxCWmMW8xLOaiopiRDlyjQ9ajKRENBH+2wjntIbk3A6ZR1+BLQttkmSHMY7Arl+AAZFwJ10grg2T6f1WI8A==",
-      "dev": true,
+      "version": "0.13.0",
+      "resolved": "https://registry.npmjs.org/recast/-/recast-0.13.0.tgz",
+      "integrity": "sha512-OwBhvGNxrL0aP5xhuVM0ms3UDYVG/uSfhfZjbPklRzoKiXukDbDmLqkfM6CtY/hkTTtAGizcMCp3XkqagctWOQ==",
       "requires": {
         "ast-types": "0.10.1",
-        "core-js": "^2.4.1",
         "esprima": "~4.0.0",
         "private": "~0.1.5",
         "source-map": "~0.6.1"
@@ -11265,20 +11268,17 @@
         "ast-types": {
           "version": "0.10.1",
           "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.10.1.tgz",
-          "integrity": "sha512-UY7+9DPzlJ9VM8eY0b2TUZcZvF+1pO0hzMtAyjBYKhOmnvRlqYNYnWdtsMj0V16CGaMlpL0G1jnLbLo4AyotuQ==",
-          "dev": true
+          "integrity": "sha512-UY7+9DPzlJ9VM8eY0b2TUZcZvF+1pO0hzMtAyjBYKhOmnvRlqYNYnWdtsMj0V16CGaMlpL0G1jnLbLo4AyotuQ=="
         },
         "esprima": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
-          "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
-          "dev": true
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+          "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
         },
         "source-map": {
           "version": "0.6.1",
           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-          "dev": true
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
         }
       }
     },
@@ -13169,9 +13169,9 @@
       }
     },
     "url-parse": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.1.tgz",
-      "integrity": "sha512-x95Td74QcvICAA0+qERaVkRpTGKyBHHYdwL2LXZm5t/gBtCB9KQSO/0zQgSTYEV1p0WcvSg79TLNPSvd5IDJMQ==",
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.3.tgz",
+      "integrity": "sha512-rh+KuAW36YKo0vClhQzLLveoj8FwPJNu65xLb7Mrt+eZht0IPT0IXgSv8gcMegZ6NvjJUALf6Mf25POlMwD1Fw==",
       "requires": {
         "querystringify": "^2.0.0",
         "requires-port": "^1.0.0"
@@ -13504,6 +13504,12 @@
           "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
           "dev": true
         },
+        "ast-types": {
+          "version": "0.10.1",
+          "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.10.1.tgz",
+          "integrity": "sha512-UY7+9DPzlJ9VM8eY0b2TUZcZvF+1pO0hzMtAyjBYKhOmnvRlqYNYnWdtsMj0V16CGaMlpL0G1jnLbLo4AyotuQ==",
+          "dev": true
+        },
         "async": {
           "version": "1.5.2",
           "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
@@ -13538,6 +13544,12 @@
             "strip-ansi": "~0.1.0"
           }
         },
+        "esprima": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+          "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+          "dev": true
+        },
         "expand-brackets": {
           "version": "0.1.5",
           "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
@@ -13592,6 +13604,21 @@
             "recast": "^0.12.5",
             "temp": "^0.8.1",
             "write-file-atomic": "^1.2.0"
+          },
+          "dependencies": {
+            "recast": {
+              "version": "0.12.9",
+              "resolved": "https://registry.npmjs.org/recast/-/recast-0.12.9.tgz",
+              "integrity": "sha512-y7ANxCWmMW8xLOaiopiRDlyjQ9ajKRENBH+2wjntIbk3A6ZR1+BLQttkmSHMY7Arl+AAZFwJ10grg2T6f1WI8A==",
+              "dev": true,
+              "requires": {
+                "ast-types": "0.10.1",
+                "core-js": "^2.4.1",
+                "esprima": "~4.0.0",
+                "private": "~0.1.5",
+                "source-map": "~0.6.1"
+              }
+            }
           }
         },
         "kind-of": {
@@ -13640,6 +13667,12 @@
             "underscore": "~1.6.0"
           }
         },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
         "strip-ansi": {
           "version": "0.1.1",
           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz",
diff --git a/package.json b/package.json
index cad868b4..bf636130 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,6 @@
     "acorn": "^5.7.1",
     "ast-types": "^0.11.5",
     "buble": "^0.19.3",
-    "chalk": "^2.4.1",
     "classnames": "^2.2.6",
     "clean-webpack-plugin": "^0.1.19",
     "clipboard-copy": "^2.0.0",
@@ -61,6 +60,7 @@
     "jss-global": "^3.0.0",
     "jss-isolate": "^5.1.0",
     "jss-nested": "^6.0.1",
+    "kleur": "^2.0.1",
     "leven": "^2.1.0",
     "listify": "^1.0.0",
     "loader-utils": "^1.1.0",
@@ -80,6 +80,7 @@
     "react-group": "^1.0.6",
     "react-icons": "^2.2.7",
     "react-lifecycles-compat": "^3.0.4",
+    "recast": "^0.13.0",
     "remark": "^9.0.0",
     "style-loader": "^0.21.0",
     "to-ast": "^1.0.0",
@@ -160,7 +161,7 @@
     "precommit": "lint-staged",
     "format": "prettier --write '**/*.{js,md}'",
     "postinstall": "node -e \"console.log('\\u001b[32mLove Styleguidist? Support us on the Open Collective:\\u001b[22m\\u001b[39m\\n > \\u001b[96m\\u001b[1mhttps://opencollective.com/styleguidist\\u001b[0m\\n')\" || exit 0",
-    "test:cypress:pre": "npm i --no-save cypress wait-on",
+    "test:cypress:pre": "npm i --no-save cypress@3.0.2 wait-on",
     "test:cypress:open": "cypress open",
     "test:cypress:run": "cypress run",
     "test:cypress:startServer": "node test/run.server.js",
diff --git a/scripts/logger.js b/scripts/logger.js
index ae52b7c8..f791854f 100644
--- a/scripts/logger.js
+++ b/scripts/logger.js
@@ -1,14 +1,14 @@
 /* eslint-disable no-console */
 
 const _ = require('lodash/fp');
-const chalk = require('chalk');
+const kleur = require('kleur');
 const logger = require('glogg')('rsg');
 
 const format = message => message.trim() + '\n';
 
 const printers = {
 	info: message => console.log(format(message)),
-	warn: message => console.warn(chalk.yellow(`Warning: ${format(message)}`)),
+	warn: message => console.warn(kleur.yellow(`Warning: ${format(message)}`)),
 	debug: message => console.log(format(message)),
 };
 
diff --git a/scripts/make-webpack-config.js b/scripts/make-webpack-config.js
index 0b789240..6f74631b 100644
--- a/scripts/make-webpack-config.js
+++ b/scripts/make-webpack-config.js
@@ -27,7 +27,7 @@ module.exports = function(config, env) {
 	const htmlPluginOptions = {
 		context: Object.assign({}, templateContext, {
 			title: config.title,
-			container: 'rsg-root',
+			container: config.mountPointId,
 			trimWhitespace: true,
 		}),
 		template,
diff --git a/scripts/schemas/config.js b/scripts/schemas/config.js
index 32977cf2..97440c43 100644
--- a/scripts/schemas/config.js
+++ b/scripts/schemas/config.js
@@ -6,7 +6,7 @@ const DEFAULT_COMPONENTS_PATTERN = `src/@(components|Components)/**/*.{${EXTENSI
 
 const path = require('path');
 const startCase = require('lodash/startCase');
-const chalk = require('chalk');
+const kleur = require('kleur');
 const reactDocgen = require('react-docgen');
 const createDisplayNameHandler = require('react-docgen-displayname-handler')
 	.createDisplayNameHandler;
@@ -134,6 +134,10 @@ module.exports = {
 	logger: {
 		type: 'object',
 	},
+	mountPointId: {
+		type: 'string',
+		default: 'rsg-root',
+	},
 	pagePerSection: {
 		type: 'boolean',
 		default: false,
@@ -253,7 +257,7 @@ module.exports = {
 		process: val => {
 			if (typeof val === 'string') {
 				throw new StyleguidistError(
-					`${chalk.bold(
+					`${kleur.bold(
 						'template'
 					)} config option format has been changed, you need to update your config.`,
 					'template'
diff --git a/scripts/utils/sanitizeConfig.js b/scripts/utils/sanitizeConfig.js
index 06873329..5627ab8b 100644
--- a/scripts/utils/sanitizeConfig.js
+++ b/scripts/utils/sanitizeConfig.js
@@ -9,7 +9,7 @@ const isString = require('lodash/isString');
 const isFinite = require('lodash/isFinite');
 const map = require('lodash/map');
 const listify = require('listify');
-const chalk = require('chalk');
+const kleur = require('kleur');
 const leven = require('leven');
 const stringify = require('q-i').stringify;
 const typeDetect = require('type-detect');
@@ -57,9 +57,9 @@ module.exports = function sanitizeConfig(config, schema, rootDir) {
 			}, null);
 
 			throw new StyleguidistError(
-				`Unknown config option ${chalk.bold(key)} was found, the value is:\n` +
+				`Unknown config option ${kleur.bold(key)} was found, the value is:\n` +
 					stringify(value) +
-					(suggestion ? `\n\nDid you mean ${chalk.bold(suggestion)}?` : '')
+					(suggestion ? `\n\nDid you mean ${kleur.bold(suggestion)}?` : '')
 			);
 		}
 	});
@@ -83,13 +83,13 @@ module.exports = function sanitizeConfig(config, schema, rootDir) {
 			if (isRequired) {
 				const message = isString(isRequired)
 					? isRequired
-					: `${chalk.bold(key)} config option is required.`;
+					: `${kleur.bold(key)} config option is required.`;
 				throw new StyleguidistError(message, key);
 			}
 		} else if (props.deprecated) {
 			logger.warn(`${key} config option is deprecated. ${props.deprecated}`);
 		} else if (props.removed) {
-			throw new StyleguidistError(`${chalk.bold(key)} config option was removed. ${props.removed}`);
+			throw new StyleguidistError(`${kleur.bold(key)} config option was removed. ${props.removed}`);
 		}
 
 		if (value !== undefined && props.type) {
@@ -98,7 +98,7 @@ module.exports = function sanitizeConfig(config, schema, rootDir) {
 			// Check type
 			const hasRightType = types.some(type => {
 				if (!typeCheckers[type]) {
-					throw Error(`Wrong type ${chalk.bold(type)} specified for ${chalk.bold(key)} in schema.`);
+					throw Error(`Wrong type ${kleur.bold(type)} specified for ${kleur.bold(key)} in schema.`);
 				}
 				return typeCheckers[type](value);
 			});
@@ -109,7 +109,7 @@ module.exports = function sanitizeConfig(config, schema, rootDir) {
 					example[key] = exampleValue;
 				}
 				throw new StyleguidistError(
-					`${chalk.bold(key)} config option should be ${typesList(types)}, received ${typeDetect(
+					`${kleur.bold(key)} config option should be ${typesList(types)}, received ${typeDetect(
 						value
 					)}.\n` +
 						(exampleValue
@@ -130,13 +130,13 @@ ${stringify(example)}`
 				if (shouldExist(types)) {
 					if (shouldBeFile(types) && !fs.existsSync(value)) {
 						throw new StyleguidistError(
-							`A file specified in ${chalk.bold(key)} config option does not exist:\n${value}`,
+							`A file specified in ${kleur.bold(key)} config option does not exist:\n${value}`,
 							key
 						);
 					}
 					if (shouldBeDirectory(types) && !isDirectory.sync(value)) {
 						throw new StyleguidistError(
-							`A directory specified in ${chalk.bold(key)} config option does not exist:\n${value}`,
+							`A directory specified in ${kleur.bold(key)} config option does not exist:\n${value}`,
 							key
 						);
 					}
diff --git a/src/index.js b/src/index.js
index d2692bc1..7bba0d21 100644
--- a/src/index.js
+++ b/src/index.js
@@ -5,8 +5,6 @@ import ReactDOM from 'react-dom';
 import renderStyleguide from './utils/renderStyleguide';
 import { getParameterByName, hasInHash } from './utils/handleHash';
 
-const CONTAINER_ID = 'rsg-root';
-
 // Examples code revision to rerender only code examples (not the whole page) when code changes
 // eslint-disable-next-line no-unused-vars
 let codeRevision = 0;
@@ -38,7 +36,7 @@ const render = () => {
 	const styleguide = require('!!../loaders/styleguide-loader!./index.js');
 	ReactDOM.render(
 		renderStyleguide(styleguide, codeRevision),
-		document.getElementById(CONTAINER_ID)
+		document.getElementById(styleguide.config.mountPointId)
 	);
 };
 
diff --git a/src/rsg-components/Argument/Argument.spec.js b/src/rsg-components/Argument/Argument.spec.js
index e369938c..3d79cd8a 100644
--- a/src/rsg-components/Argument/Argument.spec.js
+++ b/src/rsg-components/Argument/Argument.spec.js
@@ -22,6 +22,44 @@ it('should render argument without type', () => {
 	expect(actual).toMatchSnapshot();
 });
 
+it('should render optional argument', () => {
+	const actual = shallow(
+		<ArgumentRenderer
+			{...props}
+			type={{ type: 'OptionalType', expression: { name: 'Array' } }}
+			description={description}
+		/>
+	);
+
+	expect(actual).toMatchSnapshot();
+});
+
+it('should render default value of argument', () => {
+	const actual = shallow(
+		<ArgumentRenderer
+			{...props}
+			type={{ name: 'String' }}
+			default="bar"
+			description={description}
+		/>
+	);
+
+	expect(actual).toMatchSnapshot();
+});
+
+it('should render default value of optional argument', () => {
+	const actual = shallow(
+		<ArgumentRenderer
+			{...props}
+			type={{ type: 'OptionalType', expression: { name: 'Boolean' } }}
+			default="true"
+			description={description}
+		/>
+	);
+
+	expect(actual).toMatchSnapshot();
+});
+
 it('should render argument without description', () => {
 	const actual = shallow(<ArgumentRenderer {...props} name={name} type={type} />);
 
diff --git a/src/rsg-components/Argument/ArgumentRenderer.js b/src/rsg-components/Argument/ArgumentRenderer.js
index 3d0c701c..5a45c5c0 100644
--- a/src/rsg-components/Argument/ArgumentRenderer.js
+++ b/src/rsg-components/Argument/ArgumentRenderer.js
@@ -13,6 +13,11 @@ export const styles = ({ space }) => ({
 });
 
 export function ArgumentRenderer({ classes, name, type, description, returns, block, ...props }) {
+	const isOptional = type && type.type === 'OptionalType';
+	const defaultValue = props.default;
+	if (isOptional) {
+		type = type.expression;
+	}
 	return (
 		<Group className={block && classes.block} {...props}>
 			{returns && 'Returns'}
@@ -22,7 +27,13 @@ export function ArgumentRenderer({ classes, name, type, description, returns, bl
 					{type && ':'}
 				</span>
 			)}
-			{type && <Type>{type.name}</Type>}
+			{type && (
+				<Type>
+					{type.name}
+					{isOptional && '?'}
+					{!!defaultValue && `=${defaultValue}`}
+				</Type>
+			)}
 			{type && description && ` — `}
 			{description && <Markdown text={`${description}`} inline />}
 		</Group>
@@ -33,6 +44,7 @@ ArgumentRenderer.propTypes = {
 	classes: PropTypes.object.isRequired,
 	name: PropTypes.string,
 	type: PropTypes.object,
+	default: PropTypes.string,
 	description: PropTypes.string,
 	returns: PropTypes.bool,
 	block: PropTypes.bool,
diff --git a/src/rsg-components/Argument/__snapshots__/Argument.spec.js.snap b/src/rsg-components/Argument/__snapshots__/Argument.spec.js.snap
index b7340b41..a0f34189 100644
--- a/src/rsg-components/Argument/__snapshots__/Argument.spec.js.snap
+++ b/src/rsg-components/Argument/__snapshots__/Argument.spec.js.snap
@@ -53,6 +53,57 @@ exports[`should render argument without type 1`] = `
 </Group>
 `;
 
+exports[`should render default value of argument 1`] = `
+<Group
+  default="bar"
+  separator=" "
+>
+  <Styled(Type)>
+    String
+    =bar
+  </Styled(Type)>
+   — 
+  <Markdown
+    inline={true}
+    text="Converts foo to bar"
+  />
+</Group>
+`;
+
+exports[`should render default value of optional argument 1`] = `
+<Group
+  default="true"
+  separator=" "
+>
+  <Styled(Type)>
+    Boolean
+    ?
+    =true
+  </Styled(Type)>
+   — 
+  <Markdown
+    inline={true}
+    text="Converts foo to bar"
+  />
+</Group>
+`;
+
+exports[`should render optional argument 1`] = `
+<Group
+  separator=" "
+>
+  <Styled(Type)>
+    Array
+    ?
+  </Styled(Type)>
+   — 
+  <Markdown
+    inline={true}
+    text="Converts foo to bar"
+  />
+</Group>
+`;
+
 exports[`should render return value 1`] = `
 <Group
   separator=" "
diff --git a/src/rsg-components/ComponentsList/ComponentsList.js b/src/rsg-components/ComponentsList/ComponentsList.js
index 48984d80..b5a65c41 100644
--- a/src/rsg-components/ComponentsList/ComponentsList.js
+++ b/src/rsg-components/ComponentsList/ComponentsList.js
@@ -6,13 +6,15 @@ import getUrl from '../../utils/getUrl';
 function ComponentsList({ classes, items, useRouterLinks = false, useHashId, hashPath }) {
 	const mappedItems = items.map(item => ({
 		...item,
-		href: getUrl({
-			name: item.name,
-			slug: item.slug,
-			anchor: !useRouterLinks,
-			hashPath: useRouterLinks ? hashPath : false,
-			id: useRouterLinks ? useHashId : false,
-		}),
+		href: item.href
+			? item.href
+			: getUrl({
+					name: item.name,
+					slug: item.slug,
+					anchor: !useRouterLinks,
+					hashPath: useRouterLinks ? hashPath : false,
+					id: useRouterLinks ? useHashId : false,
+			  }),
 	}));
 	return <ComponentsListRenderer classes={classes} items={mappedItems} />;
 }
diff --git a/src/rsg-components/ComponentsList/ComponentsList.spec.js b/src/rsg-components/ComponentsList/ComponentsList.spec.js
index 9f626c44..f49f6dd4 100644
--- a/src/rsg-components/ComponentsList/ComponentsList.spec.js
+++ b/src/rsg-components/ComponentsList/ComponentsList.spec.js
@@ -5,10 +5,30 @@ import { ComponentsListRenderer } from './ComponentsListRenderer';
 it('should set the correct href for items', () => {
 	const components = [
 		{
+			visibleName: 'Button',
 			name: 'Button',
 			slug: 'button',
 		},
 		{
+			visibleName: 'Input',
+			name: 'Input',
+			slug: 'input',
+		},
+	];
+
+	const actual = shallow(<ComponentsList items={components} classes={{}} />);
+	expect(actual).toMatchSnapshot();
+});
+
+it('if a custom href is provided, should use it instead of generating internal link', () => {
+	const components = [
+		{
+			visibleName: 'External example',
+			name: 'External example',
+			href: 'http://example.com',
+		},
+		{
+			visibleName: 'Input',
 			name: 'Input',
 			slug: 'input',
 		},
@@ -21,10 +41,12 @@ it('should set the correct href for items', () => {
 it('should set a parameter on link when useHashId is activated', () => {
 	const components = [
 		{
+			visibleName: 'Button',
 			name: 'Button',
 			slug: 'button',
 		},
 		{
+			visibleName: 'Input',
 			name: 'Input',
 			slug: 'input',
 		},
@@ -69,12 +91,12 @@ it('should set a sub route on link when useHashId is deactivated', () => {
 it('should render sections with nested components', () => {
 	const components = [
 		{
-			name: 'Button',
+			visibleName: 'Button',
 			slug: 'button',
 			href: '#button',
 		},
 		{
-			name: 'Input',
+			visibleName: 'Input',
 			slug: 'input',
 			href: '#input',
 		},
@@ -90,10 +112,10 @@ it('should return null when the list is empty', () => {
 	expect(actual.getElement()).toBe(null);
 });
 
-it('should ignore items without name', () => {
+it('should ignore items without visibleName', () => {
 	const components = [
 		{
-			name: 'Button',
+			visibleName: 'Button',
 			slug: 'button',
 			href: '#button',
 		},
diff --git a/src/rsg-components/ComponentsList/ComponentsListRenderer.js b/src/rsg-components/ComponentsList/ComponentsListRenderer.js
index e98bb591..3e29cc5d 100644
--- a/src/rsg-components/ComponentsList/ComponentsListRenderer.js
+++ b/src/rsg-components/ComponentsList/ComponentsListRenderer.js
@@ -34,7 +34,7 @@ const styles = ({ color, fontFamily, fontSize, space, mq }) => ({
 });
 
 export function ComponentsListRenderer({ classes, items }) {
-	items = items.filter(item => item.name);
+	items = items.filter(item => item.visibleName);
 
 	if (!items.length) {
 		return null;
@@ -42,13 +42,17 @@ export function ComponentsListRenderer({ classes, items }) {
 
 	return (
 		<ul className={classes.list}>
-			{items.map(({ heading, name, href, content }) => (
+			{items.map(({ heading, visibleName, href, content, external }) => (
 				<li
 					className={cx(classes.item, (!content || !content.props.items.length) && classes.isChild)}
 					key={href}
 				>
-					<Link className={cx(heading && classes.heading)} href={href}>
-						{name}
+					<Link
+						className={cx(heading && classes.heading)}
+						href={href}
+						target={external ? '_blank' : undefined}
+					>
+						{visibleName}
 					</Link>
 					{content}
 				</li>
diff --git a/src/rsg-components/ComponentsList/__snapshots__/ComponentsList.spec.js.snap b/src/rsg-components/ComponentsList/__snapshots__/ComponentsList.spec.js.snap
index 6f9b8ac9..5d7b273a 100644
--- a/src/rsg-components/ComponentsList/__snapshots__/ComponentsList.spec.js.snap
+++ b/src/rsg-components/ComponentsList/__snapshots__/ComponentsList.spec.js.snap
@@ -1,6 +1,27 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`should ignore items without name 1`] = `
+exports[`if a custom href is provided, should use it instead of generating internal link 1`] = `
+<Styled(ComponentsList)
+  classes={Object {}}
+  items={
+    Array [
+      Object {
+        "href": "http://example.com",
+        "name": "External example",
+        "visibleName": "External example",
+      },
+      Object {
+        "href": "blank#input",
+        "name": "Input",
+        "slug": "input",
+        "visibleName": "Input",
+      },
+    ]
+  }
+/>
+`;
+
+exports[`should ignore items without visibleName 1`] = `
 <ul>
   <li
     className=""
@@ -52,11 +73,13 @@ exports[`should set a parameter on link when useHashId is activated 1`] = `
         "href": "blank#/Components?id=button",
         "name": "Button",
         "slug": "button",
+        "visibleName": "Button",
       },
       Object {
         "href": "blank#/Components?id=input",
         "name": "Input",
         "slug": "input",
+        "visibleName": "Input",
       },
     ]
   }
@@ -92,11 +115,13 @@ exports[`should set the correct href for items 1`] = `
         "href": "blank#button",
         "name": "Button",
         "slug": "button",
+        "visibleName": "Button",
       },
       Object {
         "href": "blank#input",
         "name": "Input",
         "slug": "input",
+        "visibleName": "Input",
       },
     ]
   }
diff --git a/src/rsg-components/Error/ErrorRenderer.js b/src/rsg-components/Error/ErrorRenderer.js
index ae4a50e3..610f9408 100644
--- a/src/rsg-components/Error/ErrorRenderer.js
+++ b/src/rsg-components/Error/ErrorRenderer.js
@@ -10,7 +10,7 @@ const styles = ({ fontFamily, fontSize, color, space }) => ({
 	},
 	stack: {
 		color: color.error,
-		whiteSpace: 'pre',
+		whiteSpace: 'pre-wrap',
 		fontFamily: fontFamily.monospace,
 	},
 	message: {
diff --git a/src/rsg-components/Link/Link.spec.js b/src/rsg-components/Link/Link.spec.js
index 7917cd9c..7f7a5c6d 100644
--- a/src/rsg-components/Link/Link.spec.js
+++ b/src/rsg-components/Link/Link.spec.js
@@ -23,3 +23,13 @@ it('should compose passed class names', () => {
 
 	expect(actual.find('a').prop('className')).toBe('baseLinkClass customClass');
 });
+
+it('should properly pass the target attribute', () => {
+	const actual = shallow(
+		<LinkRenderer href={href} target="_blank" classes={{}}>
+			{children}
+		</LinkRenderer>
+	);
+
+	expect(actual.find('a').prop('target')).toBe('_blank');
+});
diff --git a/src/rsg-components/Markdown/Details/Details.spec.js b/src/rsg-components/Markdown/Details/Details.spec.js
new file mode 100644
index 00000000..e0ab5ce8
--- /dev/null
+++ b/src/rsg-components/Markdown/Details/Details.spec.js
@@ -0,0 +1,15 @@
+import React from 'react';
+
+import { Details, DetailsSummary } from './index';
+
+describe('Markdown Details', () => {
+	it('should render a Details', () => {
+		const actual = render(
+			<Details>
+				<DetailsSummary>Solution</DetailsSummary>This is a hidden text.
+			</Details>
+		);
+
+		expect(actual).toMatchSnapshot();
+	});
+});
diff --git a/src/rsg-components/Markdown/Details/DetailsRenderer.js b/src/rsg-components/Markdown/Details/DetailsRenderer.js
new file mode 100644
index 00000000..dc9d4240
--- /dev/null
+++ b/src/rsg-components/Markdown/Details/DetailsRenderer.js
@@ -0,0 +1,23 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import Styled from 'rsg-components/Styled';
+
+const styles = ({ space, color, fontSize, fontFamily }) => ({
+	details: {
+		marginBottom: space[2],
+		fontFamily: fontFamily.base,
+		fontSize: fontSize.base,
+		color: color.base,
+	},
+});
+
+export function DetailsRenderer({ classes, children }) {
+	return <details className={classes.details}>{children}</details>;
+}
+
+DetailsRenderer.propTypes = {
+	classes: PropTypes.object.isRequired,
+	children: PropTypes.node.isRequired,
+};
+
+export default Styled(styles)(DetailsRenderer);
diff --git a/src/rsg-components/Markdown/Details/DetailsSummaryRenderer.js b/src/rsg-components/Markdown/Details/DetailsSummaryRenderer.js
new file mode 100644
index 00000000..417ba027
--- /dev/null
+++ b/src/rsg-components/Markdown/Details/DetailsSummaryRenderer.js
@@ -0,0 +1,29 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import Styled from 'rsg-components/Styled';
+
+const styles = ({ space, color, fontSize, fontFamily }) => ({
+	summary: {
+		marginBottom: space[1],
+		fontFamily: fontFamily.base,
+		fontSize: fontSize.base,
+		color: color.base,
+		cursor: 'pointer',
+		'&:focus': {
+			isolate: false,
+			outline: [[1, 'dotted', color.linkHover]],
+			outlineOffset: 2,
+		},
+	},
+});
+
+export function DetailsSummaryRenderer({ classes, children }) {
+	return <summary className={classes.summary}>{children}</summary>;
+}
+
+DetailsSummaryRenderer.propTypes = {
+	classes: PropTypes.object.isRequired,
+	children: PropTypes.node.isRequired,
+};
+
+export default Styled(styles)(DetailsSummaryRenderer);
diff --git a/src/rsg-components/Markdown/Details/__snapshots__/Details.spec.js.snap b/src/rsg-components/Markdown/Details/__snapshots__/Details.spec.js.snap
new file mode 100644
index 00000000..680ad27d
--- /dev/null
+++ b/src/rsg-components/Markdown/Details/__snapshots__/Details.spec.js.snap
@@ -0,0 +1,14 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Markdown Details should render a Details 1`] = `
+<details
+  class="rsg--details-0"
+>
+  <summary
+    class="rsg--summary-2"
+  >
+    Solution
+  </summary>
+  This is a hidden text.
+</details>
+`;
diff --git a/src/rsg-components/Markdown/Details/index.js b/src/rsg-components/Markdown/Details/index.js
new file mode 100644
index 00000000..18d1c4bb
--- /dev/null
+++ b/src/rsg-components/Markdown/Details/index.js
@@ -0,0 +1,2 @@
+export { default as Details } from 'rsg-components/Markdown/Details/DetailsRenderer';
+export { default as DetailsSummary } from 'rsg-components/Markdown/Details/DetailsSummaryRenderer';
diff --git a/src/rsg-components/Markdown/Markdown.js b/src/rsg-components/Markdown/Markdown.js
index 7ef80626..ffd2997f 100644
--- a/src/rsg-components/Markdown/Markdown.js
+++ b/src/rsg-components/Markdown/Markdown.js
@@ -10,6 +10,7 @@ import Pre from 'rsg-components/Markdown/Pre';
 import Code from 'rsg-components/Code';
 import Checkbox from 'rsg-components/Markdown/Checkbox';
 import Hr from 'rsg-components/Markdown/Hr';
+import { Details, DetailsSummary } from 'rsg-components/Markdown/Details';
 import { Table, TableHead, TableBody, TableRow, TableCell } from 'rsg-components/Markdown/Table';
 
 // We’re explicitly specifying Webpack loaders here so we could skip specifying them in Webpack configuration.
@@ -120,6 +121,12 @@ export const baseOverrides = {
 	td: {
 		component: TableCell,
 	},
+	details: {
+		component: Details,
+	},
+	summary: {
+		component: DetailsSummary,
+	},
 };
 
 export const inlineOverrides = {
diff --git a/src/rsg-components/Playground/Playground.js b/src/rsg-components/Playground/Playground.js
index ef6082cb..c31b3d72 100644
--- a/src/rsg-components/Playground/Playground.js
+++ b/src/rsg-components/Playground/Playground.js
@@ -96,7 +96,8 @@ class Playground extends Component {
 						name="exampleTabs"
 						active={activeTab}
 						onlyActive
-						props={{ code, onChange: this.handleChange }}
+						// evalInContext passed through to support custom slots that eval code
+						props={{ code, onChange: this.handleChange, evalInContext }}
 					/>
 				}
 				toolbar={
diff --git a/src/rsg-components/Playground/__snapshots__/Playground.spec.js.snap b/src/rsg-components/Playground/__snapshots__/Playground.spec.js.snap
index bb3a02db..038868b5 100644
--- a/src/rsg-components/Playground/__snapshots__/Playground.spec.js.snap
+++ b/src/rsg-components/Playground/__snapshots__/Playground.spec.js.snap
@@ -64,6 +64,7 @@ exports[`should render component renderer 1`] = `
   OK
 </button>
 ,
+          "evalInContext": [Function],
           "onChange": [Function],
         }
       }
diff --git a/src/rsg-components/PlaygroundError/PlaygroundErrorRenderer.js b/src/rsg-components/PlaygroundError/PlaygroundErrorRenderer.js
index 0a8e8714..2f8a6083 100644
--- a/src/rsg-components/PlaygroundError/PlaygroundErrorRenderer.js
+++ b/src/rsg-components/PlaygroundError/PlaygroundErrorRenderer.js
@@ -9,7 +9,7 @@ const styles = ({ fontFamily, fontSize, color }) => ({
 		fontSize: fontSize.small,
 		fontFamily: fontFamily.monospace,
 		color: color.error,
-		whiteSpace: 'pre',
+		whiteSpace: 'pre-wrap',
 	},
 });
 
diff --git a/src/rsg-components/Props/util.js b/src/rsg-components/Props/util.js
index 0f78eff2..0ad27826 100644
--- a/src/rsg-components/Props/util.js
+++ b/src/rsg-components/Props/util.js
@@ -5,7 +5,7 @@
  * @returns {string}
  */
 export function unquote(string) {
-	return string.replace(/^['"]|['"]$/g, '');
+	return string && string.replace(/^['"]|['"]$/g, '');
 }
 
 /**
@@ -38,5 +38,5 @@ export function getType(prop) {
  * @returns {string}
  */
 export function showSpaces(string) {
-	return string.replace(/^\s|\s$/g, '␣');
+	return string && string.replace(/^\s|\s$/g, '␣');
 }
diff --git a/src/rsg-components/ReactComponent/ReactComponent.js b/src/rsg-components/ReactComponent/ReactComponent.js
index 668e76b2..664dbf08 100644
--- a/src/rsg-components/ReactComponent/ReactComponent.js
+++ b/src/rsg-components/ReactComponent/ReactComponent.js
@@ -50,7 +50,7 @@ export default class ReactComponent extends Component {
 			config: { pagePerSection },
 		} = this.context;
 		const { component, depth, usageMode, exampleMode } = this.props;
-		const { name, slug, filepath, pathLine } = component;
+		const { name, visibleName, slug, filepath, pathLine } = component;
 		const { description, examples = [], tags = {} } = component.props;
 		if (!name) {
 			return null;
@@ -77,7 +77,7 @@ export default class ReactComponent extends Component {
 						}}
 						depth={depth}
 					>
-						{name}
+						{visibleName}
 					</SectionHeading>
 				}
 				examples={
diff --git a/src/rsg-components/ReactComponent/ReactComponent.spec.js b/src/rsg-components/ReactComponent/ReactComponent.spec.js
index 806ef471..2963f622 100644
--- a/src/rsg-components/ReactComponent/ReactComponent.spec.js
+++ b/src/rsg-components/ReactComponent/ReactComponent.spec.js
@@ -21,6 +21,7 @@ const options = {
 
 const component = {
 	name: 'Foo',
+	visibleName: 'Foo',
 	slug: 'foo',
 	pathLine: 'foo/bar.js',
 	props: {
@@ -32,6 +33,7 @@ const component = {
 };
 const componentWithEverything = {
 	name: 'Foo',
+	visibleName: 'Foo',
 	slug: 'foo',
 	pathLine: 'foo/bar.js',
 	props: {
diff --git a/src/rsg-components/ReactComponent/__snapshots__/ReactComponent.spec.js.snap b/src/rsg-components/ReactComponent/__snapshots__/ReactComponent.spec.js.snap
index 353d9598..e02ced20 100644
--- a/src/rsg-components/ReactComponent/__snapshots__/ReactComponent.spec.js.snap
+++ b/src/rsg-components/ReactComponent/__snapshots__/ReactComponent.spec.js.snap
@@ -84,6 +84,7 @@ exports[`ReactComponent should pass rendered description, usage, examples, etc.
             ],
           },
           "slug": "foo",
+          "visibleName": "Foo",
         }
       }
     >
@@ -142,6 +143,7 @@ exports[`ReactComponent should pass rendered description, usage, examples, etc.
             ],
           },
           "slug": "foo",
+          "visibleName": "Foo",
         }
       }
     />
@@ -195,6 +197,7 @@ exports[`ReactComponent should pass rendered description, usage, examples, etc.
             ],
           },
           "slug": "foo",
+          "visibleName": "Foo",
         }
       }
     />
diff --git a/src/rsg-components/Sections/Sections.js b/src/rsg-components/Sections/Sections.js
index aa2840a8..7c761c57 100644
--- a/src/rsg-components/Sections/Sections.js
+++ b/src/rsg-components/Sections/Sections.js
@@ -6,7 +6,9 @@ import SectionsRenderer from 'rsg-components/Sections/SectionsRenderer';
 export default function Sections({ sections, depth }) {
 	return (
 		<SectionsRenderer>
-			{sections.map((section, idx) => <Section key={idx} section={section} depth={depth} />)}
+			{sections
+				.filter(section => !section.href)
+				.map((section, idx) => <Section key={idx} section={section} depth={depth} />)}
 		</SectionsRenderer>
 	);
 }
diff --git a/src/rsg-components/StyleGuide/StyleGuideRenderer.js b/src/rsg-components/StyleGuide/StyleGuideRenderer.js
index a2828c9a..72de9c1c 100644
--- a/src/rsg-components/StyleGuide/StyleGuideRenderer.js
+++ b/src/rsg-components/StyleGuide/StyleGuideRenderer.js
@@ -9,6 +9,7 @@ import Version from 'rsg-components/Version';
 
 const styles = ({ color, fontFamily, fontSize, sidebarWidth, mq, space, maxWidth }) => ({
 	root: {
+		minHeight: '100vh',
 		backgroundColor: color.baseBackground,
 	},
 	hasSidebar: {
diff --git a/src/rsg-components/slots/index.js b/src/rsg-components/slots/index.js
index 66f6046c..c58f258c 100644
--- a/src/rsg-components/slots/index.js
+++ b/src/rsg-components/slots/index.js
@@ -1,8 +1,8 @@
 import Editor from 'rsg-components/Editor';
 import Usage from 'rsg-components/Usage';
-import IsolateButton from './IsolateButton';
-import CodeTabButton from './CodeTabButton';
-import UsageTabButton from './UsageTabButton';
+import IsolateButton from 'rsg-components/slots/IsolateButton';
+import CodeTabButton from 'rsg-components/slots/CodeTabButton';
+import UsageTabButton from 'rsg-components/slots/UsageTabButton';
 
 export const EXAMPLE_TAB_CODE_EDITOR = 'rsg-code-editor';
 export const DOCS_TAB_USAGE = 'rsg-usage';
diff --git a/src/styles/styles.js b/src/styles/styles.js
index 3278c80d..be85f724 100644
--- a/src/styles/styles.js
+++ b/src/styles/styles.js
@@ -6,6 +6,8 @@ const styles = {
 		isolate: false,
 		margin: 0,
 		padding: 0,
+		minWidth: 0,
+		maxWidth: '100%',
 		border: 0,
 	},
 };
diff --git a/src/utils/getRouteData.js b/src/utils/getRouteData.js
index 06debc5f..abf46283 100644
--- a/src/utils/getRouteData.js
+++ b/src/utils/getRouteData.js
@@ -49,7 +49,7 @@ export default function getRouteData(sections, hash, pagePerSection) {
 			hashArray.forEach((hashName, index) => {
 				// Filter the requested component if required but only on the first depth
 				// so in the next time of iteration, it will be trying to filter only on the second depth and so on
-				filteredSections = filterComponentsInSectionsByExactName(sections, hashName, false);
+				filteredSections = filterComponentsInSectionsByExactName(sections, hashName, isolate);
 
 				// If filteredSections exists, its because is an array of an component
 				// else it is an array of sections and depending his sectionDepth
diff --git a/src/utils/processComponents.js b/src/utils/processComponents.js
index 1c302fab..7c211499 100644
--- a/src/utils/processComponents.js
+++ b/src/utils/processComponents.js
@@ -12,6 +12,7 @@ export default function processComponents(components) {
 
 			// Add .name shortcuts for names instead of .props.displayName.
 			name: component.props.displayName,
+			visibleName: component.props.visibleName || component.props.displayName,
 
 			props: {
 				...component.props,
diff --git a/src/utils/processSections.js b/src/utils/processSections.js
index 321bfe91..7ebda654 100644
--- a/src/utils/processSections.js
+++ b/src/utils/processSections.js
@@ -9,6 +9,7 @@ import processComponents from './processComponents';
 export default function processSections(sections) {
 	return sections.map(section => ({
 		...section,
+		visibleName: section.name,
 		components: processComponents(section.components || []),
 		sections: processSections(section.sections || []),
 	}));


Test patch:
diff --git a/loaders/utils/__tests__/__snapshots__/getProps.spec.js.snap b/loaders/utils/__tests__/__snapshots__/getProps.spec.js.snap
index 78b7653e..ba516cec 100644
--- a/loaders/utils/__tests__/__snapshots__/getProps.spec.js.snap
+++ b/loaders/utils/__tests__/__snapshots__/getProps.spec.js.snap
@@ -1,5 +1,131 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`should accept @return as a synonym of @returns 1`] = `
+Array [
+  Object {
+    "docblock": "
+Baz method with foo param
+
+@public
+@return {string} test
+",
+    "returns": Object {
+      "description": "test",
+      "title": "return",
+      "type": Object {
+        "name": "string",
+        "type": "NameExpression",
+      },
+    },
+    "tags": Object {
+      "public": Array [
+        Object {
+          "description": null,
+          "title": "public",
+          "type": null,
+        },
+      ],
+    },
+  },
+]
+`;
+
+exports[`should get method info from docblock and merge it 1`] = `
+Array [
+  Object {
+    "docblock": "
+Baz method with foo param
+
+@public
+@returns {string} test
+",
+    "returns": Object {
+      "description": "test",
+      "title": "returns",
+      "type": Object {
+        "name": "string",
+        "type": "NameExpression",
+      },
+    },
+    "tags": Object {
+      "public": Array [
+        Object {
+          "description": null,
+          "title": "public",
+          "type": null,
+        },
+      ],
+    },
+  },
+]
+`;
+
+exports[`should get method params info from docblock and merge it with passed method info 1`] = `
+Array [
+  Object {
+    "docblock": "
+Foo method with baz param
+
+@public
+@param {string} [baz=bar]
+@arg {string} foo param described with @arg tag
+@argument {string} test param described with @argument tag
+@returns {string} test
+",
+    "params": Array [
+      Object {
+        "default": "bar",
+        "description": null,
+        "name": "baz",
+        "title": "param",
+        "type": Object {
+          "expression": Object {
+            "name": "string",
+            "type": "NameExpression",
+          },
+          "type": "OptionalType",
+        },
+      },
+      Object {
+        "description": "param described with @arg tag",
+        "name": "foo",
+        "title": "arg",
+        "type": Object {
+          "name": "string",
+          "type": "NameExpression",
+        },
+      },
+      Object {
+        "description": "param described with @argument tag",
+        "name": "test",
+        "title": "argument",
+        "type": Object {
+          "name": "string",
+          "type": "NameExpression",
+        },
+      },
+    ],
+    "returns": Object {
+      "description": "test",
+      "title": "returns",
+      "type": Object {
+        "name": "string",
+        "type": "NameExpression",
+      },
+    },
+    "tags": Object {
+      "public": Array [
+        Object {
+          "description": null,
+          "title": "public",
+          "type": null,
+        },
+      ],
+    },
+  },
+]
+`;
+
 exports[`should highlight code in description (fenced code block) 1`] = `
 Object {
   "description": "The only true button.
diff --git a/loaders/utils/__tests__/__snapshots__/getSections.spec.js.snap b/loaders/utils/__tests__/__snapshots__/getSections.spec.js.snap
index 0b27d102..e06be44c 100644
--- a/loaders/utils/__tests__/__snapshots__/getSections.spec.js.snap
+++ b/loaders/utils/__tests__/__snapshots__/getSections.spec.js.snap
@@ -9,7 +9,9 @@ Array [
     },
     "description": undefined,
     "exampleMode": "collapse",
+    "external": undefined,
     "filepath": "components/Button/Readme.md",
+    "href": undefined,
     "name": "Readme",
     "sectionDepth": 0,
     "sections": Array [],
@@ -89,7 +91,9 @@ Array [
     "content": undefined,
     "description": undefined,
     "exampleMode": "collapse",
+    "external": undefined,
     "filepath": undefined,
+    "href": undefined,
     "name": "Components",
     "sectionDepth": 0,
     "sections": Array [],
@@ -156,7 +160,9 @@ Array [
     "content": undefined,
     "description": undefined,
     "exampleMode": "collapse",
+    "external": undefined,
     "filepath": undefined,
+    "href": undefined,
     "name": "Ignore",
     "sectionDepth": 0,
     "sections": Array [],
@@ -240,7 +246,9 @@ Object {
   "content": undefined,
   "description": undefined,
   "exampleMode": "collapse",
+  "external": undefined,
   "filepath": undefined,
+  "href": undefined,
   "name": "Components",
   "sectionDepth": 0,
   "sections": Array [],
@@ -257,7 +265,9 @@ Object {
   },
   "description": undefined,
   "exampleMode": "collapse",
+  "external": undefined,
   "filepath": "components/Button/Readme.md",
+  "href": undefined,
   "name": "Readme",
   "sectionDepth": 0,
   "sections": Array [],
@@ -327,7 +337,9 @@ Object {
   "content": undefined,
   "description": undefined,
   "exampleMode": "collapse",
+  "external": undefined,
   "filepath": undefined,
+  "href": undefined,
   "name": "Ignore",
   "sectionDepth": 0,
   "sections": Array [],
diff --git a/loaders/utils/__tests__/getProps.spec.js b/loaders/utils/__tests__/getProps.spec.js
index 30aa8639..3a74da83 100644
--- a/loaders/utils/__tests__/getProps.spec.js
+++ b/loaders/utils/__tests__/getProps.spec.js
@@ -62,6 +62,83 @@ it('should remove non-public methods', () => {
 	expect(result).toMatchSnapshot();
 });
 
+it('should get method info from docblock and merge it', () => {
+	const result = getProps(
+		{
+			displayName: 'Button',
+			methods: [
+				{
+					docblock: `
+Baz method with foo param
+
+@public
+@returns {string} test
+`,
+				},
+			],
+		},
+		__filename
+	);
+
+	expect(result.methods).toMatchSnapshot();
+});
+
+it('should accept @return as a synonym of @returns', () => {
+	const result = getProps(
+		{
+			displayName: 'Button',
+			methods: [
+				{
+					docblock: `
+Baz method with foo param
+
+@public
+@return {string} test
+`,
+				},
+			],
+		},
+		__filename
+	);
+
+	expect(result.methods).toMatchSnapshot();
+});
+
+it('should get method params info from docblock and merge it with passed method info', () => {
+	const result = getProps(
+		{
+			displayName: 'Button',
+			methods: [
+				{
+					docblock: `
+Foo method with baz param
+
+@public
+@param {string} [baz=bar]
+@arg {string} foo param described with @arg tag
+@argument {string} test param described with @argument tag
+@returns {string} test
+`,
+					params: [
+						{
+							name: 'baz',
+						},
+						{
+							name: 'foo',
+						},
+						{
+							name: 'test',
+						},
+					],
+				},
+			],
+		},
+		__filename
+	);
+
+	expect(result.methods).toMatchSnapshot();
+});
+
 it('should return an object for props with doclets', () => {
 	const result = getProps(
 		{
@@ -161,3 +238,20 @@ it('should guess a displayName for components that react-docgen was not able to
 	);
 	expect(result).toHaveProperty('displayName', 'YourComponent');
 });
+
+describe('with @visibleName tag present in the description', () => {
+	const result = getProps({
+		description: 'bar\n@visibleName foo',
+	});
+	it('should set visibleName property on the docs object', () => {
+		expect(result).toHaveProperty('visibleName', 'foo');
+	});
+
+	it('should delete visibleName from doclets on the docs object', () => {
+		expect(result.doclets).not.toHaveProperty('visibleName');
+	});
+
+	it('should delete visibleName from tags on the docs object', () => {
+		expect(result.tags).not.toHaveProperty('visibleName');
+	});
+});
diff --git a/scripts/__tests__/config.spec.js b/scripts/__tests__/config.spec.js
index 02713352..68022518 100644
--- a/scripts/__tests__/config.spec.js
+++ b/scripts/__tests__/config.spec.js
@@ -228,3 +228,8 @@ it('should throw when old template as a string option passed', () => {
 		});
 	expect(fn).toThrow('format has been changed');
 });
+
+it('mountPointId should have default value', () => {
+	const result = getConfig();
+	expect(result.mountPointId).toEqual('rsg-root');
+});
diff --git a/scripts/__tests__/make-webpack-config.spec.js b/scripts/__tests__/make-webpack-config.spec.js
index c9dcc94b..1c167e05 100644
--- a/scripts/__tests__/make-webpack-config.spec.js
+++ b/scripts/__tests__/make-webpack-config.spec.js
@@ -192,3 +192,16 @@ it('should not overwrite NODE_ENV', () => {
 	makeWebpackConfig(styleguideConfig, 'production');
 	expect(process.env.NODE_ENV).toBe(process$env$nodeEnv);
 });
+
+it('should pass specified mountPointId to HTML plugin', () => {
+	const result = makeWebpackConfig(
+		{
+			...styleguideConfig,
+			mountPointId: 'foo-bar',
+		},
+		'development'
+	);
+	expect(getClasses(result.plugins, 'MiniHtmlWebpackPlugin')[0].options.context.container).toEqual(
+		'foo-bar'
+	);
+});
diff --git a/src/utils/__tests__/__snapshots__/renderStyleguide.spec.js.snap b/src/utils/__tests__/__snapshots__/renderStyleguide.spec.js.snap
index 28c832be..38ff8613 100644
--- a/src/utils/__tests__/__snapshots__/renderStyleguide.spec.js.snap
+++ b/src/utils/__tests__/__snapshots__/renderStyleguide.spec.js.snap
@@ -17,6 +17,7 @@ exports[`renderStyleguide should render StyleGuide component 1`] = `
                   "displayName": "Button",
                   "examples": Array [],
                 },
+                "visibleName": "Button",
               },
               Object {
                 "module": "ImageModule",
@@ -25,9 +26,11 @@ exports[`renderStyleguide should render StyleGuide component 1`] = `
                   "displayName": "Image",
                   "examples": Array [],
                 },
+                "visibleName": "Image",
               },
             ],
             "sections": Array [],
+            "visibleName": undefined,
           },
         ]
       }
@@ -48,6 +51,7 @@ exports[`renderStyleguide should render StyleGuide component 1`] = `
                 "displayName": "Button",
                 "examples": Array [],
               },
+              "visibleName": "Button",
             },
             Object {
               "module": "ImageModule",
@@ -56,9 +60,11 @@ exports[`renderStyleguide should render StyleGuide component 1`] = `
                 "displayName": "Image",
                 "examples": Array [],
               },
+              "visibleName": "Image",
             },
           ],
           "sections": Array [],
+          "visibleName": undefined,
         },
       ]
     }
diff --git a/src/utils/__tests__/processComponents.spec.js b/src/utils/__tests__/processComponents.spec.js
index 90792dbb..1b291362 100644
--- a/src/utils/__tests__/processComponents.spec.js
+++ b/src/utils/__tests__/processComponents.spec.js
@@ -15,6 +15,35 @@ describe('processComponents', () => {
 		expect(result[0].name).toBe('Foo');
 	});
 
+	describe('should set visibleName property on the component', () => {
+		it('from an visibleName component prop if available', () => {
+			const components = deepfreeze([
+				{
+					props: {
+						displayName: 'Foo',
+						visibleName: 'Foo Bar',
+					},
+					module: 13,
+				},
+			]);
+			const result = processComponents(components);
+			expect(result[0].visibleName).toBe('Foo Bar');
+		});
+
+		it('from an displayName component prop if visibleName prop is not available', () => {
+			const components = deepfreeze([
+				{
+					props: {
+						displayName: 'Foo',
+					},
+					module: 13,
+				},
+			]);
+			const result = processComponents(components);
+			expect(result[0].visibleName).toBe('Foo');
+		});
+	});
+
 	it('should append @example doclet to all examples', () => {
 		const components = deepfreeze([
 			{
diff --git a/src/utils/__tests__/processSections.spec.js b/src/utils/__tests__/processSections.spec.js
index 459b2a9b..f9ccf68e 100644
--- a/src/utils/__tests__/processSections.spec.js
+++ b/src/utils/__tests__/processSections.spec.js
@@ -5,6 +5,7 @@ const sections = deepfreeze([
 	{
 		sections: [
 			{
+				name: 'Components',
 				components: [
 					{
 						props: {
@@ -23,4 +24,9 @@ describe('processSections', () => {
 		const result = processSections(sections);
 		expect(result[0].sections[0].components[0].name).toBe('Button');
 	});
+
+	it('should set visibleName property on each section', () => {
+		const result = processSections(sections);
+		expect(result[0].sections[0].visibleName).toBe('Components');
+	});
 });
diff --git a/test/cypress/integration/core_spec.js b/test/cypress/integration/core_spec.js
index 4a1d8f0e..bafef2c4 100644
--- a/test/cypress/integration/core_spec.js
+++ b/test/cypress/integration/core_spec.js
@@ -10,7 +10,7 @@ describe('Styleguidist core', () => {
 	});
 
 	it('shows single component in isolated mode', () => {
-		cy.get('[title="Open isolated"]')
+		cy.get('a[aria-label="Open isolated"]')
 			.first()
 			.click();
 		cy.get('[id$=container]').should('have.length', 1);