Learning to Add Functionality to Gatsby Site

Note:This is part 1 of five-parts adding functionality to Gatsby site series. This learning post is still in active development and updated regularly.

In the previous Gatsby learning-note post 4-parts series, Gatsby setup & installation, understanding its building blocks, overview of Gatsby Plugins & GraphQL and programmatically creating pages were discussed. Because Gatsby is designed to add features and functionalities with plugins, the next logical step is to learn to add plugins to enhance the functionality of the site & user experience.

The objective of this learning-note post series is to add the following some basic features & functionalities such as highlighting syntax, typography & styling, adding images, adding content tags & categories, and pagination.

Learning series
Part 1: Syntax highlighter with Prismjs (this post)
Part 2: Styling Gatsby Site with Typography.js & Gatsby Sass plugin
Part 3: Learning to work with Images to Gatsby Site
Part 4: Adding Tags & Categories to Gatsby Site
Part 5: Adding Pagination to Gatsby Site

The Gatsby plugin repository list several syntax highlighter plugins available to add to the Gatsby site to add and enhancing syntax highlighting functionalities.  The most commonly used (based on downloads) syntax highlighting plugin in the plugin reposiry is gatsby-remark-prismjs followed by gatsby-remark-vscode, gastby-remark-highlights and others.

A brief review of tutorials and posts suggests that syntax highlighting in Gatsby site is done with PrismJs and Gatbyjs has a gatsby-remark-prismjs to add this functionality in a site.

Syntax highlighting with PrismJs

In this learning-note post, adding syntax highlighting functionality with the gatsby-remark-prismjs the project site will be explored.

A brief review of tutorials and posts suggests that syntax highlighting in Gatsby site is done with PrismJs and Gatbyjs has a gatsby-remark-prismjs to add this functionality in a site. In this learning-note post, adding this functionality to the project site will be explored.

Step 1: Installation

First, installation of Prismjs and its Gatsby plugins gatsby-remark-prismjs with npm or yarn.

#!add with yarn
yarn add gatsby-remark-prismjs prismjs
#! add with npm
npm install --save gatsby-remark-prismjs prismjs

The gatsby-remark-prismjs plugin is designed to work in markdown files and requires gatsby-transformer-remark plugin. Its installation is required if the plugin has not been installed already. Its installation instruction is found in Gatsby documents and was also discussed in the previous post.

Step 2: Add and Configure the Plugin in gatsby-config.js File

A detailed instruction to add & configure the gatsby-remark-prismjs plugin is described in Gatsby Doc. In this project, I followed a slightly modified configuration as described in this post which was added in gatsby-config.js at the root of the project folder:

//gatsby-config.js
module.exports = {
  siteMetadata: {
 ...
 },
  plugins: [
  .... //other plugins
// begin prismjs
  {
    resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [{
          resolve: `gatsby-remark-prismjs`,
          options: {
           classPrefix: "language-",
           inlineCodeMarker: null,
            aliases: {sh: "bash", js:"javascript"},
            showLineNumbers: true,
           noInlineHighlight: false,
          },
        }],
      },
    },
    // end prismjs
 ]
}

Some common options as described in the Gatsby Docs are as follows:

  • classPrefix: This is a class prefix for <pre> tags containing syntax highlighting; default is 'language-' (eg <pre class="language-js">). It’s best to use the default value.
  • inlineCodeMarker:This is used to allow setting a language for inline code (i.e. single backticks) by creating a separator. This separator is a string and will do no white-space stripping, (eg’, non-ascii character '›').
  • aliases: This allows to set up language aliases. For example, setting this to '{ sh: "bash" }' allows to use the language "sh" which will highlight using the bash highlighter.
  • showLineNumbers: This toggles the display of line numbers globally alongside the code. To use it, the following line in src/layouts/index.js right after importing the prism color scheme is added: `require("prismjs/plugins/line-numbers/prism-line-numbers.css");` Default value is false. If it is desired to only show line numbers on certain code blocks, it is set to false and {numberLines: true} is added below the syntax.
  • noInlineHeight: If this is set to true, the parser won’t handle and highlight inline code used in markdown i.e. single backtick code like `this`.
