Content

Pass markdown, HTML, or JSON content to the Document component.

Overview

The Document component accepts content in three formats: Markdown (default), HTML, or TipTap JSON. Markdown is the default as it's the most common and readable format.

// Markdown (default)
<Document content="# Hello World\n\nThis is **bold** text.">
  <Document.Viewer />
</Document>

// HTML
<Document content="<h1>Hello World</h1><p>This is <strong>bold</strong> text.</p>" contentType="html">
  <Document.Viewer />
</Document>

// JSON (TipTap's native format)
<Document content={jsonContent} contentType="json">
  <Document.Viewer />
</Document>

Markdown (Default)

Pass a markdown string directly. The component uses TipTap's official Markdown extension (powered by MarkedJS) to parse and render the content.

const markdown = `
# Analysis Report

This document contains **important findings** from our investigation.

## Key Points

- First observation with *emphasis*
- Second point with \`inline code\`
- Third point linking to [documentation](https://example.com)

> This is a blockquote highlighting a key statement.

### Code Example

\`\`\`typescript
function analyzeData(input: string): Result {
  return process(input);
}
\`\`\`

| Column A | Column B | Column C |
|----------|----------|----------|
| Data 1   | Data 2   | Data 3   |
| Data 4   | Data 5   | Data 6   |
`;

<Document content={markdown}>
  <Document.Viewer />
</Document>;

Supported Markdown Features

All standard Markdown syntax is supported:

FeatureSyntax
Headings# H1 through ###### H6
Bold**text** or __text__
Italic*text* or _text_
Strikethrough~~text~~
Inline code`code`
Links[text](url)
Images![alt](url)
Blockquotes> quote
Bullet lists- item or * item
Numbered lists1. item
Task lists- [ ] task or - [x] done
Code blocks``` fenced blocks
TablesGFM table syntax
Horizontal rules--- or ***

HTML

For HTML content, set contentType="html":

const htmlContent = `
<h1>Document Title</h1>
<p>Paragraph with <strong>bold</strong> and <em>italic</em> text.</p>
<ul>
  <li>List item one</li>
  <li>List item two</li>
</ul>
`;

<Document content={htmlContent} contentType="html">
  <Document.Viewer />
</Document>;

JSON (TipTap Format)

For programmatic content generation or when you need precise control, use TipTap's JSON format with contentType="json":

const jsonContent = {
  type: "doc",
  content: [
    {
      type: "heading",
      attrs: { level: 1 },
      content: [{ type: "text", text: "My Document" }],
    },
    {
      type: "paragraph",
      content: [
        { type: "text", text: "Regular text " },
        { type: "text", text: "bold text", marks: [{ type: "bold" }] },
      ],
    },
  ],
};

<Document content={jsonContent} contentType="json">
  <Document.Viewer />
</Document>;

Node Types

TypeHTMLNotes
doc-Root node (required)
text-Leaf node, can have marks
paragraph<p>Basic text block
heading<h1>-<h6>attrs: { level: 1-6 }
bulletList<ul>Unordered list
orderedList<ol>Numbered list
listItem<li>List item
blockquote<blockquote>Quote block
codeBlock<pre><code>Code block
horizontalRule<hr>Divider
hardBreak<br>Line break
table<table>Table container
tableRow<tr>Table row
tableHeader<th>Header cell
tableCell<td>Data cell
taskList<ul>Task list container
taskItem<li>Checkbox item

Marks

Inline formatting applied to text nodes:

{
  type: "text",
  text: "formatted text",
  marks: [
    { type: "bold" },
    { type: "italic" },
    { type: "strike" },
    { type: "code" },
    { type: "link", attrs: { href: "https://example.com" } },
  ]
}

Converting Between Formats

If you need to transform content between formats, you can access the TipTap editor instance:

import { useDocument } from "@tilt-legal/cubitt-components/document";

function MyComponent() {
  const { editor } = useDocument();

  // Get content as different formats
  const json = editor?.getJSON();
  const html = editor?.getHTML();
  const markdown = editor?.getMarkdown(); // Requires markdown extension

  return null;
}

Styling

Typography

Document.Viewer uses Tailwind Typography. Customize with prose modifiers:

<Document.Viewer className="prose-lg prose-headings:text-primary" />
ModifierEffect
prose-sm / prose-lgText size
prose-headings:text-primaryHeading color
prose-a:text-blue-600Link color
prose-code:bg-mutedInline code background

Highlights

Extensions like annotations render highlights as <mark> elements. Style them with Tailwind arbitrary selectors:

<Document.Viewer
  className="
    [&_mark[data-annotation-id]]:bg-yellow-100/20
    [&_mark[data-annotation-id]]:border-b
    [&_mark[data-annotation-id]]:border-dashed
    [&_mark[data-annotation-id]]:border-yellow-400/50
    [&_mark[data-annotation-id][data-active]]:bg-yellow-200/50
    [&_mark[data-annotation-id][data-active]]:border-solid
  "
/>
SelectorDescription
mark[data-annotation-id]All annotation marks
mark[data-annotation-id][data-active]Active (selected)

On this page