Skip to content

Custom Dependencies

Create a custom component, extends from Sandbox.vue

in customSetup prop, we add some dependencies, like vue3-toastify.

Tsx is highly recommended. Compared to vue single file, it is simple and straightforward.

tsx
// MySandbox.tsx
import { defineComponent } from 'vue';
import { Sandbox, sandboxProps } from 'vitepress-plugin-sandpack';

/**
 * extends from Sandbox.
 * Compared to VUE single file, it is simple and straightforward.
 */
export const MySandbox = defineComponent({
  name: 'MySandbox',
  props: sandboxProps,
  setup(props, { slots }) {
    return () => (
      <Sandbox
        {...props}
        options={{
          showLineNumbers: true,
        }}
        customSetup={{
          deps: {
            'vue3-toastify': 'latest',
          },
        }}
      >
        { slots?.default ? slots.default() : null }
      </Sandbox>
    );
  },
});
vue
<!-- MySandbox.vue -->
<template>
  <!-- 'code-options' is a build-in prop, do not edit it -->
  <Sandbox
    :rtl="rtl"
    :template="template"
    :light-theme="lightTheme"
    :dark-theme="darkTheme"
    :options="{
      ...props, // do not forget it
      showLineNumbers: true,
    }"
    :custom-setup="{
      ...props, // do not forget it
      deps: { 'vue3-toastify': 'latest' }
    }"
    :code-options="codeOptions"
  >
    <slot />
  </Sandbox>
</template>

<script setup lang="ts">
import { Sandbox, sandboxProps } from 'vitepress-plugin-sandpack';

const props = defineProps(sandboxProps);
</script>

edit theme config, register global component

docs/.vitepress/theme/index.ts

diff
import DefaultTheme from 'vitepress/theme';
import Sandbox from 'vitepress-plugin-sandpack';
+import MySandbox from 'you-dir/MySandbox.vue';
+import 'vitepress-plugin-sandpack/dist/style.css';

export default {
  ...DefaultTheme,
  enhanceApp(ctx) {
    DefaultTheme.enhanceApp(ctx);
    ctx.app.component('Sandbox', Sandbox);
+    ctx.app.component('MySandbox', MySandbox);
  },
}

edit config

docs/.vitepress/config.ts

js
import { defineConfig } from 'vitepress';
import container from 'markdown-it-container';
import { renderSandbox } from 'vitepress-plugin-sandpack';

// rule of 'html tag name' to 'component name'
// 'sanbox' -> 'Sandbox'
// 'my-sandbox' -> MySandbox
// 'sandbox-react-demo' -> SandboxReactDemo

export default defineConfig({
  // ...
  markdown: {
    config(md) {
      md
        // the second parameter is html tag name
        .use(container, 'sandbox', {
          render (tokens, idx) {
            return renderSandbox(tokens, idx, 'sandbox');
          },
        })
        .use(container, 'my-sandbox', {
          render (tokens, idx) {
            return renderSandbox(tokens, idx, 'my-sandbox');
          },
        });
    },
  },
  // ...
})

Use in markdown

Go through the above steps, vue3-toastify can be found.

code of usage
md
      
      null
    
<template>
  <h1>Hello {{ msg }}</h1>
</template>

<script setup>
import { ref } from 'vue';
const msg = ref('world');
</script>

Released under the MIT License.