Color mode

Excalidraw

Excalidraw drawing rendering for Obsidian wikilinks.

日本語

Overview

excalidraw() provides the renderAttachment hook that @riebeckite/plugin-obsidian-markdown uses when an embedded wikilink (![[drawing.excalidraw]]) resolves to an Excalidraw file. The plugin emits a placeholder figure carrying the drawing payload, and the client entry renders it to SVG.

Usage

ts
import { defineConfig } from "@riebeckite/core";
import { excalidraw } from "@riebeckite/plugin-excalidraw";
import { obsidianMarkdown } from "@riebeckite/plugin-obsidian-markdown";
 
export default defineConfig({
  // ...
  plugins: [obsidianMarkdown(), excalidraw()],
});

The plugin registers style.css and a client entry (initExcalidraw) that the app calls on page initialization.

Supported formats

*.excalidraw — plain JSON scene

A compact Excalidraw export with elements, optional appState, and files.

*.excalidraw.md — Obsidian Excalidraw drawing

Obsidian "Excalidraw" plugin stores drawings in Markdown. The ## Drawing fenced code block is extracted and supports both json and lz-string compressed-json variants.

Behavior

Build (renderAttachment)

  • Only handles embedded wikilinks (![[...]]) to paths ending in .excalidraw or .excalidraw.md; everything else returns null and falls through to the attachment plugin

  • Reads the file under config.content.directory (path-traversal safe)

  • Parses the scene and emits

    html
    <figure class="rr-excalidraw" data-excalidraw="pending" data-excalidraw-lazy="true">
      <div class="rr-excalidraw__canvas" role="img" aria-label="drawing.excalidraw"></div>
      <script type="application/json" class="rr-excalidraw__payload">{"elements":[...],"appState":{...},"files":{...}}</script>
    </figure>
  • Wikilink aliases can set a size: ![[drawing.excalidraw|800]] (width) or ![[drawing.excalidraw|800x600]] (width x height)

  • Missing files, invalid scenes, or out-of-directory paths render an error placeholder and log to the console

Client (initExcalidraw)

  • Renders pending figures to SVG with exportToSvg from @excalidraw/excalidraw
  • Figures marked data-excalidraw-lazy="false" render immediately; the rest render when they scroll into view (IntersectionObserver, 200px margin)
  • Success → data-excalidraw="ready" (the SVG replaces the empty canvas)
  • Failure → data-excalidraw="error" plus a placeholder message

Options

Option Type Default Description
lazy boolean true Render lazily in the browser (as the figure enters the viewport) instead of immediately

Exports

  • excalidraw(options?) / excalidrawPlugin — plugin factory
  • Type: ExcalidrawOptions

See also

History

1 changesCollapseExpand
1 + <!-- Generated from packages/plugins/excalidraw/README.md. Do not edit this page directly; edit the package README and run `pnpm docs:sync`. -->
2 +
3 + # Excalidraw
4 +
5 + Excalidraw drawing rendering for Obsidian wikilinks.
6 +
7 + [日本語](./excalidraw.md)
8 +
9 + ## Overview
10 +
11 + `excalidraw()` provides the `renderAttachment` hook that
12 + `@riebeckite/plugin-obsidian-markdown` uses when an embedded wikilink
13 + (`![[drawing.excalidraw]]`) resolves to an Excalidraw file. The plugin emits a
14 + placeholder figure carrying the drawing payload, and the client entry renders
15 + it to SVG.
16 +
17 + ## Usage
18 +
19 + ```ts
20 + import { defineConfig } from "@riebeckite/core";
21 + import { excalidraw } from "@riebeckite/plugin-excalidraw";
22 + import { obsidianMarkdown } from "@riebeckite/plugin-obsidian-markdown";
23 +
24 + export default defineConfig({
25 + // ...
26 + plugins: [obsidianMarkdown(), excalidraw()],
27 + });
28 + ```
29 +
30 + The plugin registers `style.css` and a client entry (`initExcalidraw`) that
31 + the app calls on page initialization.
32 +
33 + ## Supported formats
34 +
35 + ### `*.excalidraw` — plain JSON scene
36 +
37 + A compact Excalidraw export with `elements`, optional `appState`, and
38 + `files`.
39 +
40 + ### `*.excalidraw.md` — Obsidian Excalidraw drawing
41 +
42 + Obsidian "Excalidraw" plugin stores drawings in Markdown. The `## Drawing`
43 + fenced code block is extracted and supports both `json` and lz-string
44 + `compressed-json` variants.
45 +
46 + ## Behavior
47 +
48 + ### Build (`renderAttachment`)
49 +
50 + - Only handles embedded wikilinks (`![[...]]`) to paths ending in
51 + `.excalidraw` or `.excalidraw.md`; everything else returns `null` and falls
52 + through to the attachment plugin
53 + - Reads the file under `config.content.directory` (path-traversal safe)
54 + - Parses the scene and emits
55 +
56 + ```html
57 + <figure class="rr-excalidraw" data-excalidraw="pending" data-excalidraw-lazy="true">
58 + <div class="rr-excalidraw__canvas" role="img" aria-label="drawing.excalidraw"></div>
59 + <script type="application/json" class="rr-excalidraw__payload">{"elements":[...],"appState":{...},"files":{...}}</script>
60 + </figure>
61 + ```
62 +
63 + - Wikilink aliases can set a size: `![[drawing.excalidraw|800]]` (width) or
64 + `![[drawing.excalidraw|800x600]]` (width x height)
65 + - Missing files, invalid scenes, or out-of-directory paths render an error
66 + placeholder and log to the console
67 +
68 + ### Client (`initExcalidraw`)
69 +
70 + - Renders pending figures to SVG with `exportToSvg` from
71 + `@excalidraw/excalidraw`
72 + - Figures marked `data-excalidraw-lazy="false"` render immediately; the rest
73 + render when they scroll into view (`IntersectionObserver`, 200px margin)
74 + - Success → `data-excalidraw="ready"` (the SVG replaces the empty canvas)
75 + - Failure → `data-excalidraw="error"` plus a placeholder message
76 +
77 + ## Options
78 +
79 + | Option | Type | Default | Description |
80 + | ------ | ---- | ------- | ----------- |
81 + | `lazy` | `boolean` | `true` | Render lazily in the browser (as the figure enters the viewport) instead of immediately |
82 +
83 + ## Exports
84 +
85 + - `excalidraw(options?)` / `excalidrawPlugin` — plugin factory
86 + - Type: `ExcalidrawOptions`
87 +
88 + ## See also
89 +
90 + - [Plugin guide](../reference/plugin-api.en.md)
91 + - [`@riebeckite/plugin-obsidian-markdown`](./obsidian-markdown.en.md)
92 + - [`@riebeckite/plugin-attachment`](./attachment.en.md)
93 +