Skip to content
Protocore Design Systemv1.6.9

/// Typography

Prose

A typographic wrapper that styles raw rendered HTML (CMS/markdown output) with the PDS type scale and rhythm.

import { Prose } from "@protocore/pds";
View as Markdown

Rendering markup

Wrap already-rendered HTML — from a CMS, an MDX pipeline, or markdown — in Prose. Every descendant (h1h6, p, lists, blockquote, code, pre, a, table, hr) inherits the type scale and vertical rhythm from the single scope; the source markup carries no classes of its own.

Deploying to the edge

Protocore ships static sites to CloudFront, one distribution per domain. Content is driven by a single multi-tenant CMS, so editors never touch a build.

How a publish flows

  • An editor saves a change in the CMS.
  • A webhook triggers the affected site's static export.
  • The bundle syncs to S3 and the distribution is invalidated — see the pipeline notes.
Sharp edges, monochrome surfaces, one reserved accent. The rhythm carries the page.

Inline tokens.css holds the source of truth, and a pre block renders any snippet in the mono family:

export const deploy = () => sync(bucket);

Trusted HTML string

Pass a pre-sanitized HTML string via the html prop when the content arrives as a string off the wire. It renders through dangerouslySetInnerHTML, so the producer must sanitize it first.

From the CMS

This block was authored in a rich-text field and rendered to plain HTML.

  1. Editors write content.
  2. The field serializes to HTML.
  3. Prose gives it the house type scale.

Compact density

size="sm" drops the base to 14px with tighter flow spacing — for sidebars, cards, and dense help panels.

Release 2.4

Compact prose for changelog panels and card bodies. Same rhythm, a smaller reading measure.

  • Added the OverflowList component.
  • Fixed RTL mirroring on the Timeline.

When to use it

Prose is the render target for any body content the design system does not compose element-by-element: a blog post, a changelog entry, a docs page, a rich-text CMS field. Because Protocore sites are CMS-driven, this is the seam where editor output meets the type system — the CMS emits plain semantic HTML and Prose gives it the house measure, rhythm, and link treatment without the editor needing to know a single class name.

It is server-safe and stateless: render it in a React Server Component, or feed it a string. For content you compose yourself in JSX, reach for Text, Heading, and Blockquote directly instead.

Usage

Do

  • Feed it semantic HTML from your CMS or markdown renderer.
  • Sanitize any `html` string upstream before it reaches the prop.
  • Use `size="sm"` inside cards and narrow columns.
  • Let a parent constrain the line length (a `max-width` around 68ch reads best).

Don't

  • Pass unsanitized user input to `html`; sanitize at the source.
  • Reach for it to lay out app UI; compose Text/Heading/Stack there.
  • Add classes to the inner markup; the scope styles bare elements.
  • Nest a Prose inside a Prose; one scope owns the whole block.

Accessibility

  • Emits no wrapper semantics beyond a `div`; the heading order and landmarks come from your source HTML, so keep it well-structured.
  • Link styling uses an underline plus an accent decoration color, so links are distinguishable without relying on color alone.
  • Code blocks scroll horizontally inside their own container so long lines never force the page to scroll.

Prose props

PropTypeDefaultDescription
classNamestring
htmlstringA trusted HTML string to render into the scope (e.g. CMS/markdown output). Rendered via `dangerouslySetInnerHTML`, so it MUST already be sanitized by the producer. Mutually exclusive with `children`.
sizeenummdBody density: `sm` sets a 14px base with tighter rhythm; `md` (default) is the 16px reading measure.
styleCSSProperties

Related

  • TextBody copy primitive — polymorphic, with tokenised size, color, and weight.
  • HeadingSection heading — sharp, medium-weight, with a tokenised type ramp and matched tracking.
  • BlockquotePull quote — a hairline ink rule, lead-size text, and a mono attribution slot.
  • CodeBlockMonospace code panel — sunken surface, hairline border, and an optional title bar.