While customizing blog
Last Update: 2025-04-02
I've been trying to customize my blog on github page for years. The first version was using jekyll + github page with a template someone made. While using it, I got feeling to customize small parts of the design, and the codes were getting messy.
Now the new version uses Next.js + react
, and this is a note about it.
Module: parsing markdown
Many mdx libraries are providing way to build html elements from markdown text. I tried to use that but it got me error like:
- "cannot use > or < inside the markdown text without explicitly bracing it with {}"
- "need to use extra plugins for parsing latex syntax"
So I changed the plan to use parsing module separately.
- generate html text not react element
- use
showdown
library for parsing markdown
Example codes are following.
parsing module
import showdown from "showdown";
// Idk well about actual purpose of below config
// But by using it I could prevent parsing $$ signed latex syntax
// Reason for using this is because I need to keep pure $$ signed text to parse it by latex parser
const converter = new showdown.Converter({
literalMidWordUnderscores: true,
})
export function parseMarkdownToHtml(markdown: string): string {
return converter.makeHtml(markdown);
}
inserting the parsed html text
<div dangerouslySetInnerHTML={{ __html: parseMarkdownToHtml(content) }} />
Module: Client-side scripts
I used client side scripts for
- redering the latex text in user's browser.
- highlighting code snippets.
'use client';
import { useEffect } from 'react';
import Script from 'next/script';
import { usePathname } from 'next/navigation';
export function ClientScripts() {
const pathname = usePathname();
// This effect will run on each route change
useEffect(() => {
// Process highlight.js if it's loaded
if (typeof window !== 'undefined' && (window as any).hljs) {
(window as any).hljs.highlightAll();
}
// For MathJax, we need a small delay to ensure content is fully rendered
if (typeof window !== 'undefined' && (window as any).MathJax) {
const MathJax = (window as any).MathJax;
// MathJax v2.x
if (MathJax.Hub) {
MathJax.Hub.Queue(['Typeset', MathJax.Hub]);
}else if (MathJax.typeset) {
// for MathJax v3.x
MathJax.typeset();
}
}
}, [pathname]); // Re-run this effect when the pathname changes
return (
<>
<Script
id="hljs-script"
src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"
strategy="afterInteractive"
onLoad={() => {
const hljs = (window as any).hljs;
hljs.highlightAll();
console.log('hljs loaded');
}}
/>
{/* MathJax */}
<Script
id="mathjax-script"
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"
strategy="afterInteractive"
onLoad={() => {
const MathJax = (window as any).MathJax;
MathJax.Hub.Config({
tex2jax: {
inlineMath: [['$', '$']],
processEscapes: true,
},
TeX: {
extensions: ["AMSmath.js", "AMSsymbols.js", "noErrors.js", "noUndefined.js"],
Macros: {}
},
});
MathJax.Hub.Queue(['Typeset', MathJax.Hub]);
console.log('MathJax loaded');
}}
/>
</>
);
}