Skip to content

XMarkdown Rendering Component ๐Ÿ“œ โ€‹

Introduction โ€‹

The XMarkdown component has built-in basic styles such as inline code, code blocks, mathematical formula functions (inline/block), mermaid charts, etc.

๐Ÿ’Œ Info

โš ๏ธ In this development documentation, some style demonstrations may not be very good, but it should not affect the integrated usage. If there are integration or usage issues, you can join ๐Ÿ‘‰Community Group to get the latest technical support.

๐Ÿ“Œ Warning

All h function demonstrations in the documentation demos mean you can use the h function for component rendering, or use custom Vue components for rendering.

For example:

vue
<!-- This is the h function demonstration in the documentation -->
(props:any) => {return h('div', props, {default: () => 'Test'})}

๐Ÿ™Š Actually it can be written as a custom component:

vue
<!-- Import your Vue component from external -->
import SelfButton from './SelfButton.vue'

<!-- Custom component rendering -->
<!-- SelfButton is your custom Vue component above -->
<!-- selfProps are custom properties, receiving props -->
(props:any) => {return h(SelfButton, { selfProps: props })}

๐Ÿ’Ÿ In your custom component you can get props like this:

vue
<!-- SelfButton.vue -->

<script setup lang="ts">
const props = defineProps({
  selfProps: { type: Object, default: () => ({}) }
});

conslog(props.selfProps); // Check the props you get in console
</script>

<template>
  <!-- You can get props properties for some custom rendering -->
  <button>{{ selfProps.text }}</button>
</template>

Code Demo โ€‹

Basic Usage โ€‹

Quickly render a basic Markdown text. Built-in basic styles such as inline code, code blocks, mathematical formula functions (inline/block), mermaid charts, etc.

๐Ÿ“Œ Warning

Supports incremental updates, you can view node update changes in the console. The following code example demonstrates the incremental update effect, simulating the logic of streaming character reception.

Set Default Highlight/Dark Mode โ€‹

Set code block highlighting through the default-theme-mode property, whether the default is highlight theme or dark theme.

๐Ÿ’Œ Info

The demonstration here in the documentation may be affected by vitePress styles, please check the effect yourself. If the property is invalid in your project, you can join ๐Ÿ‘‰Community Group to provide feedback.

Built-in Shiki Themes โ€‹

Code block highlighting has multiple built-in themes to choose from.

Set code block themes through the themes property. This property is an object with highlight and dark theme properties, with values being built-in theme IDs.

ts
themes: {
  light: 'vitesse-light'; // Light theme (component default theme)
  dark: 'vitesse-dark'; // Dark theme (component default theme)
}

We have built-in shiki styles, you can view them at shiki-theme.

๐Ÿ“Œ Warning

After resetting the theme, you may need to refresh the page for it to take effect. Below lists all built-in shiki styles and their corresponding theme IDs. If you're in a ts project, you should get type inference hints for built-in style themes during development.

