Auralinna.blog - Tero Auralinna's web development blogAuralinna.blogTero Auralinna's blog about intriguing world of web development. Tweaking pixels since the '90s.

Code syntax highlighting with Angular and Prism.js

Published: 12/28/2017

I implemented Prism.js based code syntax highlight feature for my blog. This blog post shows how to use Prism with Angular.

Prism is a lightweight, extensible syntax highlighter, built with modern web standards in mind.

There are few existing Angular solutions for Prism:

But I decided not to use the existing ones because all the solutions use a component which requires code blocks as a content or as a parameter. Content of my blog is fetched from REST API as HTML so I can't (easily) separate code blocks from other content. That's why I decided to see how to implement support for the Prism without existing components. I use Prism's highlightAll method to process all of the pre and code tags once.

Implementing following steps needs a basic knowledge about Angular development.

1. Install Prism from npm

$ npm install prismjs --save

2. Create highlight service

Prism.js dependencies are imported in this service. Here you can add supported languages and additional Prism plugins you might want to use.

import { Injectable, Inject } from '@angular/core';

import { PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

import 'clipboard';

import 'prismjs';
import 'prismjs/plugins/toolbar/prism-toolbar';
import 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard';
import 'prismjs/components/prism-css';
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-java';
import 'prismjs/components/prism-markup';
import 'prismjs/components/prism-typescript';
import 'prismjs/components/prism-sass';
import 'prismjs/components/prism-scss';

declare var Prism: any;

@Injectable()
export class HighlightService {

  constructor(@Inject(PLATFORM_ID) private platformId: Object) { }

  highlightAll() {
    if (isPlatformBrowser(this.platformId)) {
      Prism.highlightAll();
    }
  }
}

Add service into app.module.ts

  providers: [
    ...
    HighlightService,
  ],

My implementation doesn't support server side rendering at the moment. Code syntax highlighting is enabled only for a browser because Prism.highlightAll uses document which is not available in Node.js. There probably are workarounds for this but I don't see code highlighting that important for server side rendering.

Prism supports 130 languages so I only import the ones I really need.

3. Use highlight service in your component

Then let's add the service into a component which handles data we want to highlight.

Lifecycle hook AfterViewChecked is used here to call the highlight service when view is ready. Method ngAfterViewChecked might be called multiple times. I use highlighted boolean to check if highlighting is already done to prevent multiple highlightAll method calls.

import { Component, OnInit, AfterViewChecked } from '@angular/core';

import { HighlightService } from '../shared/utils/highlight.service';

@Component({
  selector: 'app-blog-post',
  templateUrl: './blog-post.component.html',
  styleUrls: ['./blog-post.component.scss']
})
export class BlogPostComponent implements OnInit, AfterViewChecked {
  
  blogPost: BlogPostInterface;
  highlighted: boolean = false;
  
  constructor(
    ...
    private highlightService: HighlightService) {
  }

  /**
   * Highlight blog post when it's ready
   */
  ngAfterViewChecked() {
    if (this.blogPost && !this.highlighted) {
      this.highlightService.highlightAll();
      this.highlighted = true;
    }
  }

  /**
   * Fetch blog post from API
   */
  ngOnInit() {
    ...
  }
}

This code is just a partial example how to use recently created service in your own component. You need to adapt usage for your custom component.

4. Add Prism styles

Next add Prism styles into your styles.scss. Theme CSS is needed at least. Check my earlier blog post how to change Angular to use SCSS instead of CSS if you don't use SCSS already. Alternatively you can add CSS files directly into your HTML.

@import "~prismjs/plugins/toolbar/prism-toolbar.css";
@import "~prismjs/themes/prism-okaidia";

It should be working now. Please feel free to comment this post if you have questions or suggestions how to improve code base.

Comment by KhaledSamir at 2/26/2023.

@teroauralinna Can you please share a working version on SlackBlitz?

Comment by mainul35 at 7/29/2023.

Thanks a lot. It is a good article indeed. I just followed your article and it is working like a charm.

Latest CodePens

I am an experienced web developer with an eye for solid UI/UX design. I have specialized in front-end development, responsive web design, design systems, modern web frameworks, and content management systems. I also have experience in mobile apps development and back-end coding with PHP, Node.js, and Java. So I have a full stackish background, but I'm enjoying most building robust and beautiful front-ends with performance, accessibility, and testability in mind.

© Tero Auralinna

Auralinna.fiSunset with Bubbles: Travel and Photography Blog

The icon "ellipsis" is provided by loading.io