Setting up PrismJS with Phoenix
Tags: markdown, phoenix, prismjs, earmark
Published: 2019-12-16 09:47:02

---
title: Setting up PrismJS with Phoenix
published: true
description: How to set up PrismJS with Phoenix (and configure it to play nicely with Earmark)
tags: Markdown, Phoenix, PrismJS, Earmark
canonical_url: https://alchemist.camp/articles/phoenix-prism-syntax-highlighting
---

PrismJS is a great option for code syntax highlighting. It's used by Stripe, along with many other companies that deeply value documentation.

It supports a vast array of plugins and the total script weighs in at just 2k, gziped. Extra programming languages add 0.3-0.5KB each and themes are around 1KB. All in all, it's a lot of functionality for very little cost to your page load times!

This is a quick guide to get it set up on Phoenix (or just about any back-end framework that takes an agnostic approach towards JS). The code shown *in this post*, as well as on Alchemist Camp uses this setup.

This guide starts from a fresh Phoenix app. It *should* work with just about any standard app.

## Install Prism

First, `cd` into your `assets` directory and then install the following two libraries. If you're using yarn:
```bash
yarn add prismjs
yarn add babel-plugin-prismjs
```

Or, if you're using npm:
```bash
npm install prismjs
npm install babel-plugin-prismjs
```

Next, to include it in your front-end, add the following to the top of your main `app.js` file:
`import Prism from "prismjs"`

### Adding support for more languages

Prism supports syntax highlighting for well over a hundred languages, but it doesn't load them all by default. We can configure which languages load and pick a theme by creating a `.babelrc` file in our assets directory. Here's an example file:
```javascript
{
  "presets": ["@babel/preset-env"],
  "plugins": [
    [
      "prismjs",
      {
        "languages": [
          "elixir",
          "erlang",
          "css",
          "javascript",
          "markdown",
          "markup",
          "ruby",
          "scss",
          "toml"
        ],
        // themes can be found in this directory:
        // assets/node_modules/prismjs/themes
        "theme": "okaidia",
        "css": true
      }
    ]
  ]
}
```

### Customizing the theme
I wanted the styling from the okaidia theme for blocks of pre-formated code, but wanted my own styles to control inline code. So I commented out the theme line above, copied the theme file from its directory into the `/assets/css` directory where Phoenix puts stylesheets. Then removed the styles I didn't want and re-wrote it to match my specific needs. All the Prism themes are is CSS, so you can adjust them without concern about breaking anything else.

### How Prism works

Prism will add syntax highlighting to inline `code` tags and to `pre` blocks with `code` inside them. The language of highlighting applied is determined by the class of the element. If the class is `language-javascript`, the highlighting will be for JavaScript, a class of `language-elixir` will apply Elixir highlighting, and so on. For the full list, refer to [Prism's supported language chart](https://prismjs.com/#supported-languages).

You can also set a default language by setting a class on a parent element, such as the `body` tag.

### Add code to a page

Phoenix apps come with an `index.html.eex` template for the `/` page. Try replacing yours to the following:
```html
<% code = ~s"""
  defmodule MyModule do
    #stuff
  end
  """%>
<section class="row">
  <article class="column">
    <code class="language-elixir">Enum.at([:a, :b, :c], 1) |> IO.puts()</code>
    <pre><code class="language-elixir"><%= code %></code></pre>
  </article>
</section>
```
(The top line is just saving our block of code in a variable `code`, using a HEREDOC string so we don't have to worry about new lines or indentation inside the `pre` block!)

Here's the result:
<img src="https://www.dropbox.com/s/ar94ezeotyvbfyj/AC%20syntax%20highlighting%206.png?raw=1" style="display: block; margin: 1em auto;">

### Integrating with Earmark

If you're using [Earmark](https://github.com/pragdave/earmark) to convert Markdown to HTML ([as this site does](https://alchemist.camp/tagged/Markdown)), then you'll need to pass in a `code_class_prefix` option to generate the appropriate classes on your code blocks. E.g:

```elixir
  Earmark.as_html!(
    %Earmark.Options{
      code_class_prefix: "lang-",
      smartypants: false
    }
  )
```

Then you can declare the language of your code blocks in Markdown like so:

<pre><code class="language-markdown">```ruby
  puts 8 ** 3
```
</code></pre>

- - -
*Originally published on [Alchemist Camp](https://alchemist.camp)*