๐Ÿ’View all theme ID reference table
Name Chinese Translation Corresponding Value (Theme ID)
Andromeeda Andromeda andromeeda
Aurora X Aurora X aurora-x
Ayu Dark Ayu Dark ayu-dark
Catppuccin Frappรฉ Catppuccin Frappรฉ catppuccin-frappe
Catppuccin Latte Catppuccin Latte catppuccin-latte
Catppuccin Macchiato Catppuccin Macchiato catppuccin-macchiato
Catppuccin Mocha Catppuccin Mocha catppuccin-mocha
Dark Plus Dark Plus dark-plus
Dracula Theme Dracula Theme dracula
Dracula Theme Soft Dracula Soft Theme dracula-soft
Everforest Dark Everforest Dark everforest-dark
Everforest Light Everforest Light everforest-light
GitHub Dark GitHub Dark github-dark
GitHub Dark Default GitHub Dark Default github-dark-default
GitHub Dark Dimmed GitHub Dark Dimmed github-dark-dimmed
GitHub Dark High Contrast GitHub Dark High Contrast github-dark-high-contrast
GitHub Light GitHub Light github-light
GitHub Light Default GitHub Light Default github-light-default
GitHub Light High Contrast GitHub Light High Contrast github-light-high-contrast
Gruvbox Dark Hard Gruvbox Dark Hard gruvbox-dark-hard
Gruvbox Dark Medium Gruvbox Dark Medium gruvbox-dark-medium
Gruvbox Dark Soft Gruvbox Dark Soft gruvbox-dark-soft
Gruvbox Light Hard Gruvbox Light Hard gruvbox-light-hard
Gruvbox Light Medium Gruvbox Light Medium gruvbox-light-medium
Gruvbox Light Soft Gruvbox Light Soft gruvbox-light-soft
Houston Houston houston
Kanagawa Dragon Kanagawa Dragon kanagawa-dragon
Kanagawa Lotus Kanagawa Lotus kanagawa-lotus
Kanagawa Wave Kanagawa Wave kanagawa-wave
LaserWave LaserWave laserwave
Light Plus Light Plus light-plus
Material Theme Material Theme material-theme
Material Theme Darker Material Theme Darker material-theme-darker
Material Theme Lighter Material Theme Lighter material-theme-lighter
Material Theme Ocean Material Theme Ocean material-theme-ocean
Material Theme Palenight Material Theme Palenight material-theme-palenight
Min Dark Min Dark min-dark
Min Light Min Light min-light
Monokai Monokai monokai
Night Owl Night Owl night-owl
Nord Nord nord
One Dark Pro One Dark Pro one-dark-pro
One Light One Light one-light
Plastic Plastic plastic
Poimandres Poimandres poimandres
Red Red Theme red
Rosรฉ Pine Rosรฉ Pine rose-pine
Rosรฉ Pine Dawn Rosรฉ Pine Dawn rose-pine-dawn
Rosรฉ Pine Moon Rosรฉ Pine Moon rose-pine-moon
Slack Dark Slack Dark slack-dark
Slack Ochin Slack Ochin slack-ochin
Snazzy Light Snazzy Light snazzy-light
Solarized Dark Solarized Dark solarized-dark
Solarized Light Solarized Light solarized-light
Synthwave '84 Synthwave '84 synthwave-84
Tokyo Night Tokyo Night tokyo-night
Vesper Vesper vesper
Vitesse Black Vitesse Black vitesse-black
Vitesse Dark Vitesse Dark vitesse-dark
Vitesse Light Vitesse Light vitesse-light

Define Code Block Highlight Style Separately โ€‹

Through the color-replacements property, you can individually control code colors under a specific theme.

๐Ÿ“Œ Warning

Note: Color keys must start with # and be in lowercase format, otherwise they won't take effect.

Theme IDs have corresponding color variables, which can be viewed in the console. We can replace the built-in color variables with custom colors.

Unified Style Override โ€‹

If you find that the component's built-in styles become strange when integrating this component, it may be because your project's built-in global styles conflict with some basic styles of this component. You can solve this problem by overriding styles.

๐Ÿ’Œ Info

Create a style file, for example: self-markdown.css, and add some custom style content:

css
.h1 {
  font-size: 24px;
  color: red;
  margin-bottom: 16px;
}

Import this file into your project, for example:

ts
import 'self-markdown.css'

If it's not overridden, it's likely because your style hierarchy is not sufficient, you can try style penetration

Below uses the github style file to uniformly override styles as an example

Github Style โ€‹

There are also many excellent authors in the market who have open-sourced their markdown styles. Here demonstrates a case of integrating and using github styles.

You can directly download the github-markdown.css file, or copy the style code to your own css file. Then reference it in your project.

๐Ÿ“Œ Warning

However, it's worth noting that generally such file styles are wrapped by the markdown-body class name. Just importing the style file is not enough. You may also need to add a class name to XMarkdown to make the styles take effect. This class name should be consistent with the outermost class name in the imported style file.

