Remark

A Remark plugin that transforms code blocks into interactive Codespark components in MDX documents.

@codespark/plugin-remark is a unified remark plugin that transforms fenced code blocks into Codespark React components. It enables you to create interactive code playgrounds directly in your MDX documentation with minimal syntax.

Installation

npm install @codespark/plugin-remark

Vite

For Vite users, first install the official MDX Rollup plugin:

npm install @mdx-js/rollup
vite.config.ts
import remarkCodespark from '@codespark/plugin-remark';
import mdx from '@mdx-js/rollup'
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    mdx({ 
      providerImportSource: '@codespark/react', 
      remarkPlugins: [remarkCodespark] 
    })
  ]
});

Next.js

For Next.js users, first install the official MDX package:

npm install @next/mdx @mdx-js/loader @mdx-js/react

Then configure next.config.mjs to use the remark plugin:

next.config.mjs
import remarkCodespark from '@codespark/plugin-remark';
import createMDX from '@next/mdx';

const withMDX = createMDX({
  options: {
    providerImportSource: '@codespark/react', 
    remarkPlugins: [remarkCodespark], 
  },
});

/** @type {import('next').NextConfig} */
const nextConfig = {
  pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
};

export default withMDX(nextConfig);

Fumadocs

Fumadocs is a React.js documentation framework built on MDX. To use Codespark with Fumadocs, add the following configuration:

source.config.ts
import { defineConfig } from 'fumadocs-mdx/config';

export default defineConfig({
  mdxOptions: {
    providerImportSource: '@codespark/react', 
    remarkPlugins: [remarkCodespark] 
  }
})

Usage

Directives

The plugin recognizes three directives that can be added to code block meta strings:

DirectiveComponentDescription
codespark<Codespark />Full playground with editor and preview
codespark-editor<CodesparkEditor />Editor only
codespark-preview<CodesparkPreview />Preview only

Supported Languages

The plugin only processes code blocks with the following languages:

  • js
  • jsx
  • ts
  • tsx

Basic Usage

Add the codespark directive to any JavaScript/TypeScript code block:

```tsx codespark
export default function App() {
  return <button>Click me</button>
}
```

This transforms into:

<Codespark name="./App.tsx" code={"export default function App() {\n  return <button>Click me</button>\n}"} />

Code blocks with other languages (e.g., python, bash) are left unchanged.

Multi-file Usage

Use the file attribute to define multiple files that will be merged into a single Codespark component:

```tsx codespark file="./button.tsx"
export function Button({ children }) {
  return <button className="btn">{children}</button>
}
```

```tsx codespark file="./App.tsx"
import { Button } from './button'

export default function App() {
  return <Button>Click me</Button>
}
```

This transforms into a single component:

<Codespark
  name="./App.tsx"
  files={{
    "./button.tsx": "export function Button({ children }) {\n  return <button className=\"btn\">{children}</button>\n}",
    "./App.tsx": "import { Button } from './button'\n\nexport default function App() {\n  return <Button>Click me</Button>\n}"
  }}
/>

Multi-file rendering rules:

  • Consecutive code blocks with file attributes are automatically merged
  • The name prop is set to the last file's path
  • Additional attributes are taken from the last code block only
  • Non-code content between blocks breaks the merge

Editor Only

Use codespark-editor for a standalone code editor without preview:

```tsx codespark-editor
const greeting = "Hello, World!";
console.log(greeting);
```

Transforms to:

<CodesparkEditor value={"const greeting = \"Hello, World!\";\nconsole.log(greeting);"} />

Preview Only

Use codespark-preview for a preview without the editor:

```tsx codespark-preview
export default () => (
  <div className="p-4 bg-blue-500 text-white rounded">
    Preview Only
  </div>
)
```

Transforms to:

<CodesparkPreview code={"export default () => (\n  <div className=\"p-4 bg-blue-500 text-white rounded\">\n    Preview Only\n  </div>\n)"} />

Attributes

You can pass additional attributes to the generated component through the code block meta string.

String Attributes

```tsx codespark name="Demo.tsx" title="My Demo"
export default () => <div>Hello</div>
```

Boolean Attributes

Standalone attributes are treated as true:

```tsx codespark readonly
export default () => <div>Hello</div>
```

Explicit boolean values:

```tsx codespark readonly=true tailwind=false
export default () => <div>Hello</div>
```

Numeric Attributes

```tsx codespark height=400
export default () => <div>Hello</div>
```

How It Works

  1. AST Traversal: The plugin traverses the MDX AST looking for code nodes
  2. Meta Parsing: Parses the code block's meta string for directives and attributes
  3. Validation: Checks if the language is supported and a valid directive is present
  4. File Merging: Detects consecutive file blocks and merges them into a single files object
  5. JSX Generation: Creates MDX JSX elements with appropriate props
  6. Tree Modification: Replaces the original code nodes with the generated JSX components

Last updated on