Step 3: Importing Prismjs CSS Styles

PrismJS CSS style is based on it’s various default themes, and theme specific CSS can be imported in Gatsby sites. Generally, Prismjs theme CSS are loaded in site’s gatsby-browser.js file with require syntax, as shown below:

// gatsby-browser.js
//to load solarized-light css style
require("prismjs/themes/prism-solarizedlight.css")

//to load prismjs coy css style
require("prismjs/themes/prism-coy.css")
Step 4: Adding Line Numbers & Line Highlighting

To add line number & line highlight CSS style to Prismjs in Gatsby site, just load the prism-line-numbers.css from Prismjs plugin with 'require' syntax just below the theme CSS in gatsby-browser.js file as shown below:

// gatsby-browser.js

//load prismjs coy css style
require("prismjs/themes/prism-coy.css")
//load linenumber / lineheight css style
require("prismjs/plugins/line-numbers/prism-line-numbers.css")

Because the Prismjs line number CSS does not work properly in Gatsby, it needs to be adjusted as shown below:

/* adjust left margin */
line-numbers-rows {
   white-space: normal;
   width: auto;
   left: 1rem;
}

When viewed in a browser, code with line numbers displays just fine as shown below:

Figure: Screenshot of highlighted block of code snippets showing CSS adjusted line numbers (left).
Step 5: Import CSS style to <Layout /> component

Depending on the layout of the project site, the Prismjs theme and/or line number .css can be imported to to the <Layout /> component with import syntax.

// import theme style
import 'prismjs/themes/prism-tomorrow.css';

// import styles for line numbers / line heights
import 'prismjs/plugins/line-numbers/prism-line-numbers.css'

In the example above Prismjs theme & line-numbers css style sheets were imported to site’s <Layout /> component.

Additional Information: Adding code syntax highlights to gatsby blog | Hao’s Blog

Adding New Moon Theme Style

The code displayed on this post also uses Prismjs default okaida theme with CSS style from Tania Rascia’s New Moon syntax highlighter theme with the following gatsby-config.js configuration:

// gatsby-config.js
require("prismjs/themes/prism-okaidia.css")
require("prismjs/plugins/line-numbers/prism-line-numbers.css")

The new-moon CSS style was copied to src/styles/new-moon.css file and imported in src/components/layout.js page components. And the new-moon theme style works out of the box as shown below.

// highlight with new moon
``` js
//without line number
var foo = function (bar) {
  return bar++;
};

console.log(foo(5));
```

A screen shot of the above code snippets as viewed in a browser (see below).

Figure: Screenshot of block of code snippets displayed in a browser with PrismJs New Moon theme.

As described in the previous section, the line number with the code snippets also works fine with the following padding adjustment.

/* adjust padding */
pre[class*="language-"] {
   padding-left: 1.8rem!important;
}
pre[class*="language-"].line-numbers  {
   padding-left: 4.8rem!important;
}

An example code snippets with line numbers with code snippets.

// syntax highlighting with new-moon
``` javascript{numberLines: true}
// with line numbers
var foo = function (bar) {
  return bar++;
};

console.log(foo(5));
```

A screenshot of the above code displayed in a browser (below).

Figure: Screenshot of block of code snippets displayed in a browser with PrismJs New Moon theme showing line numbers.

Note: In both the Prismjs default theme (coy and okaidia), I couldn’t reproduced the line highlighting functionality in my site as described the Gatsby Docs.

Additional Prismjs Themes

In addition to the default themes, the Prismjs repository lists additional themes for syntax highlighting including the popular Atom editor style. The installation of Atom editor style highlighting with Prismjs was inspired by Niklas’s starter theme julia and his blog post.