If you want to control code block highlighting styles separately, you can do this:

allowHtml โ€‹

Supports HTML tag rendering, use the allowHtml property to enable it, disabled by default.

enableLatex โ€‹

Supports LaTeX math formula rendering, use the enableLatex property to enable it, enabled by default.

enableBreaks โ€‹

Supports remark-breaks rendering, use the enableBreaks property to enable it, enabled by default.

Supports hard breaks without requiring spaces or escape characters (converts line breaks to <br>). Makes your content rendering more authentic.

Preview HTML Code Block โ€‹

Supports previewing HTML code blocks.

  • If you don't need it, you can hide the button by setting need-view-code-btn property to false. Default is true.
  • You can also use the secure-view-code property, set to true to enable html safe mode. Default is false. If enabled, script tags will not be rendered. Click to add to cart
  • You can also configure the popover through the viewCodeModalOptions property.
js
viewCodeModalOptions: {
  mode: 'drawer',
  customClass: '',
  dialogOptions: {
    closeOnClickModal: true,
    closeOnPressEscape: true
  },
  drawerOptions: {
    closeOnClickModal: true,
    closeOnPressEscape: true
  }
}
Property Value Description
mode 'drawer' Modal display form as drawer type
customClass '' No custom style class added
dialogOptions - Dialog mode configuration (currently not enabled)
- closeOnClickModal true Click outside dialog area to close (only effective in dialog mode)
- closeOnPressEscape true Press ESC key to close dialog (only effective in dialog mode)
drawerOptions - Drawer mode configuration (currently enabled)
- closeOnClickModal true Click outside drawer area to close
- closeOnPressEscape true Press ESC key to close drawer

๐Ÿ“Œ Warning

You can also control the top preview button style through custom top code blocks.

Or, go completely custom rendering, see details below Custom Code Block Top Rendering.

Custom Code Block Rendering โ€‹

Use the codeXRender property to customize code block rendering. This property accepts an object where the key is the code block language and the value is a function. The function parameter is the code block properties, and the return value is a VNode. This means you can use Vue's template syntax to render code blocks.

๐Ÿ“Œ Warning

This feature will intercept the code blocks you set. You can discuss the code block language with the backend, then return a corresponding VNode based on the language.

We will build a component library marketplace based on this component in the future. If you're interested in this, welcome to join ๐ŸฅฐCommunity Group, or add the author's contact information to build this marketplace project together. ๐ŸฅณStay tuned

The echarts component introduced in the example code. The source code is placed here for everyone's understanding. How to customize components, the echarts component implementation here is for example only. In actual use, please encapsulate according to your own backend data and requirements.

๐Ÿ’View echarts component code example
vue
<!-- echarts.vue -->

<script setup lang="ts">
import * as echarts from 'echarts';

// Keep original props.code logic, while adding optional configuration
const props = defineProps<{
  code: string; // Original JSON string configuration
  width?: string; // Optional: chart width
  height?: string; // Optional: chart height
  theme?: string; // Optional: chart theme
}>();

const refEle = ref<HTMLElement>();
let myChart: echarts.ECharts | null = null; // Chart instance reference

