Render Code snippets with syntax highlighting in Astro đź’…

Astro supports styling your code in Markdown, via Prism using a <Prism /> component and via Shiki using a <Code /> component. Be sure to import any Astro components you want to use:


---
import { Markdown, Prism, Code } from 'astro/components';
---

(Note: The use of Prism may be deprecated in the future. This page is, and will be updated as supported methods for styling your code evolve.)

Astro’s Markdown code via single backticks

When writing in Markdown, short code samples typed between single backticks renders as the inline <code> html tag.

Astro’s default starters do not include any styles for <code>, but you can add styling via css. These are the styles I have added to global.css for the styling you see here:


code {
  background-color: #212121; // Chosen specifically to match my prefered Shiki theme to avoid conflicts
  color: white;
  border-radius: 5px;
  padding: 0.18em 0.5em;
}

Astro’s <Prism /> Component

The css code above was rendered using Astro’s <Prism /> component. This component should be passed both a lang property and a code property to properly highlight code of a particular language.

Additionally, you must supply (via a stylesheet or an import) a Prism Theme for syntax highlighting. The <Prism /> component itself will only apply style classes to your code, but without a Prism theme to define those style classes, your code will not be styled. You can add the theme’s css file to your own code or use an external link to one of the themes from an external CDN such as


<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.24.1/themes/prism-tomorrow.css">

Once you have a Prism theme downloaded or linked, you can either …

1. Type code directly into the code attribute:


    //NB: The ` character needs to be escaped with a back slash!
    <Prism lang="js" code={` 
    // In your gatsby-config.js
    plugins: [
      {
        resolve: \`gatsby-transformer-remark\`,
        options: {
          plugins: [
            \`gatsby-remark-prismjs\`,
          ],
        },
      },
    ],
    `}/>
  

OR

2. Pass a variable in to the code attribute of <Prism />


    <Prism lang="js"  code={codesnippet} />
  

… Combined with the following Astro front matter …


---
import { Prism } from 'astro/components';

let codesnippet = `
  // In your gatsby-config.js
    plugins: [
      {
        resolve: \`gatsby-transformer-remark\`,
        options: {
          plugins: [
            \`gatsby-remark-prismjs\`,
          ],
        },
      },
    ],
  `
---

Both methods will render ...


  // In your gatsby-config.js
    plugins: [
      {
        resolve: `gatsby-transformer-remark`,
        options: {
          plugins: [
            `gatsby-remark-prismjs`,
          ],
        },
      },
    ],
  

Code written in an Astro <Markdown> component

Astro’s built-in <Markdown> component uses Prism by default… but styling can be a bit hit or miss as Astro’s codebase changes and we are preparing to move to Shiki as a default. (I have seen some code be highlighted, but with no indentation. I have seen indentation, but no highlighting…) So, be prepared!

Code can be written inside <Markdown></Markdown> tags using three backticks (Note: no escape for single back ticks needed when writing code this way) or typed/passed in to a self-closing tag as a content attribute.


  <Markdown>
    ```js
      // In your gatsby-config.js
      plugins: [
        {
          resolve: `gatsby-transformer-remark`,
          options: {
            plugins: [
              `gatsby-remark-prismjs`,
            ],
          },
        },
      ],
    ```
  </Markdown>

  <Markdown content={`
     // In your gatsby-config.js
      plugins: [
        {
          resolve: `gatsby-transformer-remark`,
          options: {
            plugins: [
              `gatsby-remark-prismjs`,
            ],
          },
        },
      ],
  `} />

  <Markdown content={codesnippet} />
  

... and all of these will render a variation of ...

 // In your gatsby-config.js
  plugins: [
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          `gatsby-remark-prismjs`,
        ],
      },
    },
  ],

Rendering Astro Code

Yes, there's support for Astro code syntax highlighting!

Here's my Astro new page template:


---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout title="New Page Template!">
  <main>
    <p>New page template!</p>
  </main>
</BaseLayout>

… and I’ve rendered it by typing this:


<Prism lang="astro" code={`
---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout title="New Page Template!">
  <main>
    <p>New page template!</p>
  </main>
</BaseLayout>
`} />

Astro’s <Code /> component (Shiki)

Astro now also supports a newer <Code/> component for rendering code with Shiki.

This component should be passed some code inline or via a variable defined in front matter, a lang and optionally, a theme.


---
import { Code } from 'astro/components';
let layoutcode = `
  ---
  import BaseLayout from '../layouts/BaseLayout.astro';
  ---
  <BaseLayout title="New Page Template!">
    <main>
      <p>New page template!</p>
    </main>
  </BaseLayout>
`
---
<Code lang="astro" theme="material-darker" code={layoutcode} />

... renders as ...


  ---
  import BaseLayout from '../layouts/BaseLayout.astro';
  ---
  <BaseLayout title="New Page Template!">
    <main>
      <p>New page template!</p>
    </main>
  </BaseLayout>

But I'd LOVE to figure out why I seem to get "better" (?) Astro formatting if I change the language attribute to lang="js" -- look at the difference? Doesn't this seem more "Astro?" Waiting to see whether an update to Shiki on 2022-02-01 fixes this!


  ---
  import BaseLayout from '../layouts/BaseLayout.astro';
  ---
  <BaseLayout title="New Page Template!">
    <main>
      <p>New page template!</p>
    </main>
  </BaseLayout>