【highlight.js】シンタックスハイライトの導入と設定方法まとめ

【highlight.js】シンタックスハイライトの導入と設定方法まとめ JavaScript

highlight.js は、コードブロックに自動で色付けを行う軽量なライブラリです。CDNから1ファイル読み込むだけでも動作し、言語の個別読み込み・テーマ切り替え・行番号・コピーボタンなどを段階的に追加できます。この記事では導入から実運用の初期化、ダークモード対応、パフォーマンスやアクセシビリティの配慮まで一通りまとめます。

この記事でわかること

  • CDN / npm での導入と、言語の個別読み込みによる軽量化
  • 言語指定と自動判定の使い分け
  • テーマ切り替えと prefers-color-scheme でのダークモード対応
  • 行番号(公式プラグイン)とコピーボタンの追加
  • 遅延読み込み・WordPress設置・競合回避・トラブルシュート
この記事のバージョン:highlight.js は本記事執筆時点の最新 11.11.1 を例にしています。CDNのURLに含まれるバージョン番号は、利用時に最新版へ読み替えてください。
スポンサーリンク

最短導入(CDN)で今すぐハイライトする

HTMLにテーマCSSと本体JSを読み込み、hljs.highlightAll() で自動初期化します。コードブロックは <pre><code> で囲み、言語クラス(language-xxx)を付けるか自動判定に任せます。

HTML:CDNで最短導入
<!-- テーマ(スタイル) -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github.min.css">

<!-- 本体 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>

<!-- 自動初期化 -->
<script>hljs.highlightAll();</script>

<!-- 例:言語を明示したコードブロック -->
<pre><code class="language-javascript">
const hello = (name) => console.log(`Hello, ${name}`);
hello("world");
</code></pre>

言語の個別読み込みで軽量化する

すべての言語を含むビルドは手軽ですがファイルサイズが大きくなります。対象言語が限られるなら、本体に加えて必要な言語だけ追加読み込みします。

HTML:必要な言語だけ追加
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/javascript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/php.min.js"></script>
<script>hljs.highlightAll();</script>
最小構成にすると速い
自動判定を使う場合でも、読み込まれていない言語は判定候補になりません。サイトで実際に使う言語だけに絞ると、ダウンロード量と描画コストを抑えられます。

npm で導入してビルドに組み込む

ビルド環境に統合するなら npm を使い、必要言語だけを登録します。テーマCSSもパッケージから読み込めます。

npm:インストール
npm i highlight.js
JavaScript:必要言語だけ登録(core ビルド)
import hljs from 'highlight.js/lib/core';
import javascript from 'highlight.js/lib/languages/javascript';
import php from 'highlight.js/lib/languages/php';
import 'highlight.js/styles/github.css';

hljs.registerLanguage('javascript', javascript);
hljs.registerLanguage('php', php);
hljs.highlightAll();

言語指定と自動判定の使い分け

クラスで言語を明示すれば誤判定を防げます。複数言語が混在する記事では明示を基本にし、未指定のコードだけ自動判定に任せる構成が安定します。