function parseEChartsOption(str: string): any {
  try {
    let cleanedStr = str.replace(/^option\s*=\s*/, '').replace(/;\s*$/, '');
    cleanedStr = cleanedStr.replace(/'/g, '"');
    cleanedStr = cleanedStr.replace(/(\w+)\s*:/g, '"$1":');
    return JSON.parse(cleanedStr);
  } catch (error) {
    console.error('Failed to parse ECharts option:', error);
    return null;
  }
}

// Core rendering logic (keep original parsing process)
function renderChart() {
  if (!refEle.value) return;

  try {
    // Parse JSON configuration (keep original logic)
    const cleanedStr = parseEChartsOption(props.code);

    // Initialize/update chart
    if (!myChart) {
      myChart = echarts.init(refEle.value, props.theme);
    }
    myChart.setOption(cleanedStr);
  } catch (error) {
    console.error('Chart configuration parsing failed:', error);
  }
}

// Window resize handling
function handleResize() {
  myChart?.resize();
}

// Destroy logic
function destroyChart() {
  if (myChart) {
    myChart.dispose(); // Release ECharts instance
    myChart = null;
  }
  window.removeEventListener('resize', handleResize);
}

// Initialize rendering
onMounted(() => {
  renderChart();
  window.addEventListener('resize', handleResize); // Add resize listener
});

// Listen to code changes for automatic updates (key optimization)
watch(
  () => props.code,
  () => {
    renderChart(); // Re-render when configuration changes
  }
);

// Clean up resources when unmounting
onUnmounted(() => {
  destroyChart();
});
</script>

<template>
  <div class="echarts-wrap">
    <span class="echarts-titlt">This is my custom echarts component</span>
    <div
      ref="refEle"
      :style="{
        height: height || '400px', // Optional height, default 400px
        width: width || '100%' // Optional width, default 100%
      }"
    />
  </div>
</template>

<style scoped lang="less">
.echarts-wrap {
  position: relative;

  .echarts-titlt {
    position: absolute;
    width: fit-content;
    margin-left: 20px;
    color: blue;
    font-size: 20px;
    font-weight: bold;
  }
}
</style>

Custom Code Block Top Rendering โ€‹

If you just want to modify the content of our built-in code block top, you can use codeXSlot. And we expose the built-in collapse, theme switch, and copy methods. You can retain default functionality while only changing styles.

Use the codeXSlot property to customize code block top slot rendering. This property accepts an object where the key is a fixed property of the CodeBlockHeaderExpose type, and the value is a function. The function parameter is the code block properties, and the return value is a VNode, meaning you can use Vue's template syntax to render the top of code blocks.

You can get props in your custom template, and props has the following properties (specific properties can be printed and viewed in the project):

  • isExpand: props.isExpand whether the code block is expanded.
  • toggleExpand: props.toggleExpand expand code block.
  • isDark: props.isDark.value get current code block theme.
  • toggleTheme: props.toggleTheme switch code block theme.
  • renderLines: props.renderLines get the content of this code block, you can use it to pass to the copy function.
  • copyCode: props.copyCode(props.renderLines) copy code block (requires parameter).
  • viewCode: props.viewCode(props.renderLines) trigger built-in preview HTML code block popover (requires parameter).
  • value: props.value get this code block type is 'Code' | 'Preview'.
  • changeSelectValue: props.changeSelectValue('Code' | 'Preview') switch code block type (requires parameter).
  • changeSelectValue: props.changeSelectValue('Code' | 'Preview') switch code block type (requires parameter).
  • content: props.content get this code block content.
  • close: props.close() close built-in preview HTML popover (no parameter needed).

The following are built-in properties that can be obtained in the mermaid code block header custom component props:

  • zoomIn: props.zoomIn zoom in.
  • zoomOut: props.zoomOut zoom out.
  • reset: props.reset return to initial position.
  • toggleCode: props.toggleCode switch display code.
  • download: props.download download image.
  • fullscreen: props.fullscreen enter fullscreen.
  • copyCode: props.copyCode copy code.
ts
// Type definition for this property
interface CodeBlockHeaderExpose {
  // Custom render the entire code block header
  codeHeader?: CodeBlockHeaderRenderer;
  // Custom render the left language identifier of the code block
  codeHeaderLanguage?: CodeBlockHeaderRenderer;
  // Custom render the right control button of the code block
  codeHeaderControl?: CodeBlockHeaderRenderer;
  // Custom render the title area of the right preview popover of the code block
  viewCodeHeader?: CodeBlockHeaderRenderer;
  // Custom render the content area of the right preview popover of the code block
  viewCodeContent?: CodeBlockHeaderRenderer;
  // Custom render the close button of the right preview popover of the code block
  viewCodeCloseBtn?: CodeBlockHeaderRenderer;
  // Custom render mermaid top slot
  codeMermaidHeaderControl?: CodeBlockHeaderRenderer;
}

