Prose
Used to style remote HTML content, such as markdown or a CMS response, with the Saas UI typography language.
Title Heading 1
Title Heading 2
Title Heading 3
Title Heading 4 testing
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi at dolor nec ex rutrum semper. Praesent ultricies purus eget lectus tristique egestas ac in lacus. Press Ctrl + C to copy.
Fusce placerat ipsum vel sollicitudin imperdiet. Morbi vulputate non diam at consequat. Donec vitae sem eu arcu auctor scelerisque vel in turpis.
import { Prose } from '#components/ui/prose'
// Used for syntax highlighting
const html = String.raw
const content = html`
<h1>Title Heading 1</h1>
<h2>Title Heading 2</h2>
<h3>Title Heading 3</h3>
<h4>Title Heading 4 <code>testing</code></h4>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi at dolor nec
ex rutrum semper. Praesent ultricies purus eget lectus tristique egestas ac
in lacus. Press <kbd>Ctrl</kbd> + <kbd>C</kbd> to copy.
</p>
<hr />
<p>
Fusce placerat ipsum vel sollicitudin imperdiet. Morbi vulputate non diam at
consequat. Donec vitae sem eu arcu auctor scelerisque vel in turpis.
</p>
`
export const ProseBasic = () => {
return <Prose dangerouslySetInnerHTML={{ __html: content }} />
}
Anatomy
import { Prose } from '#components/ui/prose'<Prose>
<div dangerouslySetInnerHTML={{ __html: '...' }} />
</Prose>Usage
Prose is a styled div that targets the raw HTML elements inside it —
headings, paragraphs, lists, tables, code, blockquotes and more. Use it when you
render content you don't control, like markdown, a rich text editor value, or
HTML from a CMS, where you can't attach Chakra components to each node.
Content is constrained to 65ch by default for comfortable reading. Override it
with the maxWidth prop when you need a wider column.
Examples
Sizes
Use the size prop to change the base font size of the content. All spacing is
defined in em, so it scales with the size.
size: md
Title Heading 2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi at dolor nec ex rutrum semper. Praesent ultricies purus eget lectus tristique egestas ac in lacus.
size: lg
Title Heading 2
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi at dolor nec ex rutrum semper. Praesent ultricies purus eget lectus tristique egestas ac in lacus.
import { For, Stack, Text } from '@chakra-ui/react'
import { Prose } from '#components/ui/prose'
export const ProseWithSizes = () => {
return (
<Stack gap="10">
<For each={['md', 'lg'] as const}>
{(size) => (
<Stack key={size}>
<Text textStyle="sm" color="fg.muted">
size: {size}
</Text>
<Prose size={size}>
<h2>Title Heading 2</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi
at dolor nec ex rutrum semper. Praesent ultricies purus eget
lectus tristique egestas ac in lacus.
</p>
</Prose>
</Stack>
)}
</For>
</Stack>
)
}
Blockquote
Blockquote elements are styled to match the design language of the Blockquote component.
Blockquotes
This is a good looking blockquote!
And it can span into multiple lines:
Fusce placerat ipsum vel sollicitudin imperdiet. Morbi vulputate non diam at consequat. Donec vitae sem eu arcu auctor scelerisque vel in turpis.
There's also strong, b and em support as well.
import { Prose } from '#components/ui/prose'
// Used for syntax highlighting
const html = String.raw
const content = html`
<h3>Blockquotes</h3>
<blockquote>This is a good looking blockquote!</blockquote>
<p>And it can span into multiple lines:</p>
<blockquote>
Fusce placerat ipsum vel sollicitudin imperdiet. Morbi vulputate non diam at
consequat. Donec vitae sem eu arcu auctor scelerisque vel in turpis.
</blockquote>
<p>
There's also <strong>strong</strong>, <b>b</b> and <em>em</em> support
as well.
</p>
`
export const ProseWithBlockquote = () => {
return <Prose dangerouslySetInnerHTML={{ __html: content }} />
}
List
List elements are styled to match the design language of the List component.
Lists
Let's look at some unordered lists. Things to buy:
- Milk
- Eggs
- Bread
- Saas UI Pro license
And some ordered lists. Things to do:
- Pay the bills
- Walk the dog
- Take out trash
import { Prose } from '#components/ui/prose'
// Used for syntax highlighting
const html = String.raw
const content = html`
<h3>Lists</h3>
<p>Let's look at some unordered lists. Things to buy:</p>
<ul>
<li>Milk</li>
<li>Eggs</li>
<li>Bread</li>
<li>Saas UI Pro license</li>
</ul>
<p>And some ordered lists. Things to do:</p>
<ol>
<li>Pay the bills</li>
<li>Walk the dog</li>
<li>Take out trash</li>
</ol>
`
export const ProseWithList = () => {
return <Prose dangerouslySetInnerHTML={{ __html: content }} />
}
Table
Table elements are styled to match the design language of the Table component.
Tables
| Plan | Seats | Price |
|---|---|---|
| Starter | 3 | $0 |
| Team | 25 | $49 |
| Enterprise | Unlimited | Custom |
import { Prose } from '#components/ui/prose'
// Used for syntax highlighting
const html = String.raw
const content = html`
<h3>Tables</h3>
<table>
<thead>
<tr>
<th>Plan</th>
<th>Seats</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Starter</td>
<td>3</td>
<td>$0</td>
</tr>
<tr>
<td>Team</td>
<td>25</td>
<td>$49</td>
</tr>
<tr>
<td>Enterprise</td>
<td>Unlimited</td>
<td>Custom</td>
</tr>
</tbody>
</table>
`
export const ProseWithTable = () => {
return <Prose dangerouslySetInnerHTML={{ __html: content }} />
}
React Markdown
Prose pairs well with a markdown renderer. Here's an example using
react-markdown.
Heading
Based on your Saas UI plan. So click here to confirm your plan.
- first item
- second item
- third item
import { Prose } from '#components/ui/prose'
import Markdown from 'react-markdown'
const content = `
## Heading
Based on your Saas UI plan. So [click here](https://saas-ui.dev) to confirm your plan.
- first item
- second item
- third item
`
export const ProseWithReactMarkdown = () => {
return (
<Prose>
<Markdown>{content}</Markdown>
</Prose>
)
}
Props
| Prop | Default | Type |
|---|---|---|
size | 'md' | 'md' | 'lg'The base font size of the content. Spacing is defined in em, so it scales along. |
maxWidth | '65ch' | SystemStyleObject['maxWidth']The maximum width of the content column. |
children | React.ReactNodeThe HTML content to style. Can also be set with dangerouslySetInnerHTML. | |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |