Skip to content
Components, switch product

Markdown text

<gui-markdown-text> renders Markdown as HTML: headings, lists, links, quotes, code and tables, styled to match the other elements. It ships no parser: you give it the one your app already uses.

Code of the example above
MarkdownTextBasic.tsx
import type { SanitizedHtml } from '@golemui/gui-components';
import snarkdown from 'snarkdown';
import { GuiMarkdownText } from '@golemui/gui-components/react';
import '@golemui/gui-components/index.css';
const dependencies = {
markdown: { parse: (md: string) => snarkdown(md) as SanitizedHtml },
};
const notes = `## What's new in 2.4
Shared projects are here. Invite **Grace Hopper** or anyone on your team, and edit together.
- Comments on every task
- Due dates in the calendar
- Faster search
Read the [full changelog](#changelog).`;
export function MarkdownTextBasic() {
return (
<GuiMarkdownText
id="release-notes"
dependencies={dependencies}
md={notes}
/>
);
}

The element’s entry point is @golemui/gui-components/markdown-text, which registers <gui-markdown-text> and nothing else. To install the package and load the stylesheet, see Installation.

The @golemui/gui-components/react components have typed props and an on* prop for each event. React 18 or later.

MarkdownTextExample.tsx
import { GuiMarkdownText } from '@golemui/gui-components/react';
import '@golemui/gui-components/index.css';
export function MarkdownTextExample() {
return (
<GuiMarkdownText
md="## Release notes"
/>
);
}

It renders nothing until you give it a parser in its dependencies property, below.

Properties

Property Type Default Description
md string – The Markdown to render.
dependencies { markdown?: MarkdownParser } – Provides the markdown parser that turns md into HTML. The element inserts that HTML without sanitizing it, see MarkdownParser.

CSS custom properties

Property Default Description
--gui-md-text-color – Text color.
--gui-md-line-height – Line height.
--gui-md-heading-color – Heading color.
--gui-md-heading-weight – Heading font weight.
--gui-md-link-color – Link color.
--gui-md-link-hover-color – Link color on hover.
--gui-md-blockquote-bg – Quote background.
--gui-md-blockquote-border-color – Quote border color.
--gui-md-blockquote-color – Quote text color.
--gui-md-code-bg – Code background.
--gui-md-code-color – Code text color.
--gui-md-code-radius – Code corner radius.
--gui-md-hr-color – Horizontal rule color.

dependencies takes an object with a markdown parser: any object with a parse(markdown) method that returns its HTML, synchronously. Set it as a property, in a script or with your framework’s property binding. The element runs parse again each time md or dependencies change.

In TypeScript, parse returns SanitizedHtml, a string type that only a cast creates. The cast marks the place where you sanitize the HTML, or trust where it comes from:

main.ts
import type { SanitizedHtml } from '@golemui/gui-components';
import '@golemui/gui-components/markdown-text';
import snarkdown from 'snarkdown';
const notes = document.querySelector('gui-markdown-text')!;
// The Markdown is in your own code, so the cast alone is enough.
notes.dependencies = {
markdown: { parse: (md) => snarkdown(md) as SanitizedHtml },
};

Most libraries fit with a small wrapper, such as marked.parse(md, { async: false }) for marked. The examples on this page use snarkdown, a tiny parser, and load it from a CDN only so they run in the page.

The element puts the parser’s HTML into the page as it is, without sanitizing it. When the Markdown can come from your users or from stored data, sanitize the parser’s output, for example with DOMPurify, so no script or event handler gets into your page. Snarkdown and Marked keep raw HTML and javascript: links. Micromark and markdown-it escape both with their default options. When all the Markdown comes from your own code, the cast alone is enough.

Code of the example above
MarkdownTextSanitize.tsx
import type { SanitizedHtml } from '@golemui/gui-components';
import DOMPurify from 'dompurify';
import snarkdown from 'snarkdown';
import { GuiMarkdownText } from '@golemui/gui-components/react';
import '@golemui/gui-components/index.css';
const dependencies = {
markdown: {
parse: (markdown: string) =>
DOMPurify.sanitize(snarkdown(markdown)) as SanitizedHtml,
},
};
// A visitor's comment. The sanitizer drops the onmouseover handler and keeps the text.
const comment = `Loved the **Lisbon** tour! <span onmouseover="alert('Gotcha')">Hover me</span>`;
export function MarkdownTextSanitize() {
return (
<GuiMarkdownText
id="guest-comment"
dependencies={dependencies}
md={comment}
/>
);
}

<gui-markdown-text> renders the parser’s HTML in the light DOM, with no wrapper of its own, and the stylesheet styles the tags inside it:

gui-markdown-text
<gui-markdown-text>
<h2>What's new in 2.4</h2>
Shared projects are here. Invite <strong>Grace Hopper</strong> or anyone on
your team, and edit together.<br />
<ul>
<li>Comments on every task</li>
<!-- …one li per item -->
</ul>
<br />Read the <a href="#changelog">full changelog</a>.
</gui-markdown-text>

What’s inside the element is whatever your parser writes; this is snarkdown’s output for the first example.

ClassPart
gui-markdown-textOn an ancestor of the element, not on the element: turns its styles on.

Inside, the stylesheet styles the plain tags the parser writes: h1 to h6, p, a, strong, em, code, pre, blockquote, ul, ol, li, hr, img, table, th and td. Override them with selectors such as .gui-markdown-text gui-markdown-text h2.

The element has tokens of its own for its typography, the --gui-md-* tokens listed in its API above and with their defaults in Tokens. It also reads these design tokens:

TokenWhat it styles
--gui-font-smThe text size, and the size of code blocks.
--gui-font-3xl … --gui-font-baseThe sizes of the headings, h1 to h6.
--gui-space-1 … --gui-space-6The space around headings, paragraphs and lists.
--gui-radius-mdThe corners of code blocks, quotes and images.
--gui-border-defaultThe borders of the table cells.
--gui-bg-surface-hoverThe background of the table headers.
styles.css
/* Roomier text, with brand links, in the help panel only. */
.help-panel {
--gui-md-line-height: 1.8;
--gui-md-link-color: #d96c3f;
--gui-md-link-hover-color: #b4532b;
}

To restyle beyond the tokens, see Overriding styles; for dark mode and the Clay theme, see Themes and dark mode.

  • Headings. The Markdown’s headings are real headings in your page’s outline. Start the Markdown at the level that fits where it sits, such as ## under the page’s h1.
  • Links and images. Write link text that makes sense out of context, and alt text for every image: ![A map of Lisbon](lisbon.png).
  • Content only. The element adds no role, name or announcement. When the Markdown changes, screen readers don’t announce it.

The element takes no focus and has no keys of its own. Links inside it work as anywhere else.

What every element shares is in Accessibility.