Code Block Rendering
Overview
Code blocks can be rendered in three ways depending on which optional dependencies you install and how you configure the library:
- Monaco (recommended for large/interactive code blocks): installs and uses
stream-monacoto provide an editor-like, incremental rendering experience. The library lazy-loadsstream-monacoat runtime when available. - Shiki (MarkdownCodeBlockNode): install
shiki+stream-markdownand override thecode_blocknode viasetCustomComponentsto use a lightweight Markdown-driven renderer. - Fallback (no extra deps): if neither optional package is installed, code blocks render as plain
<pre><code>blocks (basic styling / no Monaco features).
Monaco (recommended)
- Install:
pnpm add stream-monaco
# or
npm i stream-monacoBehavior: when
stream-monacois present the built-inCodeBlockNodewill use Monaco-based streaming updates for large or frequently-updated code blocks.Vite worker note: Monaco and some worker-backed features require appropriate worker bundling configuration in your bundler (Vite) so the editor/workers are available at runtime. See /nuxt-ssr for guidance and examples of configuring workers and client-only initialization.
See also: /guide/monaco for worker bundling tips and preload snippets.
Shiki mode (MarkdownCodeBlockNode)
- Install:
pnpm add shiki stream-markdown
# or
npm i shiki stream-markdown- Override the
code_blocknode viasetCustomComponentsto register the Shiki-based renderer:
import { MarkdownCodeBlockNode, setCustomComponents } from 'markstream-vue'
setCustomComponents({ code_block: MarkdownCodeBlockNode })Once set, MarkdownCodeBlockNode (powered by Shiki via stream-markdown) will be used for code_block nodes. You can also supply your own component that uses stream-markdown directly.
Vue CLI 4 (Webpack 4) notes
If you use Vue CLI 4 (Webpack 4), it’s recommended to use the Shiki mode for code blocks and override code_block to avoid Monaco + legacy-bundler edge cases.
Key pitfalls and fixes (see playground-vue2-cli):
- Webpack 4 doesn’t support
package.json#exports→ preferdist/*paths viaresolve.alias. - ESM-only packages (like
stream-markdown) may not be discoverable viarequire.resolve()insidevue.config.js(CJS) → use a filesystem fallback to findnode_modules/stream-markdown, and alias it todist/index.js. - If you use
IgnorePluginto skip optional deps, don’t accidentally ignorestream-markdown(otherwise you’ll getwebpackMissingModuleat runtime).
Fallback
If you don't install either optional package the renderer falls back to a simple pre/code representation.
Links & further reading
- Worker / SSR guidance: /nuxt-ssr
- Installation notes: /guide/installation
Try this — simple CodeBlock render:
<CodeBlockNode :node="{ type: 'code_block', language: 'js', code: 'console.log(42)', raw: 'console.log(42)' }" />