HelpBot Assistant

How can I help you?

Integrate highlight.js into the Angular Rich Text Editor

11 Feb 20266 minutes to read

This guide shows how to integrate highlight.js - syntax highlighting with the Syncfusion Angular RichTextEditor so code blocks stay highlighted while editing and in preview/export.

Prerequisites

Before proceeding, complete the base Rich Text Editor setup described in the Getting Started guide. The guide covers Angular CLI setup, package installation, CSS imports, module injection, and basic editor markup: Getting Started with Angular Rich Text Editor.

Key features

  • Highlight language-aware code blocks inside the editor content and preview
  • Keep highlighting after edits, inserts, and exports
  • Register only the languages you need to reduce bundle size

Setup or Installation

Install the highlight.js package using the following command:

npm install highlight.js

Configure highlight.js for the Rich Text Editor

Step 1: Configure editor content target

  • Use the ViewChild decorator to access the Angular Rich Text Editor instance.
  • The RichTextEditor renders editable content inside an element with class .e-rte-content. You will run highlight.js against pre code elements inside that container.

Step 2: Register languages and load theme

  • Import the highlight.jscore and the language modules you need module into your Angular component.
import highlight from 'highlight.js/lib/common';
  • Then call highlight.registerLanguage(name, module) for each language.
import javascript from 'highlight.js/lib/languages/javascript';
import typescript from 'highlight.js/lib/languages/typescript';

highlight.registerLanguage('javascript', javascript);
highlight.registerLanguage('typescript', typescript);
  • Add a highlight.js theme stylesheet to your global styles.

Option A — angular.json:

"styles": [
  "src/styles.scss",
  "node_modules/highlight.js/styles/github.css"
]

Option B — import from src/styles.css:

@import 'highlight.js/styles/atom-one-dark.min.css';

Step 3: Wire the RichTextEditor events

  • Use the Rich Text Editor’s created event to highlight existing blocks at startup.
  • Use change event to re-run highlighting after edits.

Step 4: Add Highlight.js Styles to Ensure Proper Code Block Rendering

To ensure that Highlight.js styles correctly apply inside the Rich Text Editor and override the default RTE code block formatting, include the following Highlight.js style rules in your app.css file.

.e-richtexteditor .e-rte-content .e-content pre code, 
.e-richtexteditor .e-rte-content .e-content pre[data-language], 
.e-richtexteditor .e-rte-content .e-content pre[data-language] code{
    color: #abb2bf;
    background-color: #282c34;
}

Example: Integrate with Syncfusion Rich Text Editor (app.ts)

The following examples demonstrate how Highlight.js can be seamlessly integrated with the Syncfusion Rich Text Editor to enable automatic syntax highlighting within editor content.

import { RichTextEditorComponent, RichTextEditorModule, ToolbarSettingsModel } from '@syncfusion/ej2-angular-richtexteditor';
import { Component, ViewChild } from '@angular/core';
import { ToolbarService, LinkService, ImageService, HtmlEditorService, QuickToolbarService, CodeBlockService } from '@syncfusion/ej2-angular-richtexteditor';
import highlight from 'highlight.js/lib/common';

@Component({
  imports: [RichTextEditorModule],
  standalone: true,
  selector: 'app-root',
  styleUrl: 'app.css',
  encapsulation: ViewEncapsulation.None,
  template: `
    <ejs-richtexteditor
      #rte
      [value]="initialHtml"
      [toolbarSettings]='tools'
      (created)="onCreated()"
      (change)="onChange()"
    ></ejs-richtexteditor>
  `,
  providers: [ToolbarService, LinkService, ImageService, HtmlEditorService, QuickToolbarService, CodeBlockService],
})
export class App {
  @ViewChild('rte')
  public rte: RichTextEditorComponent | undefined;
  public tools: ToolbarSettingsModel = {
    items: ['Undo', 'Redo', '|', 'CodeBlock', '|', 'InsertCode', 'Bold', 'Italic', 'Underline', 'StrikeThrough', 'InlineCode', '|', 'CreateLink', 'Image', 'CreateTable', 'Blockquote', '|', 'BulletFormatList', 'NumberFormatList', '|', 'Formats', 'Alignments', '|', 'Outdent', 'Indent', '|',
      'FontColor', 'BackgroundColor', 'FontName', 'FontSize', '|', 'SourceCode']
  };
  public initialHtml = `
<p>Welcome! Here are some preloaded code blocks:</p>
<p><strong>No language class</strong> (auto-detect):</p>
<pre><code>
  SELECT id, name FROM users WHERE active = 1;
</code></pre>
<p><strong>Language class (TypeScript)</strong>:</p>
<pre data-language="Typescript" spellcheck="false"><code class="language-typescript">
export function hello(name: string) {
  console.log('Hello ' + name);
}
</code></pre>
<p><strong>Language class (Python)</strong>:</p>
<pre data-language="Python" spellcheck="false"><code class="language-python">
def sum(a, b):
  return a + b
</code></pre>
<pre data-language="C++" spellcheck="false"><code class="language-cpp">
#include <iostream>
using namespace std;
int main() {
    cout << "Hello from C++!" << endl;
    int a = 10;
    int b = 20;
    int sum = a + b;
    cout << "Sum = " << sum << endl;
    return 0;
}
</code></pre>
  `;

  onCreated() {
    // Highlight existing code blocks at startup
    this.highlightAllCodeBlocks();
  }

  onChange() {
    this.highlightAllCodeBlocks();
  }

  private highlightAllCodeBlocks() {
    const container: HTMLElement = this.rte!.element.querySelector('.e-rte-content') as HTMLElement;
    if (!container) { return; }
    const blocks: NodeListOf<Element> = container.querySelectorAll('pre code');
    blocks.forEach((block: Element) => {
      if (!block.classList.contains('hljs')) {
        highlight.highlightElement(block as HTMLElement);
      }
    });
  }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { App } from './app.component';
import 'zone.js';

bootstrapApplication(App).catch((err) => console.error(err));
@import '../node_modules/@syncfusion/ej2-base/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-buttons/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-inputs/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-lists/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-navigations/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-popups/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-splitbuttons/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-richtexteditor/styles/tailwind3.css';
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/tailwind3.css';
@import 'highlight.js/styles/atom-one-dark.min.css';

Additional Resources