Integrating Expressive Code in My Existing Astro JS Website
Context or Problem
For those who want to do it on your site just open their official docs and do it on your own.
Anyways, I just want to write the next episode from my last journal about encountering expressive code after take lot of time configuring another tools for it which is not bad, because I really learn much new things especially in CSS selector that using data[blabla]
and rehype
ecosystem.
For today challenge this may be just another refactoring things but I believe this is worth the time investment on it while I have too much free time too LOL.
Let’s see how I can integrate astro-expressive-code
to my existing Astro JS website that fortunately not really have much articles or components yet so it shouldn’t be that hard.
Experiment
I start by writing this artile and make sure I have journal on everything I do in my daily random debugging time.
First I will just install astro-expressive-code
and see if it conflicted with my existing spaghetti codebase.
npx astro add astro-expressive-code
Then try to run the project but I got this error message:
Incorrect integration order: To allow code blocks on MDX pages to use astro-expressive-code, please move astroExpressiveCode() before mdx() in the “integrations” array of your Astro config file.
So I tried to just comments all existing rehype-pretty-code
part while following that info to see if it will works or not.
And everything works as I expected with default theme. Now I can just maybe steal my configuration from my testing project available on my other repo to be like this.
// @ts-checkimport { defineConfig } from "astro/config";import tailwindcss from "@tailwindcss/vite";
import expressiveCode, { ExpressiveCodeTheme } from "astro-expressive-code";import mdx from "@astrojs/mdx";
// @ts-ignoreimport fs from "node:fs";
// Load your saved theme JSONC file here and create a theme from itconst jsoncString = fs.readFileSync( new URL(`./beautiful-dracula.json`, import.meta.url), "utf-8",);const beautifulDracula = ExpressiveCodeTheme.fromJSONString(jsoncString);
// https://astro.build/configexport default defineConfig({ vite: { plugins: [tailwindcss()], }, integrations: [ expressiveCode({ themes: [beautifulDracula], }), mdx(), ],});
But it took long time to see the refreshed page. So I just restart the npm run dev
command and see what will happen.
Well now it works! guess maybe my intel celeron devices can’t handle that config reload that fast haha.
Now I need to see my other published journal and make some, wait better I get rid of the custom css that I placed before to style rehype-pretty-code
.
Now that everything works fine and my Tailwind CSS configuration simplified it’s a great time to rewrite some of my published journal .mdx
file to make sure it didn’t break and also applied some features offered by expressive code to it.
I notice a little breaking changes, for inline code like
`let data = []{:js}` or `<Tag>{:html}`
Using rehype-pretty-code
will have syntax highlighting too like this
but, when I am using astro-expressive-code
it didn’t work.
I will look if it can be styled by expressive code or I need to write custom css only for that inline code.
After doing some research (googling) I found, that feature is not available right now but still have posibility to come in future.
https://github.com/expressive-code/expressive-code/issues/250
So yeah I will just create custom CSS for it. The best thing I can do for it is just using the same background as the VSCode theme. I also need to get rid of tailwind typography prose css that automatically adding backticks
tag on after::
and before::
. End result was something like this
/* Using direct rsms css file to have curly quotes etc, google font suck */@import url("https://rsms.me/inter/inter.css");@import "tailwindcss";@plugin "@tailwindcss/typography";
@theme { --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /*"liga" 1, "calt" 1 used to fix for Chrome */ --font-sans--font-feature-settings: "liga" 1, "calt" 1, "ss02", "ss08";}
.prose code { @apply bg-[#1e1e2f] font-mono text-sm text-[#c1c1cb]; margin-block: -0.125rem; padding: 0.125rem 0.375rem;}
Adjusting the tailwind prose to not show additional backticks
on inline code.
Dunno if this is the correct way to do it but it works.
<articleclass="mx-auto w-full max-w-3xl rounded-lg p-6 text-neutral-200 shadow prose-headings:text-neutral-300 prose-code:before:hidden prose-code:after:hidden"> <!-- Contents --></article>
Other things to consider is by default expressive code doesn’t have showLineNumbers
except using a plugin but for now it was fine. Line number still usefull in future or in specific learning materials for student I bet, but for my journaling use cases it should be enough.
I also encountering stupid bug on my codebase (of course) that cause wrapped codeblock to just always make it overflowing inline in long text inside a codeblock even if it’s already have wrap
tag.
I thought it was an issue on astro-expressive-code
, but turn out it because my old custom component code for rehype-pretty-code
which is CodeBlock.astro
and mapped to <Content components={MDXComponentMapping} />
tag are the main problem. I spend that night and this morning, even reinstalling everything on this project LOL.
So I just remove it and not use any custom mdx component for code
and pre
at all and now everything works fine!
Outcome
Working fine codeblock highlighted with my favorite VSCode theme.
Altought is not works on inline
code like this
it’s fine.
It already have copy to clipboard button for some lazy people out there (like me).
Possible Next Steps
Keep writing and have muscle memory on using it on future journals.