• English
  • Streaming Markdown in Angular

    Append incoming chunks to a signal and pass it to text. The streaming input controls unfinished syntax repair, smooth output, and entrance effects.

    Connect a text stream

    This example receives an async iterator of decoded text. Keep SSE or other protocol decoding in your request layer:

    import { Component, signal } from '@angular/core';
    import { Fluxdown } from '@fluxdown/angular';
    
    @Component({
      selector: 'app-message',
      imports: [Fluxdown],
      template: `<fluxdown [text]="text()" [streaming]="pending()" />`,
    })
    export class Message {
      readonly text = signal('');
    
      readonly pending = signal(false);
    
      async read(chunks: AsyncIterable<string>) {
        this.text.set('');
    
        this.pending.set(true);
    
        try {
          for await (const chunk of chunks) {
            this.text.update((text) => text + chunk);
          }
        } finally {
          this.pending.set(false);
        }
      }
    }

    Call read(chunks) after starting a request. Disable streaming when it ends to show all received content and remove the trailing marker.

    Adjust output

    streaming: true enables ending repair, smooth output, and the scale effect. Use an object to control them separately:

    import type { StreamingConfig } from '@fluxdown/angular';
    
    import { Component, input } from '@angular/core';
    import { Fluxdown } from '@fluxdown/angular';
    
    @Component({
      selector: 'app-message',
      imports: [Fluxdown],
      template: `<fluxdown [text]="text()" [streaming]="pending() && streaming" />`,
    })
    export class Message {
      readonly text = input.required<string>();
    
      readonly pending = input(false);
    
      readonly streaming: StreamingConfig = {
        repairEnding: true,
        smooth: true,
        effect: ['shad', { length: 3, maskWidth: 18 }],
      };
    }

    Import StreamingConfig from @fluxdown/angular.

    OptionPurpose
    repairEndingRepairs unfinished Markdown; enabled by default.
    smoothReveals new content gradually; enabled by default.
    effectSelects an effect; defaults to scale. Use false to disable it.

    Four effects

    EffectAppearance
    scaleNew characters grow and become clear as their blur fades.
    shadA gradient mask reveals the trailing text.
    chunkFades in received chunks; useful with smooth: false.
    suffixShows a trailing marker while content is being generated.

    Keep the original network chunks and fade them in individually:

    <fluxdown
      [text]="text()"
      [streaming]="pending() && { smooth: false, effect: 'chunk' }"
    />

    effect also accepts [name, config] or an array of effects. See configuration for the fields and animation effects for live examples. Custom tickers and schedulers are covered in Core streaming.

    Multiple messages

    Give each message its own component, and track it by message ID in @for so a different message gets its own playback state:

    @for (message of messages(); track message.id) {
    <fluxdown [text]="message.text" [streaming]="message.pending" />
    }