Freshでダークモードを切り替え時にPrism.jsも更新する

作成日
更新日

Freshでダークモードを切り替え時にPrism.jsも更新する。

ダークモード対応はFreshでダークモード対応をするにて実装済み。

islandsで切り替える

Signaltheme が定義されているので、それを監視して利用する。

islands/PrismThemeSwitcher.tsx
export default function PrismThemeSwitcher() {
  useEffect(() => {
    function applyPrismTheme(isDark: boolean) {
      const linkId = "prism-theme-link";
      const existing = document.getElementById(linkId) as HTMLLinkElement | null;
      const href = isDark ? DARK_THEME : LIGHT_THEME;

      if (existing) {
        existing.href = href;
      } else {
        const link = document.createElement("link");
        link.id = linkId;
        link.rel = "stylesheet";
        link.href = href;
        document.head.appendChild(link);
      }
    }

    // 初回適用
    applyPrismTheme(isDarkMode.value);

    // signal の変化を購読
    const dispose = isDarkMode.subscribe(applyPrismTheme);

    return () => dispose();
  }, []);

  return null;
}

つかう

pageから呼び出す。id="prism-theme-link" を指定してislandから置き換えられるようにする。

/routes/[slug].tsx
export default function PostPage({ data }: PageProps) {
  const { post } = data;
  return (
    <>
      <Head>
        <style dangerouslySetInnerHTML={{ __html: CSS }} />
        <link
          rel="stylesheet"
          id="prism-theme-link" // これが必要
          href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css"
        />
      </Head>
      <PrismThemeSwitcher />
      <PostContent post={post} />
    </>
  );
}

まとめ

そもそも Prism.js がdeno/gfmと互換性がないからダメ! jsも読み込まないとダメ。

Freshでダークモード切り替え時にシンタックスハイライトも更新したい

サイトアイコン
公開日
更新日