
# Markdown preview

`markdownPreview` renders a Markdown file next to itself: a preview button in the tab bar, a
preview tab beside the source, and a button back. It keeps up as you type.

```ts
import { markdownPreview } from "codelet/extensions/markdown";
import { FileSystem, Workbench } from "codelet/workbench";

const workbench = new Workbench({
  parent: document.getElementById("app")!,
  fs: new FileSystem({ "/README.md": "# Hello" }),
  extensions: [markdownPreview],
});
```

`markdownPreview` takes no options.

::warning
The renderer, [md4x](https://esm.sh/md4x) (md4c compiled to WebAssembly), is fetched from a CDN
the first time a preview opens — it isn't bundled with codelet. A page that's offline, or served
under a CSP that blocks `esm.sh`, opens a preview tab that says so instead of rendering. Nothing
is fetched until the first preview opens.
::

## Try it

Click the preview button at the right of the tab bar above `guide.md` to render it. The
renderer loads from a CDN the first time you open a preview, so it may take a moment to appear.

::codelet-playground{mode="workbench" extensions="markdown-preview" active="guide.md" height="420"}

```ts [index.ts]
export const greet = (name: string) => `hi ${name}`;
```

````md [guide.md]
# codelet

A minimal web IDE you can embed in your own app.

- Renders as you type
- Code fences painted in the editor's theme
- [Read the docs](https://github.com/pithings/codelet)

```ts
import { greet } from "./index";

console.log(greet("codelet"));
```
````

::

## Opening a preview

Four ways in, all running the same **Open Preview** command:

- The preview icon at the right of the tab bar, over any open Markdown file.
- **Open Preview** on a Markdown row's context menu in the explorer, without opening the file
  first.
- **Open Preview** on a tab's own context menu.
- The command palette, `Markdown: Open Preview`.

Running it on a file that's already showing a preview reveals that tab rather than opening a
second one.

The preview's own tab carries the way back: an **Open Source** button at the right of its bar,
which shows the file it's a preview of.

## Code fences

Fenced code blocks are highlighted with the workbench's own syntax colours — the same theme the
editor uses, including a switch between light and dark. The language named on a fence's opening
line (`ts`, `sh`, `jsx`, and so on) is read the same way the editor reads one; a name it doesn't
recognise renders the block unhighlighted rather than failing.

## Not the same as the Markdown language server

`markdownPreview` only renders a file's contents — it doesn't touch the editor. For diagnostics,
completion or symbols while editing Markdown, use the Markdown language server instead. The two
are independent and can run together.

:read-more{to="/extensions/lsp"}

:read-more{to="/extensions"}
