highlight.js does not work with Angular 2
Asked Answered
C

5

12

I am trying to add syntax highlighting to my application using highlight.js but it doesn't seem to work with Angular 2.

Could you please let me know what I might be doing incorrectly?

Here is the Plnkr: https://plnkr.co/edit/G3NFFPGXKyc9mV1a6ufJ?p=preview

This is the component:

import {Component} from 'angular2/core';
@Component({
selector: "my-app",
template: `
Hello!
<pre>
            <code class="html">
              &lt;html&gt;
                &lt;body&gt;

                &lt;h1&gt;My First Heading&lt;/h1&gt;
                &lt;p&gt;My first paragraph.&lt;/p&gt;

                &lt;/body&gt;
              &lt;/html&gt;
            </code>
          </pre>
`
})
export class AppComponent{
}

This is where I am adding highlight.js using cdn:

<!DOCTYPE html>
<html>
   <head>
      <!-- IE required polyfills, in this exact order -->
      <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.0/es6-shim.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.25/system-polyfills.js"></script>
      <script src="https://npmcdn.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
      <!-- Angular polyfill required everywhere -->
      <script src="https://code.angularjs.org/2.0.0-beta.13/angular2-polyfills.js"></script>
      <script src="https://code.angularjs.org/tools/system.js"></script>
      <script src="https://code.angularjs.org/tools/typescript.js"></script>
      <script src="https://code.angularjs.org/2.0.0-beta.13/Rx.js"></script>
      <script src="https://code.angularjs.org/2.0.0-beta.13/angular2.dev.js"></script>
      <link rel="stylesheet" href="style.css" />
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.4.0/styles/solarized-light.min.css">
      <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.4.0/highlight.min.js"></script>
      <script>hljs.initHighlightingOnLoad();</script>
      <script>
         System.config({
           transpiler: 'typescript', 
           typescriptOptions: { emitDecoratorMetadata: true }, 
           packages: {
             'api': {defaultExtension: 'ts'}, 
             'app': {defaultExtension: 'ts'} 
           } 
         });
         System.import('app/main')
             .then(null, console.error.bind(console));
      </script>
   </head>
   <body>
      <my-app>loading...</my-app>
   </body>
</html>

https://highlightjs.org/usage/

Cartagena answered 18/5, 2016 at 18:53 Comment(1)
nice article for code highlighting blog.almightytricks.com/2020/10/27/code-highlighting-ngx-quillChristean
D
19

You need to explicitly apply highlightjs on a block this way:

import {Component, ElementRef, ViewChild} from 'angular2/core';

declare var hljs: any;

@Component({
  selector: "my-app",
  template: `
    Hello!
    <pre>
      <code #code class="html">
        &lt;html&gt;
          &lt;body&gt;

          &lt;h1&gt;My First Heading&lt;/h1&gt;
          &lt;p&gt;My first paragraph.&lt;/p&gt;

          &lt;/body&gt;
        &lt;/html&gt;
      </code>
    </pre>
  `
})
export class AppComponent{
  @ViewChild('code')
  codeElement: ElementRef;

  ngAfterViewInit() {
    hljs.highlightBlock(this.codeElement.nativeElement);
  }
}

See this plunkr

A good approach would be to create a custom directive for this:

@Directive({
  selector: 'code[highlight]'
})
export class HighlightCodeDirective {
  constructor(private eltRef:ElementRef) {
  }

  ngAfterViewInit() {
    hljs.highlightBlock(this.eltRef.nativeElement);
  }
}

and use it this way:

@Component({
  selector: "my-app",
  template: `
    Hello!
    <pre>
      <code highlight class="html">
        (...)
      </code>
    </pre>
  `,
  directives: [ HighlightCodeDirective ]
})
(...)
Dooryard answered 18/5, 2016 at 19:0 Comment(3)
thanks Thierry. that works. but what if there are multiple blocks of code on the same page. Can i apply #code to all those block? I though I can use #code on only one block.Cartagena
You're welcome! Yes, you're right ;-) I added an approach based on a directivve. See my updated answer...Dooryard
thank you , the solution with the directive is very nice !Aluminiferous
B
6

I have published highlight.js module for angular, install it from npm

npm install --save ngx-highlightjs

It is very simple to use, it loads highlight.js automatically for you and works with lazy modules, check out the demo

Bacciform answered 29/7, 2017 at 3:20 Comment(1)
@PSKP I've updated the link ngx-highlight.netlify.appBacciform
C
4

I think that you have to fire highlight manually.

To do that you can delegate this function to special directive like:

@Directive({
  selector: 'pre'
})
class PreHighlight implements AfterViewInit {
  constructor(private elRef: ElementRef) {}

  ngAfterViewInit() {
    hljs.highlightBlock(this.elRef.nativeElement);
  }
} 

Plunker Example

Cheung answered 18/5, 2016 at 19:6 Comment(2)
it works on multiple pre tags on one page when the highlightBlock method is called here ngAfterViewInit(). Check out Thierry's solution and please upvote his answer if possible.Cartagena
@mila Thanks. FixedCheung
A
3

Angular 12+

Another way of doing this is custom usage of highlight.js

First, install the library

 npm install highlight.js

Add styles file to angular.json

"styles": [
   "./node_modules/highlight.js/styles/default.css" // I choose default but you can choose your favorite one.
],

In the component, you want to use highlighter import highlight.js

import hljs from 'highlight.js';

...

 constructor(@Inject(DOCUMENT) private document: Document) { }

 ngOnInit(): void {
    setTimeout(() => {
          this.document.querySelectorAll('pre code').forEach((el) => {
            hljs.highlightElement(el);
          });
        }, 500)
  }

Note: If you fetch data from an API please make sure your data is rendered on the page then run forEach()

Acadian answered 2/10, 2021 at 10:59 Comment(0)
E
0

The best highlightjs module for angular by far is angular2-highlight-js

https://www.npmjs.com/package/angular2-highlight-js

npm i angular2-highlight-js
Em answered 28/11, 2020 at 18:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.