Skip to content

Repository files navigation

Quartz Chat Bubbles

A Quartz v5 transformer plugin that turns Markdown chat syntax into chat-style bubbles. Chats are only collapsible when the Markdown explicitly opts in.

Syntax

The primary syntax is an attribute-based fenced block. It is explicit, Markdown-like, and leaves room for future metadata without inventing new delimiters.

```chat from="Sam" time="10:42"
Hey, are you joining?
```

```chat status="read"
Yes, in two minutes.
```

When from is omitted, it defaults to self (displayed as “Me”) and the message is placed on the right. Explicit senders default to the left. from="self" and from="me" are equivalent, and the legacy side attribute can still override the inferred side.

Supported attributes:

Attribute Values
from Sender label; defaults to self / “Me”
side Legacy override: left, right
avatar Image URL
time Display timestamp
status sent, delivered, read, failed
variant default, system, warning, success
tone neutral, muted, emphasis
thread Thread identifier added as data-thread
collapsed true, false; makes the thread collapsible and initially collapsed
collapsible true, false; adds a toggle without forcing initial collapse
maxHeight Collapsed height for that thread, in pixels

All options follow the same space-separated key="value" format:

```chat status="sent" time="2026-08-27T10:42:00" avatar="./assets/avatar.png" variant="warning" collapsed="true" maxHeight="300"
This message uses the supported metadata options.
```

Collapse a long chat only when you ask for it:

```chat from="Sam" collapsed="true" maxHeight="420"
This long message starts collapsed.
```

Directive Syntax

Directive-style blocks are available for shorter authoring:

::chat{from="Ava" time="9:15"}
Can you review this?
::

::chat-reply{from="Me" status="read"}
Reviewed. Looks good.
::

Aliases: ::message, ::reply, ::bubble, and ::dm.

Transcript Syntax

For quick conversations, use a :::chat container with < for left-side messages and > for right-side messages.

:::chat {.collapsed maxHeight="420"}
< Sam [10:42]: Hey.

> Me [read]: Hi.

< Sam: Quick question.
:::

The bracket metadata becomes a timestamp unless it matches a known status.

Installation

npx quartz plugin add github:jerlendds/quartz-chat-bubbles

Then enable the plugin in quartz.config.yaml:

plugins:
  - source: github:jerlendds/quartz-chat-bubbles
    enabled: true
    options:
      maxHeight: 600
      defaultCollapsed: false

For TypeScript configuration:

import * as ExternalPlugin from "./.quartz/plugins";

export default {
  plugins: {
    transformers: [
      ExternalPlugin.ChatBubbles({
        maxHeight: 600,
        defaultSide: "left",
      }),
    ],
  },
};

Options

Option Type Default
maxHeight number 600
defaultCollapsed boolean false
defaultSide "left" | "right" "left"
threadClass string undefined
expandLabel string "Show full conversation"
collapseLabel string "Collapse conversation"
enableTranscriptSyntax boolean true
enableDirectiveSyntax boolean true

defaultCollapsed only applies to threads that are explicitly marked collapsible. Unmarked chats never collapse automatically.

Notes

Message bodies support paragraphs, line breaks, inline code, emphasis, strong text, and basic links. Because the plugin emits HTML during Quartz's text transform step, it intentionally does not run full Markdown parsing inside each bubble.

Development

npm install
npm test
npm run build

Commit the generated dist/ output before publishing.

About

A plugin for displaying chat bubbles on a Quartz page (https://quartz.jzhao.xyz/) via custom MD syntax

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages