@rspress/plugin-playground

Provide a real-time playground to preview the code blocks in MDX files.

Installation

npm
yarn
pnpm
bun
npm add @rspress/plugin-playground -D

Usage

Register

First, write the following config in the config file:

rspress.config.ts
import { defineConfig } from 'rspress/config';
import { pluginPlayground } from '@rspress/plugin-playground';

export default defineConfig({
  plugins: [pluginPlayground()],
});
Note

This plugin will set markdown.mdxRs to false. In the future, the Rspress team will port this plugin to the Rust version of the compiler.

Internal Components

Note

It is recommended to use js or jsx to write sample code to avoid ts type errors in the editor.

The component code of internal components is declared in the mdx file. This plugin supports jsx and tsx. You can declare the following code block in the mdx file:

```jsx
import React from 'react';

function App() {
  return <div>Hello World</div>;
}

export default App;
```

Otherwise, You can use direction parameter to specify the playground layout, horizontal and vertical are supported:

```jsx direction=vertical
import React from 'react';

function App() {
  return <div>Hello World</div>;
}

export default App;
```

It's worth noting that you need to export the component as default, and Rspress will automatically render this component.

But if you want to keep the style of the code block instead of rendering it as a component, you can add the pure identifier to specify, the usage is as follows:

```tsx pure
import React from 'react';

function App() {
  return <div>Hello World</div>;
}

export default App;
```

If you have set defaultRenderMode to 'pure', Rspress will not render this component by default, but instead display it as a code block. If you want to render a code block as a component in this situation, you can do add the preview identifier to specify, the usage is as follows:

```tsx playground
function App() {
  return <div>Hello World</div>;
}
export default App;
```
Tip

Make sure the document ends with .mdx.

External Components

In addition to writing the component code in the code block of the mdx file, you can also write the component code in an external file, and then import it in the mdx file through the code tag. For example

example.mdx
<code src="./Demo.jsx" />
Demo.jsx
import React from 'react';

export default function App() {
  return <div>Hello World</div>;
}

Same as internal components, external components also support direction attribute:

example.mdx
<code src="./Demo.jsx" direction="vertical" />

External components also need to export the component as default. Through the src attribute of the code tag, you can specify the path of the external component. This plugin supports both relative paths and alias paths(alias).

For some more complex components, this way of using external components will be more convenient.

Define the layout of the entire page

You can write playgroundDirection in frontmatter to define the layout of the editor and preview area in the entire page.

example.mdx
---
title: title
playgroundDirection: horizontal
---

Priority: Defined directly on the preview area > Page Definition > Configuration.

Configuration

This plugin accepts an object parameter, the type is as follows:

interface PlaygroundOptions {
  render: string;
  include: Array<string | [string, string]>;
  // Define the default playground layout (horizontal/vertical)
  defaultDirection: 'horizontal' | 'vertical';
  // Define the position of the editor in horizontal layout (left/right)
  editorPosition: 'left' | 'right';
  // Default editor (monaco) partial configuration
  monacoLoader: Parameters<typeof loader.config>[0];
  monacoOptions: MonacoEditorProps['options'];
}
Note

monacoLoader and monacoOptions will be serialized to JSON, so some data types, such as functions and circularly referenced objects, are not supported.

render

You can customize the render file for rendering Playground. Please note that the file name must be Playground.(jsx?|tsx?)

pluginPlayground({
  render: '/path/to/render/Playground.tsx',
});

In the custom playground, you can directly import the original editor and renderer, and import pre-packaged dependencies through _rspress_playground_imports:

import getImport from '_rspress_playground_imports';
import { Runner, Editor } from '@rspress/plugin-playground/web';

You can refer to the built-in Playground.tsx.

include

By default, this plugin will automatically scan all import statements in the demos, the packages not used in the demos cannot be used in the playground. If you want to add other packages to the playground, you can use the include parameter:

pluginPlayground({
  include: [
    // Add dayjs package
    'dayjs',
    // Add a package named "my-package", and it actual reference to "/path/to/package/index.js"
    ['my-package', '/path/to/package/index.js'],
  ],
});

babelUrl

Playground uses @babel/standalone to compile the demo code, loaded from cdnjs.com by default.

You can modify the URL served to other CDNs, such as unpkg, jsdelivr, etc.

monacoLoader

Configure monaco-loader behaviors, loaded from cdnjs.com by default.

You can modify the URL served to other CDNs, such as unpkg, jsdelivr, etc.

The full document can be found at suren-atoyan/monaco-loader

monacoOptions

Configure monaco editor, corresponding to IStandaloneEditorConstructionOptions

defaultRenderMode

The default mode of rendering internal code blocks that do not have the pure or playground identifiers declared by users, defaulting to playground.

  • pure: render as regular code block
  • playground: render as Playground component