How to use PrismJS in Gatsby when the html and <code> block is contained within dangerouslySetInnerHTML?

399 Views Asked by At

So I am trying to use PrismJS within Gatbsy in order to display my code blocks. I followed this tutorial in order to get setup and running, and the following is the implementation within my code:

import React from "react";
import { useEffect } from "react";
import { graphql, Link } from 'gatsby';
import Layout from "../components/layout";
import SEO from "../components/seo";

//import the Prism package
import Prism from "prismjs"

const PostPage = ({ data }) => {
  const { post } = data.gcms;
  useEffect(() => {
    // call the highlightAll() function to style our code blocks
    Prism.highlightAll();
  });
  return (
  <Layout>
    <SEO
        keywords={[
          `planflow`,
          `ui`,
          `ux`,
          `information architecture`,
        ]}
        title={post.title}
      />
    <section className="w-full text-gray-700 body-font">
      <div className="container flex flex-col justify-center px-5 pb-24 mx-auto">
      <h1 className="flex justify-center mb-12 text-4xl font-semibold text-center text-black">{post.title}</h1>
        <div className="flex flex-col justify-center">
          <div className="h-64 overflow-hidden rounded-lg border-1 border-gray-light">
            <img alt="content" className="object-cover object-center w-full h-full" src={post.coverImage.url}></img>
          </div>
          <div className="flex flex-row justify-between w-full mt-4">
            <span className="flex flex-col pl-8 mt-6">
              <h3 className="text-2xl">{post.author.name}</h3>
              <h4 className="text-black-lighter">Published: {post.date}</h4>
            </span>
            <span className="pr-8 mt-6">
            { 
              post.tags.map((tag) =>
                <span key={tag} className="inline-block px-3 py-1 mb-2 mr-2 text-xs font-medium tracking-widest capitalize border-2 border-dashed rounded border-black-lighter text-blue bg-blue-indigo">{tag}</span>
              )
            }
            </span>
          </div>
          <div className="flex flex-col mt-6 sm:flex-row">
            {/* <div>Notication Section Here.</div> */}
            {/* {Post Content} */}
            <div className="pt-4 mt-4 text-center border-t border-gray-300 sm:w-full sm:pl-8 sm:py-8 sm:border-t-0 sm:mt-0 sm:text-left">
              <div dangerouslySetInnerHTML={{ __html: post.content.html }} className="mb-4 text-lg leading-loose sm:pr-8"></div>
            </div>
          </div>
        </div>
      </div>
    </section>
  </Layout>
)};

export const pageQuery = graphql`
  query postPageQuery($id: ID!) {
    gcms {
      post(where: { id: $id }) {
        id
        html
    }
}`

Within the HTML is the relevant code block, which I assume should be detected by Prism. Ultimately, Prism does not seem to detect it, and the code is not run.

Any advise here would be appreciated.

Thanks!

1

There are 1 best solutions below

0
On

include the desired language for Prism to highlight in the class attribute in your code tags

in your content html (the one you're going to parse) make sure you are setting class attribute in your code tags to specify the language used.

Do not use className in the html you're going to parse. class is an attribute in an html element <code class='language-javascript'></code>. While, on the other hand, .className is a property that can by called on an element to get/set its class.

var element = document.createElement('code');
element.className = 'language-javascript'
// element is <span class='language-javascript'></span>
so make sure your code snippet in the html you're going to parse looks something like this: example for javascript:
<pre>
  <code class=”language-javascript”>
    <p>some text</p>
  </code>
</pre>