HTML:言語を明示する
<pre><code class="language-css">
.button { background: #0aa; color: #fff; }
</code></pre>

テーマの切り替えとダークモード対応

highlight.js は多数のテーマを同梱しています。OSのダークモードに合わせて自動で切り替えるには prefers-color-scheme を使います。

HTML:prefers-color-scheme で自動切り替え
<!-- 通常(ライト) -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github.min.css">
<!-- ダーク時だけ上書き -->
<link rel="stylesheet" media="(prefers-color-scheme: dark)"
      href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github-dark.min.css">

手動トグルにするなら、テーマ用 link 要素の href を差し替えれば即時反映されます。サイト全体のダークモード実装はWebサイトにダークモードを実装する方法も参考にしてください。

行番号を付けたいときは公式プラグインを使う

highlight.js 本体に行番号機能は含まれていません。最も安全なのは、互換プラグイン highlightjs-line-numbers.js を使う方法です。ハイライト後に hljs.initLineNumbersOnLoad() を呼ぶだけで行番号が付きます。

HTML:行番号プラグイン
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.8.0/highlightjs-line-numbers.min.js"></script>
<script>
  hljs.highlightAll();
  hljs.initLineNumbersOnLoad(); // ハイライト後に行番号を付与
</script>
自作の「改行で分割して span 化」は壊れる
ハイライト後の innerHTML を改行で分割し、各行を <span> で囲む自作スクリプトは避けてください。highlight.js の出力には複数行にまたがる <span>(ブロックコメントや複数行文字列など)があり、改行で機械的に分割するとタグが途中で切れて表示が崩れます。行番号は構造を理解しているプラグインに任せるのが安全です。

コピー用ボタンを後付けする

読者がコードをコピーしやすいよう、各ブロックにボタンを動的に追加します。クリップボードAPIを使えば数行で実装できます。

JavaScript:コピーボタンを追加
document.querySelectorAll('pre').forEach(pre => {
  const btn = document.createElement('button');
  btn.className = 'copy-btn';
  btn.type = 'button';
  btn.textContent = 'Copy';
  btn.addEventListener('click', async () => {
    const code = pre.querySelector('code')?.innerText ?? '';
    try {
      await navigator.clipboard.writeText(code);
      btn.textContent = 'Copied!';
      setTimeout(() => (btn.textContent = 'Copy'), 1500);
    } catch { btn.textContent = 'Error'; }
  });
  pre.style.position = 'relative';
  btn.style.position = 'absolute';
  btn.style.top = '8px';
  btn.style.right = '8px';
  pre.appendChild(btn);
});
navigator.clipboard はHTTPS必須
クリップボードAPIはセキュアコンテキスト(HTTPS または localhost)でのみ動作します。HTTPの本番環境では使えないため、http:// での確認時は注意してください。フォールバックや成功通知を含む実装はクリップボードにコピーする方法(Clipboard API・writeText・HTTPS制限)にまとめています。

遅延読み込みで描画ブロックを避ける

初回表示を速くしたいときは、CSSは先に読み込み、JSは defer で遅延させ、読み込み完了後に初期化します。

HTML:defer で遅延初期化
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github.min.css">
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
<script>
  window.addEventListener('load', () => hljs.highlightAll());
</script>

WordPress での設置ポイントと競合回避

テーマに組み込むなら wp_enqueue_scripts でCSSとJSを登録します。インラインスクリプトは wp_add_inline_script で本体に紐づけると読み込み順を保てます。

PHP:functions.php で enqueue
<?php
add_action('wp_enqueue_scripts', function () {
  wp_enqueue_style('hljs-theme',
    'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github.min.css',
    [], null);
  wp_enqueue_script('hljs-core',
    'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js',
    [], null, true);
  wp_add_inline_script('hljs-core', 'hljs.highlightAll();');
});
二重ハイライトに注意
すでにプラグインが別ライブラリ(Prism など)を読み込んでいると、二重にハイライトされて表示が崩れます。どちらか片方に統一してください。enqueue の基本はwp_enqueue_scriptの使い方wp_enqueue_styleの使い方を参照してください。

アクセシビリティとセキュリティの注意点

テーマによっては文字色と背景のコントラストが不足します。特に暗色テーマではコントラスト比をチェックし、必要に応じてCSSで補正します。

ユーザー生成コンテンツは必ずエスケープ
コメント欄など利用者が入力したコードをハイライトする場合は、サーバー側でHTMLエスケープしてから出力し、ライブラリにスクリプトを実行させない設計にします。highlight.js はエスケープ済みのテキストに色を付けるためのもので、XSS対策の代わりにはなりません。

トラブルシューティングの要点

色が付かないときは、初期化関数の呼び出し漏れ・言語の未読み込み・クラス名の違いが典型です。Ajax などで後から挿入したコードが無色のままなら、挿入後にその要素を個別にハイライトします。表示が崩れる場合はテーマCSSとサイト側のコードブロックCSSの競合を疑います。

JavaScript:後から追加した要素を個別にハイライト
// Ajax 等で後から追加した要素に適用(highlightBlock は非推奨)
const el = document.querySelector('#ajax-code code');
hljs.highlightElement(el);

よくある質問(FAQ)

Qhighlight.jsとは何ですか?
AWebページでコードのシンタックスハイライト(色付け表示)を行うJavaScriptライブラリです。190以上の言語に対応し、CSSテーマで見た目を変更できます。
Q基本的な使い方は?
ACDNまたはnpmで読み込み、hljs.highlightAll() を呼ぶと pre > code 要素が自動でハイライトされます。言語を指定するには class="language-python" のようにクラスを付けます。
Q行番号を付けるには?
A本体に行番号機能は無いため、互換プラグイン highlightjs-line-numbers.js を読み込み、hljs.initLineNumbersOnLoad() を呼びます。ハイライト後の innerHTML を改行で分割する自作スクリプトは、複数行にまたがるタグを壊すため避けてください。
Qデフォルトテーマを変更するには?
ACSSテーマファイルを切り替えます。CDNから highlight.js/styles/テーマ名.min.css を読み込むか、npmからインポートします。githubmonokaiatom-one-dark など多数あります。
Qコピーボタンが動きません。
Anavigator.clipboardHTTPSまたはlocalhostでのみ動作します。HTTPの環境では使えないため、本番はHTTPS化が前提です。詳しくはクリップボードにコピーする方法を参照してください。

まとめ

  • 導入:CDNなら数行。使う言語だけ個別読み込みで軽量化
  • 言語:複数混在は明示が基本、未指定だけ自動判定
  • ダークモードprefers-color-scheme でテーマCSSを切り替え
  • 行番号:公式プラグインに任せる(自作の改行分割は壊れる)
  • コピー:クリップボードAPIはHTTPS必須
  • WordPress:enqueueに集約し、他ライブラリとの二重ハイライトを避ける

小さく始めて必要な分だけ機能を足していけば、運用負荷を抑えつつ読みやすい技術記事を安定して提供できます。