Esc

comark-qr

QR

Put a QR code next to a preview link so a reviewer can open it on their phone. It's an SVG drawn while parsing, with no script and no image to fetch.

Playground

Open the preview on your phone:

The code is an inline SVG with one path, dark on white in both color schemes, so a phone's camera reads it off any page, and it prints.

:qr{value="https://pr-123.preview.example.com"}
md
Prop What it does
value Required. The text to encode, usually a link. Up to about 2,300 characters.

:qr is inline, so it can sit in a sentence, a table cell, or a list item. It's an svg in a span named "QR code: " and its value for screen readers. The code uses error correction level M and a quiet zone of two modules.

The plugin adds every problem to meta.issues, as Validation describes: a :qr with no value, one too long to encode, text in its brackets, and a prop it doesn't read. Each issue names its block and says how to fix it, and each has its own rule in Doctor. A :qr with no value, or one too long, renders nothing.

A review of a visual change often comes with a preview deployment. Put its link and a code side by side, so a reviewer at a desk clicks and one with a phone scans:

| Preview | Phone |
| --- | --- |
| [pr-123.preview.example.com](https://pr-123.preview.example.com) | :qr{value="https://pr-123.preview.example.com"} |
md

Codes are 8rem wide by default. Set --cqr-size on .cqr or any element above it:

.cqr {
  --cqr-size: 6rem;
}
css

The plugin takes no options. qr: false in comarkUi() turns it off.

The parse plugin encodes the code with uqr, Anthony Fu's zero-dependency ES module of 27 kB (8 kB gzipped) from his QR Toolkit, at its defaults, and writes its modules as an SVG path, so no renderer encodes anything.

comark-ui brings comark-qr and registers it. To use it alone, install it with Comark and a renderer:

pnpm add comark @comark/html comark-qr

Register the plugin and pass the renderer's components:

import { createHtmlRenderer } from "@comark/html";
import qr, { components } from "comark-qr/html";

const render = createHtmlRenderer({ plugins: [qr()], components });
ts

For Vue, React, or Svelte, import from comark-qr/vue, comark-qr/react, or comark-qr/svelte; the components add the styles when they mount. Import comark-qr/style.css with your styles so a server-rendered page doesn't shift. Renderers covers using it with other plugins.

The code sits on a tile that reads the shared tokens: --comark-border for its 1px border and --comark-radius for its corners, capped at 0.5rem so they can't round into the code. The modules are always black on white, in both color schemes, since phones read dark modules on a light ground best. The rules sit in a comark CSS layer, so any plain rule of your own wins.

Class Element
.cqr The span around the code's svg