humanonlyweb/writer

Blocks

Your Vue components, written in Markdown.

Markdown

Writing one

Attributes become props, #name sections become slots:

::callout{type="warning"}
#title
Heads up
#default
Body with **Markdown**.
::
Copy code
Copy code

Registering

In Nuxt, every component in components/blocks/ is a block: Callout.vue is ::callout, media/Video.vue is ::media-video. They load on demand.

In Vue, pass them to createWriter({ blocks: { callout: Callout } }).

The slash menu's labels and snippets go in app.config.ts (or { component, label, snippet } in Vue):

export default defineAppConfig({
  writer: {
    blocks: {
      callout: { label: "Callout", snippet: '::callout{type="${note}"}\n${}\n::' },
    },
  },
});
Copy code

Snippets use CodeMirror's syntax: ${} is where the cursor lands, ${name} a field Tab moves to.

Unknown blocks

Only registered blocks render. Anything else renders its content alone, so a removed block never breaks a page.

GitHub alerts (> [!NOTE]) render as a blockquote, or as your note block if you register one.

In the editor

Blocks render inside the editor through the app, not the page around it: they get app-level plugins and provides, but nothing provided by a parent of <WriterEditor>. Declare a __node prop to receive the block's raw node.