Unlike the Prismjs default themes, the Prismjs additional themes requires additional steps to configure the gatsby-remark-prismjs plugin & was configured following Niklas’ post:

Step 1: Install the prism themes with npm or yarn

#!install with npm
npm i prism-themes
#! install with yarn
yardn add prism-themes

Step 2: Add the following to the gatsby-browser.js file at the project root:

# gatsby-browser.js
require("prism-themes/themes/prism-atom-dark.css");
require("prismjs/plugins/line-numbers/prism-line-numbers.css");

Step 3: Update the following CSS style as an override and import to the src/components/layout.js component:

/* atop-editor-override-style */
.gatsby-highlight {
  background-color: #1d1f21;
  border-radius: 0.3em;
  margin: 0.5em 0;
  padding: 1em;
  overflow: auto;
}

.gatsby-highlight pre[class*="language-"].line-numbers {
  padding: 0;
  padding-left: 2.8em;
  overflow: initial;
}

Step 4: An Example with Prismjs Atom Editor Syntax highlighting

// syntax highlighting with atom-editor
``` js
var foo = function (bar) {
  return bar++;
};

console.log(foo(5));
```

The above code snippet is displayed in a browser as shown below:

Figure: Screenshot of block of code snippets displayed in a browser with PrismJs Atom editor theme.

Additional Information: Implement PrismJS in GatsbyJS | niklasmt.de

Some Markdown Use Case Examples

A few examples of using syntax highlighting of block of codes with PrismJs in some commonly used languages in markdown files are shown below:

1. An example of syntax highlighting of a JavaScript file with PrismJs

<!--- markdown file --->
```js
console.log("Hello World");
```

In the example above JavaScript alias js (line 2) defined in gatsby-config.js was used to define language. The JavaScript can also be used to define language (line 2 below) as shown below:

<!--- gatsby-config.js --->
```javascript
...
 plugins: [
 <!--- prismjs configuration --->
   {
    resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [{
          resolve: `gatsby-remark-prismjs`,
          options: {
            classPrefix: "language-",
            inlineCodeMarker: null,
            aliases: { sh: "bash", js: "javascript" },
            showLineNumbers: false,
            noInlineHighlight: false,
           },
        }],
      },
    },
  <!--- end --->
 ],
}
```

2. An example of code snippets with markdown file used in markdown file.

<!--- markdown file --->
```markdown
---
title: Syntax Highlighting with PrismJs
date: "2019-08-03"
author: Niklas
tags: ['prism', 'gatsby']
---

This is an example of markdown syntax highlight
```

3. An example of code snippets with CSS file in markdown file.

<!--- CSS file --->
```css
.background {
  background-color: red;
  padding: 2rem;
}
```

4. An example of code snippets with JSX file in markdown file.

<!--- JSX file --->
```jsx
import React from "react"
import Layout from "../components/layout"

export default () => (
  <Layout>
    <div>
      <h1 className="page-title">About Us</h1>
        <p>We are a small but a diverified team passately working to 
           solve most pressing problems of our community</p>
          <img src="https://source.unsplash.com/780x300/?cat" alt="" />
    </div>
  </Layout>  
)
```

5. An example of code snippets with HTML file in markdown file.

<!--- HTML File --->
```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>My Gatsby Site</title>  
</head>
<body>
  <p> Hello Gatsby Community </p>
</body>
</html>
```

The examples presented above are a snap shot of using Prismjs highlighting block of code snippets in some commonly used languages in markdown files. Examples of use cases with more languages will be available in a working site (currently under development).

Wrapping Up

In this learning-note post, step by step procedure to add highlighting block of code snippets functionality to Gatsby site with gatsby-remark-prismjs plugin were discussed with some use case examples in markdown file. In the next learning-note post, Styling Gatsby Site with Typography.js & Gatsby Sass plugin will be discussed.

Next Post: Styling Gatsby Site with Typography.js & Gatsby Sass plugin

Useful resources

While preparing this post, I have referred the following references extensively. Please to refer original posts for more detailed information.