LeonYew-Ley28 downloadsEmbed interactive HTML files, URLs, or inline HTML as Claude-style sandboxed artifact cards inside notes.
English · 中文
Artifact Embed lets you drop interactive HTML — local files, remote URLs, or inline source — straight into your Obsidian notes as Claude-Desktop-style cards. Each artifact runs in a sandboxed iframe, inherits your Obsidian theme variables, and gives you a tiny toolbar to reload, open externally, or copy the source.
Plain Obsidian only renders Markdown. If you want a tabbed cheatsheet, a chart widget, or a self-contained mini-tool inside a note, your choices are: (a) paste raw HTML and pollute the note's global CSS, (b) launch a dedicated HTML viewer in a separate tab, or (c) iframe a URL into a sidebar pane. None of these put a polished, sandboxed, theme-aware artifact card inline next to your prose. That's what this plugin does.
```artifact code block that auto-detects whether its body is a path, a URL, or inline HTML.<iframe sandbox="allow-scripts"> with no same-origin access; iframe JS can't reach your vault, cookies, or window.parent.--background-primary, --text-normal, --font-text, …) are injected into the iframe, so var(--text-normal) inside your HTML follows light/dark mode.height=600 title="My Demo".```artifact
Assets/cheatsheet.html
```
```artifact
https://example.com/
```
Many production sites set
X-Frame-Options: DENYor a strict CSP — those will refuse to render inside an iframe. That's the remote site's choice, not the plugin's limitation.
```artifact
height=320 title="Counter"
<!doctype html>
<html>
<body>
<button id="b">+1</button>
<span id="n">0</span>
<script>
let count = 0;
document.getElementById('b').onclick = () => {
document.getElementById('n').textContent = ++count;
};
</script>
</body>
</html>
```
The plugin classifies the code block body by these rules:
| Body looks like | Treated as |
|---|---|
Single line starting with http:// or https:// |
external URL → <iframe src=…> |
Single line ending in .html/.htm, no < chars |
vault path → load file → <iframe srcdoc=…> |
| Anything else | inline HTML → <iframe srcdoc=…> |
If the first line of the code block matches key=value syntax (and contains no <), it's parsed as directives:
| Key | Effect | Default |
|---|---|---|
height |
iframe height in px | 480 |
title |
text shown in the card header | source path / URL / inline HTML |
height=600 title="Big chart"
<svg>…</svg>
Claude (and other Anthropic-flavored artifact generators) defaults to its own CSS token system — --color-background-primary, --color-text-primary, --font-sans, --border-radius-lg, etc. None of those variables exist in Obsidian, so the artifact renders with no background, no border, and fallback fonts.
To make Claude reliably emit theme-aware HTML for this plugin, the full rule set is packaged as a reusable Skill at skills/artifact-embed/SKILL.md. The Skill covers Obsidian-native variable mapping, sandbox constraints, output format, and a migration table for existing Anthropic-style artifacts.
skills/artifact-embed/ directory into your project (or symlink it into ~/.claude/skills/artifact-embed/). Claude will auto-invoke it whenever you ask for an Obsidian artifact widget.SKILL.md, copy its body, and paste it as the system prompt (or the first message) of a new project or conversation.Minimal skeleton the Skill produces:
<style>
.card {
background: var(--background-primary);
color: var(--text-normal);
border: 1px solid var(--background-modifier-border);
border-radius: var(--radius-m);
padding: 1rem;
font-family: var(--font-text);
}
.card code {
font-family: var(--font-monospace);
background: var(--background-secondary);
padding: 1px 6px;
border-radius: var(--radius-s);
}
</style>
<div class="card">…</div>
```artifact fence, or save it as Assets/whatever.html and reference it with ```artifact\nAssets/whatever.html\n ``.Already have an existing Claude artifact using
--color-*tokens? Either re-run it through the Skill to regenerate, or apply the find-and-replace mapping in the Skill's migration table.
This plugin isn't in the community plugin browser yet. To install from source:
manifest.json, main.js, and styles.css from the latest release (or clone this repo)<your-vault>/.obsidian/plugins/obsidian-artifact-embed/Ctrl+P → Reload app without saving)The iframe is sandboxed with allow-scripts allow-forms allow-popups allow-modals. allow-same-origin is deliberately omitted. Consequences:
window.parent, document.cookie, localStorage, or vault stateIf you ever need that kind of access, you almost certainly want a different plugin (Templater, Dataview JS, CustomJS). This one's design line is: render untrusted HTML safely.
height=…. Auto-resizing would require sending a postMessage from inside every embedded document, which we deliberately don't enforce.See examples/test-note.md — drop it into a vault to verify all three syntaxes render correctly.
The banner is hand-written SVG (docs/banner.svg) — no external tooling needed. If you want to make your own plugin banner, popular free options include:
MIT © LeonYew-Ley