Basic Usage
GptMarkdown takes a single required positional argument — the markdown string. Everything else is optional.
Minimal example
main.dart
1import 'package:gpt_markdown/gpt_markdown.dart';
2
3// Minimal — just pass your string
4GptMarkdown('**Hello!** Inline math: \\( E = mc^2 \\)')Inside a Scaffold
Wrap in SingleChildScrollView when content may overflow the screen.
markdown_screen.dart
1import 'package:flutter/material.dart';
2import 'package:gpt_markdown/gpt_markdown.dart';
3
4class MarkdownScreen extends StatelessWidget {
5 final String content;
6 const MarkdownScreen({super.key, required this.content});
7
8
9 Widget build(BuildContext context) {
10 return Scaffold(
11 appBar: AppBar(title: const Text('Response')),
12 body: SingleChildScrollView(
13 padding: const EdgeInsets.all(16),
14 child: GptMarkdown(content),
15 ),
16 );
17 }
18}Streaming AI output
Append chunks to a string buffer and pass it directly — the widget re-renders on each update.
streaming_chat.dart
1import 'package:flutter/material.dart';
2import 'package:gpt_markdown/gpt_markdown.dart';
3
4class StreamingChat extends StatefulWidget {
5 const StreamingChat({super.key});
6
7
8 State<StreamingChat> createState() => _StreamingChatState();
9}
10
11class _StreamingChatState extends State<StreamingChat> {
12 String _buffer = '';
13
14 void _onChunk(String chunk) {
15 setState(() => _buffer += chunk);
16 }
17
18
19 Widget build(BuildContext context) {
20 return SingleChildScrollView(
21 padding: const EdgeInsets.all(16),
22 child: GptMarkdown(_buffer),
23 );
24 }
25}Handling link taps
Use onLinkTap to intercept clicks on Markdown links.
example.dart
1GptMarkdown(
2 content,
3 onLinkTap: (url, title) {
4 launchUrl(Uri.parse(url));
5 },
6)Text style & direction
Control the base text style, RTL support, and text alignment.
example.dart
1GptMarkdown(
2 content,
3 style: const TextStyle(
4 fontSize: 16,
5 height: 1.6,
6 color: Colors.black87,
7 ),
8 textDirection: TextDirection.rtl, // RTL language support
9 textAlign: TextAlign.justify,
10)Custom code block renderer
Replace the built-in code block with your own widget via codeBuilder.
example.dart
1GptMarkdown(
2 content,
3 codeBuilder: (context, name, code, closed) {
4 return MyCustomCodeBlock(
5 language: name,
6 code: code,
7 isClosed: closed,
8 );
9 },
10)Custom LaTeX renderer
Override the LaTeX renderer and optionally enable $...$ dollar-sign syntax.
example.dart
1GptMarkdown(
2 content,
3 useDollarSignsForLatex: true, // enables $...$ and $$...$$ syntax
4 latexBuilder: (context, latex, textStyle, inline) {
5 return MyLatexRenderer(
6 equation: latex,
7 inline: inline,
8 );
9 },
10)Custom link renderer
example.dart
1GptMarkdown(
2 content,
3 linkBuilder: (context, text, href, title) {
4 return InkWell(
5 onTap: () => launchUrl(Uri.parse(href)),
6 child: Text(
7 text,
8 style: const TextStyle(
9 color: Colors.blue,
10 decoration: TextDecoration.underline,
11 ),
12 ),
13 );
14 },
15)Custom image renderer
example.dart
1GptMarkdown(
2 content,
3 imageBuilder: (context, url, alt) {
4 return ClipRRect(
5 borderRadius: BorderRadius.circular(8),
6 child: Image.network(url, semanticLabel: alt),
7 );
8 },
9)Best Practices
- Always wrap
GPTMarkdownin aSingleChildScrollViewto handle overflow content. - Consider using
FutureBuilderorStreamBuilderwhen loading markdown content from an API or database. - Implement error handling for cases where the markdown content might be malformed.
- Test your implementation with different types of markdown content to ensure consistent rendering.
- Use the package's theming options to match your app's design system.
Next Steps
Now that you understand the basics of using GPT Markdown, you can explore its more advanced features: