How to use Prism.js in Ionic Stencil app

Here is the procedure for using the Prism.js syntax highlighter in an Ionic / Stencil app. 

First install prism.js with the following command:

npm install --save prismjs

Add the following line in the head section of your app’s index.html file:

<link href="/assets/prismjs/prism.css" rel="stylesheet" />

In stencil.config.ts, add the following stanza to copy the appropriate theme into your assets folder. 

copy: [{
    src: '../node_modules/prismjs/themes/prism-okaidia.css',
    dest: 'assets/prismjs/prism.css'
}]

Note that we are using the prism-okaidia.css theme file as the source, but copying it over to the generic name, prism.css. This allows you to change the theme globally in the src line without having to make any changes elsewhere.

Now, in the page component where you want to use syntax highlighting, add the following import statement:

import Prism from "prismjs"

Then, add your code snippet as a constant at the top of the file, after imports and before the class definition (constants can’t be defined within the component class itself). Here’s an example:

import { Component, h } from '@stencil/core';
import Prism from "prismjs"

const code = `<tr *ngFor="#item of data">
<td><a href="#">{{ item.invoiceNo }}</a></td>
<td>{{ item.invoiceDate }}</td>
<td>{{ item.invoiceStatus }}</td>
<td class="right aligned">{{ item.invoiceTotal | currency:'USD':true:'1.2-2' }}</td>
</tr>`;

@Component({
    tag: 'page-whatever',
})
export class PageWhatever {

// ...

}

Inside the render() method, you can put the code within a pre tag as follows:

<pre><code class="language-html">{code}</code></pre>

Then finally add the following method to the class:

componentDidLoad() {
     setTimeout(() => Prism.highlightAll(), 0)
}

That’s it! Let’s now look at the example page component all in one piece:

import { Component, h } from '@stencil/core';
import Prism from "prismjs"

const code = `<tr *ngFor="#item of data">
<td><a href="#">{{ item.invoiceNo }}</a></td>
<td>{{ item.invoiceDate }}</td>
<td>{{ item.invoiceStatus }}</td>
<td class="right aligned">{{ item.invoiceTotal | currency:'USD':true:'1.2-2' }}</td>
</tr>`;

@Component({
    tag: 'page-whatever',
})
export class PageWhatever {

    title = 'My Page Title';

    componentWillLoad() {
        document.title = this.title;
    }

    componentDidLoad() {
        setTimeout(() => Prism.highlightAll(), 0)
    }

    render() {
        return [
            <ion-header>
                <ion-toolbar color="primary">
                    <ion-buttons slot="start">
                        <ion-back-button defaultHref="/" />
                    </ion-buttons>
                    <ion-title>Blog</ion-title>
                </ion-toolbar>
            </ion-header>,
            <ion-content>
                  <h1>{this.title}</h1>
                  <p>Here's a code snippet formatted with prism.js...</p>
                  <pre><code class="language-html">{code}</code></pre>
            </ion-content>
        ];
    }
}