Vue Chat - Markdown Support
You often need to convert Chat messages from Markdown to HTML since Chat supports HTML. This is useful when using OpenAI or supporting Markdown in user inputs.
To support Markdown, use a third-party library for conversion. The unified + remark + rehype stack is a good option, as shown in our AI integration demo:
This powerful stack supports various extensions and allows control over different conversion stages. For a simpler, lightweight solution, you can use libraries such as micromark.
Regardless of the library choice, convert the message text within the messageTemplate property:
jQuery
index.html
index.js
<script type="module">
import {
micromark
} from 'https://esm.sh/micromark@3?bundle';
window.micromark = micromark;
</script>
<div id="chat"></div>
$(() => {
const chat = $("#chat")
.dxChat({
onMessageEntered: ({ component, message }) => {
component.renderMessage(message);
},
messageTemplate: (e, element) => {
const htmlText = $(micromark(e.message.text)).html();
$("<div>").html(htmlText).appendTo(element);
}
})
.dxChat("instance");
});Angular
app.component.html
app.component.ts
<dx-chat
[items]="messages"
(onMessageEntered)="onMessageEntered($event)"
messageTemplate="messageTemplate"
>
<div *dxTemplate="let data of 'messageTemplate'">
<div [innerHTML]="convertToHtml(data.message.text)"></div>
</div>
</dx-chat>
import { DxChatTypes } from "devextreme-angular/ui/chat";
import { micromark } from 'micromark';
// ...
export class AppComponent {
messages: DxChatTypes.Message[] = [];
onMessageEntered(e: DxChatTypes.MessageEnteredEvent) {
if (e.message) {
this.messages = [...this.messages, e.message];
}
}
convertToHtml(text: string) {
let html = micromark(text);
return html.replace(/^<p>/, '').replace(/<\/p>$/, '');
}
}Vue
App.vue
<template>
<DxChat
:items="messages"
@message-entered="onMessageEntered"
message-template="message"
>
<template #message="{ data }">
<div v-html="convertToHtml(data.message.text)"></div>
</template>
</DxChat>
</template>
<script setup lang="ts">
import { DxChat } from 'devextreme-vue';
import type { DxChatTypes } from 'devextreme-vue/cjs/chat';
import { micromark } from 'micromark';
import { ref, type Ref } from 'vue';
const messages: Ref<DxChatTypes.Message[]> = ref([]);
const onMessageEntered = (e: DxChatTypes.MessageEnteredEvent) => {
if (e.message) {
messages.value = [...messages.value, e.message];
}
}
const convertToHtml = (text: string) => {
let html = micromark(text);
return html.replace(/^<p>/, '').replace(/<\/p>$/, '');
}
</script>React
App.tsx
import { Chat } from 'devextreme-react';
import { ChatTypes } from 'devextreme-react/cjs/chat';
import 'devextreme/dist/css/dx.light.css'
import { useCallback, useState } from 'react';
import HTMLReactParser from 'html-react-parser';
import { micromark } from 'micromark';
const convertToHtml = (text: string) => {
let html = micromark(text);
return html.replace(/^<p>/, '').replace(/<\/p>$/, '');
}
const messageRender = (data: ChatTypes.MessageTemplateData) => {
return (HTMLReactParser(convertToHtml(data.message!.text!)));
}
export default function App() {
const [messages, setMessages] = useState<ChatTypes.Message[]>([]);
const onMessageEntered = useCallback((e: ChatTypes.MessageEnteredEvent) => {
setMessages((prevMessages) => [...prevMessages, e.message!]);
}, []);
return(
<Chat
items={messages}
onMessageEntered={onMessageEntered}
messageRender={messageRender}
/>
);
}
Feel free to share topic-related thoughts here.
If you have technical questions, please create a support ticket in the DevExpress Support Center.
Thank you for the feedback!
If you have technical questions, please create a support ticket in the DevExpress Support Center.