Skip to content

Commit 52691a2

Browse files
Quantstruct Bot: Add quickstart, markdown messages, and message types docs
1 parent 0b4b24f commit 52691a2

11 files changed

+584
-311
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,7 @@ Install our Github App to auto propagate changes from your repo to your deployme
3030

3131
- Mintlify dev isn't running - Run `mintlify install` it'll re-install dependencies.
3232
- Page loads as a 404 - Make sure you are running in a folder with `mint.json`
33+
34+
## Customizations
35+
36+
Mintlify allows you to customize the look and feel of your documentation.

development.mdx

Lines changed: 0 additions & 106 deletions
This file was deleted.

favicon.png

483 KB
Loading

images/lopus_authentication.png

31.8 KB
Loading

images/lopus_chat_component.png

71 KB
Loading

introduction.mdx

Lines changed: 0 additions & 71 deletions
This file was deleted.

logo/lopus-ai-logo.avif

9.71 KB
Binary file not shown.

markdown-messages.mdx

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
---
2+
title: Render Markdown Messages
3+
description: Learn how to render markdown messages using the `useLopusChat` hook
4+
---
5+
6+
This guide will walk you through the process of rendering markdown messages in your React application using the `useLopusChat` hook. We'll cover the setup, rendering logic, and best practices to ensure a smooth integration.
7+
8+
## Prequisites
9+
10+
1. Ensure you have a React application setup
11+
2. Complete the [quickstart guide](/quickstart)
12+
2. Install `react-markdown` package
13+
14+
<CodeGroup>
15+
```bash npm
16+
npm install react-markdown
17+
```
18+
19+
```bash pnpm
20+
pnpm add react-markdown
21+
```
22+
23+
```bash yarn
24+
yarn add react-markdown
25+
```
26+
27+
```bash bun
28+
bun add react-markdown
29+
```
30+
31+
```bash deno
32+
deno install npm:react-markdown@latest
33+
```
34+
</CodeGroup>
35+
36+
## Upgrade Your Message Component with `ReactMarkdown`
37+
38+
Return messages inside a `ReactMarkdown` component instead of a `div`:
39+
40+
<CodeGroup>
41+
```tsx Message.tsx
42+
import React, { ReactElement, JSXElementConstructor } from 'react';
43+
import ReactMarkdown from 'react-markdown';
44+
45+
export function Message({ message }: MessageProps) {
46+
return (
47+
<div
48+
className={`mb-2 p-2 rounded ${
49+
message.sender === 'USER'
50+
? 'bg-blue-600 text-white ml-auto'
51+
: 'bg-gray-200 text-black'
52+
} max-w-[80%]`}
53+
>
54+
{(() => {
55+
switch (typeof message.content) {
56+
case 'string':
57+
return (
58+
<ReactMarkdown className="prose max-w-none">
59+
{message.content}
60+
</ReactMarkdown>
61+
);
62+
case 'object':
63+
if (React.isValidElement(message.content)) {
64+
return message.content;
65+
}
66+
return <div>{JSON.stringify(message.content)}</div>;
67+
default:
68+
return (
69+
<ReactMarkdown className="prose max-w-none">
70+
{String(message.content)}
71+
</ReactMarkdown>
72+
);
73+
}
74+
})()}
75+
</div>
76+
);
77+
}
78+
79+
interface Message {
80+
content: string | ReactElement<unknown, string | JSXElementConstructor<any>> | Record<string, unknown>;
81+
sender: 'USER' | 'ASSISTANT';
82+
}
83+
84+
interface MessageProps {
85+
message: Message;
86+
}
87+
```
88+
89+
```tsx MessageList.tsx
90+
import React, { ReactElement, JSXElementConstructor } from 'react';
91+
import { Message } from './Message';
92+
93+
export function MessageList({ messages, isLoading }: MessageListProps) {
94+
return (
95+
<div className="flex-1 overflow-auto mb-4">
96+
{messages.map((message, index) => (
97+
<Message key={index} message={message} />
98+
))}
99+
{isLoading && <div className="text-gray-500">Loading...</div>}
100+
</div>
101+
);
102+
}
103+
104+
interface Message {
105+
content: string | ReactElement<unknown, string | JSXElementConstructor<any>> | Record<string, unknown>;
106+
sender: 'USER' | 'ASSISTANT';
107+
}
108+
109+
interface MessageListProps {
110+
messages: Message[];
111+
isLoading: boolean;
112+
}
113+
114+
115+
```
116+
117+
```tsx ChatInput.tsx
118+
import React, { useState } from 'react';
119+
120+
export function ChatInput({ onSubmit, isLoading }: ChatInputProps) {
121+
const [input, setInput] = useState('');
122+
123+
const handleSubmit = async (e: React.FormEvent) => {
124+
e.preventDefault();
125+
if (!input.trim()) return;
126+
127+
try {
128+
await onSubmit(input);
129+
setInput('');
130+
} catch (error) {
131+
console.error('Failed to send message:', error);
132+
}
133+
};
134+
135+
return (
136+
<form onSubmit={handleSubmit} className="flex gap-2">
137+
<input
138+
type="text"
139+
value={input}
140+
onChange={(e) => setInput(e.target.value)}
141+
className="flex-1 p-2 border rounded text-black placeholder-zinc-400 border-zinc-600 focus:outline-none focus:border-blue-500"
142+
placeholder="Type your message..."
143+
/>
144+
<button
145+
type="submit"
146+
disabled={isLoading}
147+
className="px-4 py-2 bg-blue-600 text-white rounded disabled:bg-zinc-600 disabled:text-zinc-400 hover:bg-blue-700"
148+
>
149+
Send
150+
</button>
151+
</form>
152+
);
153+
}
154+
155+
interface ChatInputProps {
156+
onSubmit: (message: string) => Promise<void>;
157+
isLoading: boolean;
158+
}
159+
```
160+
161+
```tsx ChatComponent.tsx
162+
'use client';
163+
import { useLopusChat } from "lopus-ai";
164+
import { MessageList } from './components/MessageList';
165+
import { ChatInput } from './components/ChatInput';
166+
167+
export default function ChatComponent() {
168+
const { messages, sendQuery, isLoading } = useLopusChat({
169+
apiKey: 'your_api_key_here',
170+
});
171+
172+
return (
173+
<div className="flex flex-col h-screen p-4 bg-gray-100">
174+
<MessageList messages={messages} isLoading={isLoading} />
175+
<ChatInput onSubmit={sendQuery} isLoading={isLoading} />
176+
</div>
177+
);
178+
}
179+
```
180+
</CodeGroup>
181+
182+
Your Lopus Chat Component can now render markdown messages:
183+
184+
<Frame as="div" caption="Lopus Chat Component">
185+
![](/images/lopus_chat_component.png)
186+
</Frame>
187+
188+
189+
# Best Practices
190+
191+
1. **Type Safety:** Use type guards like `isReceivedMessage` to safely handle different message types.
192+
2. **Error Handling:** Wrap `sendQuery` and `sendSubmission` calls in try-catch blocks to manage errors effectively.
193+
3. **Component Handling:** For messages containing components, ensure they are rendered correctly.
194+
4. **Cleanup:** The hook manages cleanup automatically, but ensure to remove any custom message handlers if added.
195+
196+
By following these steps, you can effectively render markdown messages in your React application using the `useLopusChat` hook. This setup allows for a rich, interactive chat experience.

0 commit comments

Comments
 (0)