# `Kotoba.Nodes.Embed`
[🔗](https://github.com/hattoriai/kotoba/blob/v0.8.0/lib/kotoba/nodes/embed.ex#L1)

Something live of the app's own in the document (type `"embed"`): a
canvas, a grid, a chart. The document keeps what the app needs to find
it, and the app renders it, live, in the editor (`Kotoba.Embeds`). The
JSON keys are `kind`, `ref` and `title`.

  * `kind` - what it is, in the app's words, for example `"canvas"`.
  * `ref` - which one, for example the canvas's id, as a string.
  * `title` - its title, for the text and the Markdown of the document,
    and for a page that renders the document without the app.

## Rendering

Kotoba does not know what an embed is: the app says what it renders as,
with the `:embed` option of `Kotoba.Renderer` (and of
`Kotoba.Components.kotoba_content/1`), or for every render (the HTML
cached when content is cast too) with the config:

    config :kotoba, embed: &MyApp.Embeds.render/2

The function gets the embed and the format (`:html`, `:markdown` or
`:text`) and returns what takes its place: safe HTML for `:html` (a
`~H` template, `{:safe, iodata}`; a string is escaped), Markdown or text
as a string, or `nil` for the default. For example, a canvas in Markdown
as a Mermaid diagram (see `Hakushi.Kit.to_markdown/2`):

    def render(%{kind: "canvas", ref: id}, :markdown),
      do: Diagrams.get!(id) |> then(&Hakushi.Kit.to_markdown(&1.kits, &1.graph))

    def render(_embed, _format), do: nil

By default, an embed is its title: a `div.kotoba-embed` with its kind
and ref in HTML, which a page can fill with the app's content, and the
title in text and Markdown. See the [Embeds](embeds.md) guide.

## In Markdown, and back

In Markdown, an embed is what the app renders (or its title) between two
comments that say what it is, which Markdown viewers leave out:

    <!-- kotoba:embed {"kind":"grid","ref":"7","title":"Open tasks"} -->

    | Task | Due |
    | --- | --- |
    | Write the guide | 2026-11-02 |

    <!-- /kotoba:embed -->

`Kotoba.Content.from_markdown/2` reads it back as the embed, so a
document exported to Markdown comes back with its embeds, of any kind.

# `t`

```elixir
@type t() :: %Kotoba.Nodes.Embed{
  extra: term(),
  kind: term(),
  ref: term(),
  title: term(),
  version: term()
}
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
