Shiki with eleventy

Syntax highlighting in Eleventy 3.0 with Shiki was never simpler than this

  • Back
  • Integrating Shiki for syntax highlighting in a couple of lines with Eleventy 3.0 (alpha 19 at the time of writing).

    This builds up on How I use Shiki in Eleventy by Stefan Zweifel who also built his solution upon Using shiki with 11ty by Raphael Höser.

    This solution uses some hot out of the oven features like the new TypesScript JSDoc @import Tag and the Eleventy 3.0 alpha which now allows async plugin functions and therefore no longer the workaround to get Shiki working.

    Create a function that will act as a plugin and add it as a plugin in your eleventy configuration.

    import { createHighlighter } from "shiki";
    /**
     * New TypeScript 5.5 JSDoc import syntax
     * @import { BundledLanguage, BundledTheme } from "shiki"
     * @import { UserConfig } from "@11ty/eleventy"
     * @typedef {{ theme: BundledTheme, languages: BundledLanguage[], themes: BundledTheme[] }} Options
     */
    
    /**
     * @param {UserConfig} configuration
     * @param {Options} options
     */
    async function shikiPlugin(configuration, options) {
      const highlighter = await createHighlighter(options);
      configuration.amendLibrary("md", (library) => {
        library.set({
          highlight: (code, language) => {
            return highlighter.codeToHtml(code, {
              lang: language,
              theme: options.theme,
            });
          },
        });
      });
    }
    
    /** The eleventy configuration function
     * @param {UserConfig} configuration
     */
    export default function (configuration) {
      configuration.addPlugin(
        shikiPlugin,
        /** @type {Options} */ ({
          // Choose your theme
          theme: "dark-plus",
          // Define themes to be loaded
          themes: ["dark-plus"],
          // Choose your highlighted languages
          // It is kind of a hassle to define each language beforehand but at least this doesn't silently break highlighting
          langs: [
            "bash",
            "html",
            "toml",
            "rust",
            "groovy",
            "kotlin",
            "ruby",
            "swift",
          ],
        })
      );
    }
    

    If you don't want to load languages manually, you can import bundledLanguages or bundledThemes from shiki Object.keys it to get all the values but this is not recommended by shiki.