Keyboard Shortcuts

j / kScroll down / up
ggScroll to top
GScroll to bottom
K / /Open search
?Show this help
EscClose search / help
n / NNext / previous section
hGo to landing
dGo to docs
:Command mode — type section name

Press ? or Esc to close

Systems

Rich Text

Server content is authored in TipTap JSON. The app renders it read-only with TipTapRenderer — there is no editor input widget, only a renderer.

The model

Content arrives as a list of TipTapNode objects, each with a type and optional marks (bold, italic, link, etc.).

lib/config/ui/tiptap/tiptap_renderer.dart
class TipTapNode {
  final String type;          // paragraph, heading, image, codeBlock, ...
  final Map<String, dynamic>? attrs;
  final List<TipTapMark>? marks;
  final List<TipTapNode>? content;
}

Rendering

TipTapRenderer walks the node tree and switches on type. Images use CachedNetworkImage with a custom cache manager; mentions and links are tappable.

lib/config/ui/tiptap/tiptap_renderer.dart
Widget _renderNode(TipTapNode node) {
  switch (node.type) {
    case 'paragraph':
      return _renderParagraph(node);
    case 'heading':
      return _renderHeading(node);
    case 'image':
      return AppImage(src: node.attrs!['src'] as String);
    case 'codeBlock':
      return _CodeBlock(node);
    case 'bulletList':
    case 'orderedList':
      return _renderList(node);
    default:
      return const SizedBox.shrink();
  }
}

Usage

lib/features/article/presentation/widgets/article_body.dart
TipTapRenderer(nodes: article.content)
Scope: rendering only. Authoring happens in the web CMS; the app never edits TipTap JSON.
sam's arch — A Pragmatic Flutter Architecture