I wondered if it is possible to do syntax highlighting under these two criterias:
- Without shipping syntax parser to the client (huge bundle size)
- Without doing dangerouslySetInnerHTML (prone to XSS)
So I figured to use refractor (https://github.com/wooorm/refractor) to do the syntax highlighting, which converts the code using Prism.js (https://github.com/PrismJS/prism) into unist (https://github.com/syntax-tree/unist) AST in compile time / on server side. On client side, this AST is hydrated using rehype-react (https://github.com/rehypejs/rehype-react)
# Demo def fib(n): a, b = 0, 1 while a < n: print(a, end=' ') a, b = b, a+b print() fib(1000)
Even the styling for this code block above is encapsulated into a CSS Module (https://github.com/css-modules/css-modules) so it won’t increase the CSS file size for the rest of the site.