Configuration
Customize nstreamdown's behavior and appearance to match your application's needs.
StreamdownConfig
The Streamdown component accepts a config prop with the following options:
streamdown-config.ts
interface StreamdownConfig {/*** Mode: 'streaming' for real-time updates, 'static' for complete markdown* @default 'static'*/mode?: 'streaming' | 'static';/*** Whether to show copy/download controls on code blocks and tables* @default true*/controls?: boolean;/*** Whether to show the animated caret during streaming* @default true (when mode is 'streaming')*/showCaret?: boolean;/*** Custom caret character* @default '▋'*/caret?: string;/*** Override body text color for headings, paragraphs, lists, blockquotes* Example: 'white', '#ffffff'*/textColor?: string;/*** Override link text color* @default '#2563eb'*/linkColor?: string;/*** Override inline code text color* @default '#db2777'*/codeInlineColor?: string;/*** Override strikethrough text color* @default '#94a3b8'*/strikethroughColor?: string;/*** Override inline math text color*/mathInlineColor?: string;/*** Override paragraph spacing/wrapper class*/paragraphClass?: string;/*** Override heading spacing class*/headingClass?: string;/*** Override list container class*/listClass?: string;/*** Override blockquote spacing class*/blockquoteClass?: string;/*** Override code block spacing class*/codeBlockClass?: string;/*** Override image container class*/imageClass?: string;/*** Override horizontal rule spacing class*/horizontalRuleClass?: string;/*** Override table spacing class*/tableClass?: string;/*** Override math block spacing class*/mathBlockClass?: string;}
Style Customization
Customize markdown colors and spacing classes to match your app design system.
<Streamdown[content]="markdown"[config]="{textColor: '#e2e8f0',linkColor: '#60a5fa',codeInlineColor: '#f9a8d4',strikethroughColor: '#94a3b8',mathInlineColor: '#c4b5fd'}"/>
<Streamdown[content]="markdown"[config]="{paragraphClass: 'mb-2',headingClass: 'mt-2 mb-1',listClass: 'my-1',blockquoteClass: 'border-l-2 pl-3 my-2',codeBlockClass: 'my-2',imageClass: 'my-2',horizontalRuleClass: 'my-2',tableClass: 'my-2',mathBlockClass: 'my-2'}"/>
Note: exact default spacing classes vary slightly by framework implementation.
Mode Options
Static Mode
Use static mode when you have complete markdown content that doesn't change:
<Streamdown[content]="completeMarkdown"[config]="{ mode: 'static' }"/>
Streaming Mode
Use streaming mode for AI-generated content that arrives word-by-word:
<Streamdown[content]="streamingContent"[config]="{ mode: 'streaming', showCaret: true }"/>
Controls
Enable or disable interactive controls on code blocks and tables:
<!-- Show copy and download buttons --><Streamdown [content]="markdown" [config]="{ controls: true }" /><!-- Hide all controls --><Streamdown [content]="markdown" [config]="{ controls: false }" />
When controls are enabled:
- Code blocks: Copy to clipboard and download as file buttons
- Tables: Copy as text and export as CSV buttons
Custom Caret
Customize the streaming caret character:
<!-- Default caret --><Streamdown [content]="content" [config]="{ showCaret: true }" /><!-- Custom caret --><Streamdown [content]="content" [config]="{ showCaret: true, caret: '|' }" /><!-- Blinking cursor style --><Streamdown [content]="content" [config]="{ showCaret: true, caret: '_' }" />
Full Example
ai-chat.component.ts
import { Component } from '@angular/core';import { Streamdown, StreamdownConfig } from '@nstudio/nstreamdown';@Component({selector: 'app-ai-chat',template: `<Streamdown [content]="response" [config]="config" />`,imports: [Streamdown],})export class AiChatComponent {response = '';config: StreamdownConfig = {mode: 'streaming',controls: true,showCaret: true,caret: '▋',textColor: '#e2e8f0',linkColor: '#60a5fa',paragraphClass: 'mb-2',codeBlockClass: 'my-2',};async sendMessage(message: string) {this.response = '';// Connect to your AI APIconst stream = await fetch('/api/chat', {method: 'POST',body: JSON.stringify({ message }),});const reader = stream.body?.getReader();if (!reader) return;while (true) {const { done, value } = await reader.read();if (done) break;const text = new TextDecoder().decode(value);this.response += text;}}}