Learning to use a new technology has been in my experience, a process of spending days searching for information to piece together a puzzle of which you don't have the entire picture yet.
A process that is at the same time rewarding and frustrating, it has become a new experience that I just have to get used to while walking the path of a self-taught developer.
The most recent time I walked this path, was when I decided to remake my personal website using Gatsby and upon watching a lot of blogs and sites with really cool and styled block codes with syntax highlighting, I thought that it would be good to use it on my site.
There are many libraries for syntax highlighting, but the one that seems to be the most used and preferred is Prism, so I decided to not spend too much time searching the pros and cons of all of them and give Prism a try, I would be happy to see your opinions on other libraries in the comments.
The main thing that you need to take into account
If you are in the process of porting (or creating from scratch) your website or blog to Gatsby, and wanted to use Prism for code highlighting, the first thing that you need to decide is whether you're going to be using markdown files or not, because the process is different depending on this decision.
The need for using markdown files will depend on the type of website you are creating, but basically, if you are creating a blog or blog-like type of website, in the end using Markdown to source the content to your site is the most efficient way to go. If this is your case, the process will involve installing and configuring a couple of gatsby plugins (gatsby-transformer-remark
and gatsby-remark-prismjs
), installing the Prism npm package and querying for the Markdown files (or snippets) with GraphQL.
On the other hand, if you are creating any other type of website, with a more complex design, Markdown won't give you enough flexibility to apply things like collapsible containers, carousels, etc. In this case, you just need to get Prism working in React while using a custom .babelrc configuration file.
I created a blank Gatsby project to use for both examples, you can download it here, or create it from the console using the following format.
gatsby new <project-name> https://github.com/FidelVe/gatsby-blank-starter
In case you haven't install Gatsby yet, run the following command first:
npm i -g gatsby-cli
Gatsby, React and PrismJs without remark
The first scenario that I will be explained is using Prism without markdown files. This scenario is basically using Prism inside React in a way that Gatsby can process without any problems.
Lets first create a new gatsby project.
gatsby new gatsby-prism https://github.com/FidelVe/gatsby-blank-starter
Try running the gatsby develop
server and you will see the following page with the default <code>
style.
The first thing to do is install the npm Prism package:
npm install --save prismjs
Now we are going to install babel-plugin-prismjs
, this plugin allows us to configure and customize Prism by using Babel.
npm install --save babel-plugin-prismjs
To use this plugin we need to create a .babelrc file and put our configurations in it. Gatsby ships with a default .babelrc file, in order to create our own file and modify it we need to install the babel-preset-gatsby
preset and add it to our new .babelrc file.
npm install --save babel-preset-gatsby
At this point, we have already installed everything we need so let's start with the configurations.
First, create a new file at the root of the project and call it .babelrc. Inside this file, we can customize Prism, in my case this is the content of the .babelrc file.
{
"presets": ["babel-preset-gatsby"],
"plugins": [
["prismjs", {
"languages": ["javascript", "css", "markup"],
"plugins": ["show-language"],
"theme": "okaidia",
"css": true
}]
]
}
With the installations and configurations out of the way, now we just need to import prismjs
and use the Prism.highlightAll()
function call to style our code blocks.
If you're using the repo I linked at the beginning, open the src/pages/index.js file and add the following:
import React from "react"
import { useEffect } from "react"
import Layout from "../components/layout"
//import the Prism package
import Prism from "prismjs"
// The code we will be displaying
const code = `const foo = 'foo';
const bar = 'bar';
console.log(foo + bar);
`
const IndexPage = () => {
useEffect(() => {
// call the highlightAll() function to style our code blocks
Prism.highlightAll()
})
return (
<Layout>
<div
style={{
display: "flex",
alignItems: "center",
flexFlow: "column nowrap",
margin: "6px 10px",
maxWidth: "800px",
}}
>
<h2>
Using Prism to style <code>code blocks</code> in Gatsby
</h2>
<div className="code-container">
<pre>
<code className="language-javascript">{code}</code>
</pre>
</div>
</div>
</Layout>
)
}
export default IndexPage
Run the gatsby develop
server and you will see the following page with the code block styled with the prism theme.
Congratulations, now you know how to add code styles with Prism inside Gatsby, here is a list of links to expand more on this topic.
Gatsby, React and PrismJs with remark
Parsing markdown files on gatsby is done with a transformer plugin called gatsby-transformer-remark. This plugin takes markdown formatted content and transform it into valid html, so in this case, we are going to write our code snippets in triple backtick () inside markdown files (.md), use GraphQl to query the data inside the file and put it inside our code.
Let's start by creating a new blank gatsby project.
gatsby new gatsby-markdown-prism https://github.com/FidelVe/gatsby-blank-starter
Now, lets install prismjs
, gatsby-transformer-remark
and gatsby-remark-prismjs
.
npm install --save prismjs gatsby-transformer-remark gatsby-remark-prismjs
There are several themes to choose from in Prism, for this project I'm using the okaidia theme. In order to define a theme, create a file called gatsby-browser.js in the root folder and add the following.
require("prismjs/themes/prism-okaidia.css");
Since we are going to be using .md files to write our code snippets in them, create a folder (src/content/). to put all the markdown files, and inside that folder create a new markdown file called code.md and add the following content.
The next step is to configure the plugins we have installed. open the gatsby-config.js file at the root of the project and add the following:
module.exports = {
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `code`,
path: `${__dirname}/src/content`,
},
},
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
{
resolve: `gatsby-remark-prismjs`,
options: {},
},
],
},
},
],
}
The gatsby-source-filesystem
plugin creates File
nodes from the files in our system. In this case, we are creating nodes from each file inside our src/content/ folder.
Every .md file we create inside our src/content/ folder gets parsed and transformed into valid html by gastby-transformer-remark
, and because we are using the gatsby-remark-prismjs
plugin, content inside triple backticks is automatically formatted by Prism.
Having installed and configured all the necessary plugins, the only thing that's left is inserting the parsed content into our page and for that we will use GraphQl.
Open the src/page/index.js file and add the following content to it.
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Layout from "../components/layout"
const IndexPage = () => {
const data = useStaticQuery(graphql`
{
allMarkdownRemark(filter: { fileAbsolutePath: { regex: "/code.md/" } }) {
nodes {
html
}
}
}
`)
return (
<Layout>
<div
style={{
display: "flex",
alignItems: "center",
flexFlow: "column nowrap",
margin: "6px 10px",
maxWidth: "800px",
}}
>
<h2>
Using Prism to style <code>code blocks</code> in Gatsby
</h2>
<div
className="code-container"
dangerouslySetInnerHTML={{
__html: data.allMarkdownRemark.nodes[0].html,
}}
></div>
</div>
</Layout>
)
}
export default IndexPage
Start the gatsby develop
server and you should see the code styled as shown in the image.
Thanks for reading, hope this helped you implement Prism to your Gatsby pages.
Again, here is a list of links to expand more on this topic.
Top comments (8)
The best resource I've read about this. I'm a very casual frontend engineer (I'm a backend engineer), so my Gatsby / React skills are "eh".
I had no idea the "remark" plugins were for dealing with markup files. This helped me solve my issue.
Thank you!
Thanks for the article! I am wondering if you have ever incorporated a copy-to-clipboard functionality with the code block that is generated from the
gatsby-remark-prismjs
plugin. There seems to be a bunch of prism specific plugins that are not accessible/exposed to thegatsby-remark-prismjs
plugin. Thanks!Hey Fidel, thanks for the great tutorial.
I'm wondering how you would do this with
dangerouslySetInnerHTML={{ __html: post.content.html }}
. When I followed your above steps, it did not work for me.
I would love to see an addition to this that covers how to work with Prism Plugins within Gatsby, for example prismjs.com/plugins/show-language/
As of 6/12/2021, there's still no way to use most Prism plugins like show-language with Gatsby. Someone made a pull request that added in the show-invisibles plugin though! github.com/gatsbyjs/gatsby/pull/21439
How to add file type on the code snippet?
Thanks .
Thanks for your article, this is exactly what I was looking for!