Custom Attributes โ€‹

Use the customAttrs property to receive an object where the properties are tag names and the values are tag attributes. When a tag is matched, the corresponding attributes will be added to that tag.

Mermaid Operation Bar Configuration โ€‹

Use the mermaidConfig property to customize the mermaid top ToolbarConfig. This property accepts a MermaidToolbarConfig object, which can control the hide/show of top controls, add some class names, and control hover colors.

๐Ÿ“Œ Warning

If you set the codeMermaidHeaderControl property with code-x-slot, it completely takes over the mermaid Toolbar slot, allowing developers to fully customize it. Of course, we still expose the built-in Toolbar methods, so you can retain some built-in methods you need while only modifying styles.

ts
interface MermaidToolbarConfig {
  showToolbar?: boolean;
  showFullscreen?: boolean;
  showZoomIn?: boolean;
  showZoomOut?: boolean;
  showReset?: boolean;
  showDownload?: boolean;
  toolbarStyle?: Record<string, any>;
  toolbarClass?: string;
  iconColor?: string;
  tabTextColor?: string;
  hoverBackgroundColor?: string;
  tabActiveBackgroundColor?: string;
}

Slot Tag Interception โ€‹

You can intercept some tags, or custom tags, and then customize the rendering of these tags. If you want to customize the rendering of images or videos, it might be very convenient

Built-in Code Block Languages โ€‹

We have built-in matching for some commonly used programming and development languages to render corresponding code block content.

๐Ÿ“Œ Warning

Some languages can be matched using their abbreviations, for example, javascript can be matched using js

