loading...

Live code editing in docusaurus - UX at its best

mrmuhammadali profile image Muhammad Ali ・3 min read

Docusaurus is a tool designed to make it easy for teams to publish documentation websites without having to worry about the infrastructure and design details.

Docusaurus 2 is bringing a lot of new features with it but my most favorite one is live code editing. It lets you preview your changes at run-time without switching your context which gives you a really good user experience.

Installation

There is an official plugin to enable live code editing in your website, i.e. @docusaurus/theme-live-codeblock. This theme provides a @theme/CodeBlock component that is powered by react-live.
First, install the plugin in your website.

yarn add @docusaurus/theme-live-codeblock

You will also need to add the plugin to your docusaurus.config.js.

module.exports = {
  // ...
  themes: ['@docusaurus/theme-live-codeblock'],
  // ...
};

Usage

To use the plugin, create a code block with live attached to the language meta string.

```jsx live
function Clock(props) {
  const [date, setDate] = useState(new Date());
  useEffect(() => {
    var timerID = setInterval(() => tick(), 1000);

    return function cleanup() {
      clearInterval(timerID);
    };
  });

  function tick() {
    setDate(new Date());
  }

  return (
    <div>
      <h2>It is {date.toLocaleTimeString()}.</h2>
    </div>
  );
}
```

The code block will be rendered as an interactive editor. Changes to the code will reflect on the result panel live.

Third-party Components

By default React is in scope of live code blocks in MDX files but in order to render third-party components we need to add those components in the scope by swizzling the default theme, i.e. @docusaurus/theme-classic.
To swizzle a component for a theme, run the following command in your doc site:

docusaurus swizzle <theme name> [component name]

In our case, theme name is @docusaurus/theme-classic and component name is MDXComponents:

yarn swizzle @docusaurus/theme-classic MDXComponents

It'll copy the MDXComponents folder to src/themes. Let's say we want to render Button from material-ui, so we'll have to update the index.js file and add Button in the scope of CodeBlock component:

// ... imports

+ import Button from "@material-ui/core/Button";

export default {
  code: props => {
    const { children } = props;
    if (typeof children === "string") {
-      return <CodeBlock {...props} />;
+      return <CodeBlock {...props} scope={{ Button }} />;
    }
    return children;
  },

  // ...

};

Now, in your live code block you can just use the Button component which will render button from material-ui:

```jsx live
function MuiButton() {
  return (
    <Button variant="contained" color="primary">
      Primary
    </Button>
  );
}
```

You can also add the whole package in scope but that'll increase your bundle size even if you're not using most of the components, so I'd prefer optimized imports and adding the only components which are being used.

Customization

In order to customize the design / implementation of the code block and code preview we'll swizzle the theme:

yarn swizzle @docusaurus/theme-live-codeblock Playground

Let's change orientation of the playground by editing src/themes/Playground/index.js:

// ...

<LiveProvider
  code={children.replace(/\n$/, "")}
  transformCode={transformCode || (code => `${code};`)}
  theme={theme}
  {...props}
>
  <div className={styles.playgroundPreview}>
    <LivePreview />
    <LiveError />
  </div>
  <div
    className={classnames(
      styles.playgroundHeader,
      styles.playgroundEditorHeader,
    )}
  >
    Live Editor
  </div>
  <LiveEditor />
</LiveProvider>

// ...

You can customize this file as you like, I just wanted to demonstrate how easily you can do that.

Caution

Docusaurus team discourages the usage of swizzle so use it with caution:

We would like to discourage swizzling of components until we've minimally reached a Beta stage. The components APIs have been changing rapidly and are likely to keep changing until we reach Beta. Stick with the default appearance for now if possible to save yourself some potential pain in future.

  • Some documentation part of the article is copied from official docs of docusaurus.
  • And thanks to Johnny's comment which saved me from more digging regarding scope of code block.

Posted on by:

mrmuhammadali profile

Muhammad Ali

@mrmuhammadali

I am a sniper. I believe in just one & final shot. Software Engineer || Developer || Geek

Discussion

pic
Editor guide