npm package: @jxpeng98/vitepress-webr
Description: VitePress plugin and components to run R (webR) in Markdown with shared page state.
Author: Jiaxin Peng
Latest version: 1.0.1

# vitepress-webr

Run R (webR) inline in VitePress. This package provides:

- Markdown-it plugins to turn code into interactive cells:
  - Fenced blocks: `` ```webr `` → interactive cell
  - HTML blocks: `<WebR>…</WebR>` → interactive cell (dedented, newlines preserved)
  - Vue components with a shared in‑browser interpreter per page and a tidy VitePress look

## Highlights

- Per‑page shared state: later cells can reuse variables from earlier cells
- Fresh state on new pages (SPA navigation): the first run clears globals
- Editor hidden by default; buttons: Run, Clear, Show/Hide Code
- Dark mode via VitePress tokens — no hardcoded colors
- Adaptive heights: editor/output avoid empty space, but can grow

## Table of Contents

- [vitepress-webr](#vitepress-webr)
  - [Highlights](#highlights)
  - [Table of Contents](#table-of-contents)
  - [Installation](#installation)
  - [Setup](#setup)
    - [VitePress Configuration (`.vitepress/config.(ts|mts)`)](#vitepress-configuration-vitepressconfigtsmts)
    - [VitePress Theme Enhancement (`.vitepress/theme/index.(ts|mts)`)](#vitepress-theme-enhancement-vitepressthemeindextsmts)
  - [Usage](#usage)
    - [Fenced Blocks](#fenced-blocks)
      - [Optional Metadata](#optional-metadata)
    - [HTML Form](#html-form)
  - [Component API](#component-api)
  - [Behavior Notes](#behavior-notes)
  - [Additional R Packages](#additional-r-packages)
  - [Styling](#styling)
  - [Customize](#customize)

## Installation

```bash
pnpm add -D vitepress-webr
```

## Setup

### VitePress Configuration (`.vitepress/config.(ts|mts)`)

```ts
import { createWebRMarkdownPlugin, createWebRHtmlBlockPlugin } from 'vitepress-webr/markdown'

export default {
  markdown: {
    config(md) {
      // Default layout: vertical (output below). Use 'horizontal' for side‑by‑side.
      md.use(createWebRMarkdownPlugin({ layout: 'vertical' }))
      md.use(createWebRHtmlBlockPlugin({ layout: 'vertical' }))
    }
  }
}
```

### VitePress Theme Enhancement (`.vitepress/theme/index.(ts|mts)`)

```ts
import { enhanceAppWithWebR } from 'vitepress-webr/client'

export default {
  enhanceApp(ctx) {
    enhanceAppWithWebR(ctx)
  }
}
```

## Usage

### Fenced Blocks

Use ` ```webr ` to create an interactive R cell.

```webr title="Define data"
data <- c(3, 3, 6, 9, 12)
print(sum(data), length(data))
```

#### Optional Metadata

Metadata can be added in the info string:

- **Title**: `title="My Cell"` or bare words after `webr` (e.g., ` ```webr My Cell `)
- **Layout**: `layout=horizontal` | `layout=vertical` or shorthand tokens: `horizontal`/`right`/`vertical`
- **Locale Override**: `locale="en"` | `"zh-CN"`

**Example:**

```webr layout=horizontal title="Horizontal (EN)" locale="en"
x <- 41
print(paste("x =", x))
```

### HTML Form

Use `<WebR>…</WebR>` HTML blocks for interactive cells.

```markdown
<WebR title="中文示例" locale="zh-CN" layout="vertical">
print("你好，webR！")
</WebR>
```

## Component API

- `<WebR ...>` (wrapper) forwards to `<WebRCell ...>` ensuring identical UI to fenced blocks
- **Props:**
  - `layout?`: `'vertical'` | `'horizontal'`
  - `locale?`: `string` (e.g., `'en'`, `'zh-CN'`)
  - `title?`: `string`
  - `code?`: `string` (optional initial code)
  - `code64?`: `string` (base64 initial code; used by plugins)

## Behavior Notes

- **Script semantics:** Only printed output appears. Bare expressions won’t display unless printed.
- **First run:** Downloads webR. Subsequent runs reuse the same instance.
- **State persistence:** Variables persist within the same page; navigating to another page starts fresh state.

## Additional R Packages

By default webR ships with (roughly) base R only. To use extra packages such as `ggplot2` or `dplyr` inside your interactive cells:

- Install them once (first run may be slow because the package is downloaded into the browser).
- Load them with `library()` and reuse them in later cells on the same page (this plugin uses a shared webR instance per page).

**Install and load packages in a cell:**

```webr title="Install extra packages (first time)"
webr::install(c("ggplot2", "dplyr"))
library(ggplot2)
library(dplyr)
```

After installation, other cells on the same page can use these packages directly:

```webr title="Use ggplot2"
library(ggplot2)

ggplot(iris, aes(Sepal.Length, Sepal.Width, colour = Species)) +
  geom_point()
```

Notes:

- Packages are stored client‑side (e.g. IndexedDB); switching browsers or using private windows may require reinstalling.
- Prefer the `webr` helper, or explicitly set the WASM repo:  
  `install.packages("ggplot2", repos = "https://repo.r-wasm.org")`  
  Installing from the default CRAN mirror usually won’t work in webR.

## Styling

- Adapts to VitePress theme via CSS variables (no hardcoded colors)
- Editor/output heights auto‑fit content; users can drag the editor bigger

## Customize

- **Default layout per site:** Pass `{ layout: 'horizontal' }` to the plugins in config
- **webR version/CDN:** Update `packages/vitepress-webr/src/runtime.ts`