๐Ÿ’ View all supported languages
Language Name Language Match ID Language Match Abbreviation
ABAP abap
ActionScript actionscript-3
Ada ada
Angular HTML angular-html
Angular TypeScript angular-ts
Apache Conf apache
Apex apex
APL apl
AppleScript applescript
Ara ara
AsciiDoc asciidoc adoc
Assembly asm
Astro astro
AWK awk
Ballerina ballerina
Batch File bat batch
Beancount beancount
Berry berry be
BibTeX bibtex
Bicep bicep
Blade blade
1C (Enterprise) bsl 1c
C c
Cadence cadence cdc
Cairo cairo
Clarity clarity
Clojure clojure clj
CMake cmake
COBOL cobol
CODEOWNERS codeowners
CodeQL codeql ql
CoffeeScript coffee coffeescript
Common Lisp common-lisp lisp
Coq coq
C++ cpp c++
Crystal crystal
C# csharp c#cs
CSS css
CSV csv
CUE cue
Cypher cypher cql
D d
Dart dart
DAX dax
Desktop desktop
Diff diff
Dockerfile docker dockerfile
dotEnv dotenv
Dream Maker dream-maker
Edge edge
Elixir elixir
Elm elm
Emacs Lisp emacs-lisp elisp
ERB erb
Erlang erlang erl
Fennel fennel
Fish fish
Fluent fluent ftl
Fortran (Fixed Form) fortran-fixed-form fforf77
Fortran (Free Form) fortran-free-form f90f95f03f08f18
F# fsharp f#fs
GDResource gdresource
GDScript gdscript
GDShader gdshader
Genie genie
Gherkin gherkin
Git Commit Message git-commit
Git Rebase Message git-rebase
Gleam gleam
Glimmer JS glimmer-js gjs
Glimmer TS glimmer-ts gts
GLSL glsl
Gnuplot gnuplot
Go go
GraphQL graphql gql
Groovy groovy
Hack hack
Ruby Haml haml
Handlebars handlebars hbs
Haskell haskell hs
Haxe haxe
HashiCorp HCL hcl
Hjson hjson
HLSL hlsl
HTML html
HTML (Derivative) html-derivative
HTTP http
HXML hxml
Hy hy
Imba imba
INI ini properties
Java java
JavaScript javascript js
Jinja jinja
Jison jison
JSON json
JSON5 json5
JSON with Comments jsonc
JSON Lines jsonl
Jsonnet jsonnet
JSSM jssm fsl
JSX jsx
Julia julia jl
Kotlin kotlin ktkts
Kusto kusto kql
LaTeX latex
Lean 4 lean lean4
Less less
Liquid liquid
LLVM IR llvm
Log file log
Logo logo
Lua lua
Luau luau
Makefile make makefile
Markdown markdown md
Marko marko
MATLAB matlab
MDC mdc
MDX mdx
Mermaid mermaid mmd
MIPS Assembly mipsasm mips
Mojo mojo
Move move
Narrat Language narrat nar
Nextflow nextflow nf
Nginx nginx
Nim nim
Nix nix
nushell nushell nu
Objective-C objective-c objc
Objective-C++ objective-cpp
OCaml ocaml
Pascal pascal
Perl perl
PHP php
PL/SQL plsql
Gettext PO po potpotx
Polar polar
PostCSS postcss
PowerQuery powerquery
PowerShell powershell psps1
Prisma prisma
Prolog prolog
Protocol Buffer 3 proto protobuf
Pug pug jade
Puppet puppet
PureScript purescript
Python python py
QML qml
QML Directory qmldir
Qt Style Sheets qss
R r
Racket racket
Raku raku perl6
ASP.NET Razor razor
Windows Registry Script reg
RegExp regexp regex
Rel rel
RISC-V riscv
reStructuredText rst
Ruby ruby rb
Rust rust rs
SAS sas
Sass sass
Scala scala
Scheme scheme
SCSS scss
1C (Query) sdbl 1c-query
ShaderLab shaderlab shader
Shell shellscript bashshshellzsh
Shell Session shellsession console
Smalltalk smalltalk
Solidity solidity
Closure Templates soy closure-templates
SPARQL sparql
Splunk Query Language splunk spl
SQL sql
SSH Config ssh-config
Stata stata
Stylus stylus styl
Svelte svelte
Swift swift
SystemVerilog system-verilog
Systemd Units systemd
TalonScript talonscript talon
Tasl tasl
Tcl tcl
Templ templ
Terraform terraform tftfvars
TeX tex
TOML toml
TypeScript with Tags ts-tags lit
TSV tsv
TSX tsx
Turtle turtle
Twig twig
TypeScript typescript ts
TypeSpec typespec tsp
Typst typst typ
V v
Vala vala
Visual Basic vb cmd
Verilog verilog
VHDL vhdl
Vim Script viml vimvimscript
Vue vue
Vue HTML vue-html
Vyper vyper vy
WebAssembly wasm
Wenyan wenyan wenyan
WGSL wgsl
Wikitext wikitext mediawikiwiki
WebAssembly Interface Types wit
Wolfram wolfram wl
XML xml
XSL xsl
YAML yaml yml
ZenScript zenscript
Zig zig

Properties โ€‹

Property NameTypeRequiredDefaultDescription
markdownstringYes''markdown content
allowHtmlboolNofalseWhether to render html
enableLatexboolNotrueWhether to render latex
enableBreaksboolNotrueWhether to render breaks
codeXRenderObjectNo()=>{}Custom code block rendering
codeXSlotObjectNo()=>{}Custom code block top slot rendering
customAttrsObjectNo()=>{}Custom attributes
mermaidConfigObjectNo()=>{}mermaid configuration

Features โ€‹

  • Supports incremental rendering, excellent performance
  • Supports custom slots, which can be h function components or template components. Easier to get started
  • Built-in rich basic styles for mathematical formulas, mermaid diagrams, reducing developer burden
  • Supports multiple interceptions and custom rendering, reaching the upper limit