Skip to content

Latest commit

 

History

History
196 lines (161 loc) · 5.51 KB

markdown-messages.mdx

File metadata and controls

196 lines (161 loc) · 5.51 KB
title description
Render Markdown Messages
Learn how to render markdown messages using the `useLopusChat` hook

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.

Prequisites

  1. Ensure you have a React application setup
  2. Complete the quickstart guide
  3. Install react-markdown package
```bash npm npm install react-markdown ```
pnpm add react-markdown
yarn add react-markdown
bun add react-markdown
deno install npm:react-markdown@latest

Upgrade Your Message Component with ReactMarkdown

Return messages inside a ReactMarkdown component instead of a div:

```tsx Message.tsx import React, { ReactElement, JSXElementConstructor } from 'react'; import ReactMarkdown from 'react-markdown';

export function Message({ message }: MessageProps) { return ( <div className={mb-2 p-2 rounded ${ message.sender === 'USER' ? 'bg-blue-600 text-white ml-auto' : 'bg-gray-200 text-black' } max-w-[80%]} > {(() => { switch (typeof message.content) { case 'string': return ( {message.content} ); case 'object': if (React.isValidElement(message.content)) { return message.content; } return

{JSON.stringify(message.content)}
; default: return ( {String(message.content)} ); } })()} ); }

interface Message { content: string | ReactElement<unknown, string | JSXElementConstructor> | Record<string, unknown>; sender: 'USER' | 'ASSISTANT'; }

interface MessageProps { message: Message; }


```tsx MessageList.tsx
import React, { ReactElement, JSXElementConstructor } from 'react';
import { Message } from './Message';

export function MessageList({ messages, isLoading }: MessageListProps) {
  return (
    <div className="flex-1 overflow-auto mb-4">
      {messages.map((message, index) => (
        <Message key={index} message={message} />
      ))}
      {isLoading && <div className="text-gray-500">Loading...</div>}
    </div>
  );
} 

interface Message {
  content: string | ReactElement<unknown, string | JSXElementConstructor<any>> | Record<string, unknown>;
  sender: 'USER' | 'ASSISTANT';
}

interface MessageListProps {
  messages: Message[];
  isLoading: boolean;
}


import React, { useState } from 'react';

export function ChatInput({ onSubmit, isLoading }: ChatInputProps) {
  const [input, setInput] = useState('');

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!input.trim()) return;
    
    try {
      await onSubmit(input);
      setInput('');
    } catch (error) {
      console.error('Failed to send message:', error);
    }
  };

  return (
    <form onSubmit={handleSubmit} className="flex gap-2">
      <input
        type="text"
        value={input}
        onChange={(e) => setInput(e.target.value)}
        className="flex-1 p-2 border rounded text-black placeholder-zinc-400 border-zinc-600 focus:outline-none focus:border-blue-500"
        placeholder="Type your message..."
      />
      <button
        type="submit"
        disabled={isLoading}
        className="px-4 py-2 bg-blue-600 text-white rounded disabled:bg-zinc-600 disabled:text-zinc-400 hover:bg-blue-700"
      >
        Send
      </button>
    </form>
  );
} 

interface ChatInputProps {
  onSubmit: (message: string) => Promise<void>;
  isLoading: boolean;
}
'use client';
import { useLopusChat } from "lopus-ai";
import { MessageList } from './components/MessageList';
import { ChatInput } from './components/ChatInput';

export default function ChatComponent() {
  const { messages, sendQuery, isLoading } = useLopusChat({
    apiKey: 'your_api_key_here',
  });

  return (
    <div className="flex flex-col h-screen p-4 bg-gray-100">
      <MessageList messages={messages} isLoading={isLoading} />
      <ChatInput onSubmit={sendQuery} isLoading={isLoading} />
    </div>
  );
}

Your Lopus Chat Component can now render markdown messages:

![](/images/lopus_chat_component.png)

Best Practices

  1. Type Safety: Use type guards like isReceivedMessage to safely handle different message types.
  2. Error Handling: Wrap sendQuery and sendSubmission calls in try-catch blocks to manage errors effectively.
  3. Component Handling: For messages containing components, ensure they are rendered correctly.
  4. Cleanup: The hook manages cleanup automatically, but ensure to remove any custom message handlers if added.

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.