EJSのincludeで別ファイルを読み込むときの画像パスを指定する方法

EJSを使うと、ヘッダーやフッターなどの共通パーツを別ファイルで管理しておいて、最終的にHTMLとしてコンパイルできるので、あとからヘッダーを修正しないといけないときなどに便利です。
似たようなテンプレートエンジンにPugもありますが、Pugは記法が独特なのに対してEJSはあくまでもHTMLにプラスアルファの機能が付いたイメージなので学習コストが低く、チームメンバー内でとりあえずHTMLが書ければ問題なく作業してもらえるのが大きなメリットです。
そんなEJSの、ファイル分割をするときのパス管理方法についてまとめておきます。
EJSの基本
EJSの基本的なところに関しては、過去に記事にしているのでそちらをご覧ください。
includeのパスを管理
include()を使えば別ファイルを読み込んでコンパイルができます。
ヘッダーやフッターなどの共通部品はもちろん、使い回しのパーツを1つのファイルで管理ができるので修正時にかなりラクになります。
しかし、ヘッダーに画像を使っている場合はパスを「../images/logo.png」のように指定してしまっていると、最終的に生成されたHTMLの階層によってはリンク切れを起こしてしまいます。
絶対パスであれば問題ありませんが、相対パスを使いたい場合は、include()にパス用の変数を渡してあげます。
index.ejs<%
data.path = '../'; //このページの階層を指定
-%>
<%- include('./_common/header', {data:'data'}) %>data.pathをページの最初に定義して、ここにページの階層を指定する「../」を入力します。
階層が深くなると「../../」のように長くなっていきます。
そして、定義したdataをinclude()で別ファイルを読み込むときに{data:'data'}で中に入れてあげます。
パスを指定
次にinclude()するファイル(今回の場合は_header.ejs)を開いて、中のパスを書き換えます。
aタグのリンクや、imgで画像パスを指定している場所を、下記のように変数を組み合わせて記述してばOKです。
_header.ejs
<a href="<%= data.path %>about/">アバウトページへ</a>_header.ejs
<img src="<%= data.path %>images/logo.png/">こうすると、data.pathの値が変わってそれぞれのページがコンパイルされていくので、リンク切れがおきません。
実際にコンパイルされたパスを見ると下記のようになっているはずです。
| ページ(階層) | パス |
|---|---|
| トップページ | ./images/logo.png |
| ・アバウトページ | ../images/logo.png |
| ・・詳細ページ | ../../images/logo.png |
| ・お問い合わせ | ../images/logo.png |
当たり前ですが、data.pathの値が間違っているとリンク切れを起こしてしまうので、間違えないように注意しましょう。
特にファイルをコピーして別ページを作成するときなどは忘れてしまいがちで、前のページのパスの設定が残っていることがあります。
include以外でも使用可能
このパスの指定方法はinclude()外でも使えます。
この指定方法だと階層の移動があったり、コピペで同じ箇所を作るときにもパスを変えてチェックする必要がなかったり、変更し忘れもなくなります。
EJSを使う場合は、最初から全てのパスをこの方法で統一するのが良さそうです。


MAMPでローカル開発環境にWordPressをインストールする手順
横幅が広がったときの挙動が変わる!CSS Gridの「auto-fill」と「auto-fit」の違い
SVGを操作するためのCSSプロパティまとめ
SourceTreeのカスタムアクションを使って差分ファイルだけをまとめる方法
HTMLが書ければすぐ習得できるテンプレートエンジン「EJS」の基本的な書き方
コーディングで「スペース」と「タブ」のどちらを使えばいいのか?
JavaScriptのtest関数と正規表現でバリデーションチェックを行う
属性・Class・IdなどHTMLタグの細かい部分を見ていこう!!
WordPressの自動バックグラウンド更新を無効にする方法とその注意点
SafariのURLメニュー部分も考慮できるCSSの単位「dvh」
iTerm2で「Use System Window Restoration Setting」を設定しているとアラートが表示されて機能しない
Google Chromeのサイト内検索(カスタム検索)機能を別のプロファイルに移行する方法
iPadで入力モードを切り替えずに数字や記号をすばやく入力する方法
iPhoneやiPadでYouTubeの再生速度を3倍速や4倍速にする方法
Keynoteで有効にしているはずのフォントが表示されない現象
MacのKeynoteにハイライトされた状態でコードを貼り付ける方法
AirPodsで片耳を外しても再生が止まらないようにする方法
iTerm2でマウスやトラックパッドの操作を設定できる環境設定の「Pointer」タブ
DeepLで「インターネット接続に問題があります」と表示されて翻訳できないときに確認すること
Ulyssesの「第2のエディタ」表示を使って2つのシートを横並びに表示する
Googleカレンダーを便利に活用するための小技集(祝日だけを表示・月末の繰り返しイベントを追加)
Obsidianを使った「自己流PKM」で行う知識トレーニング
テキストエディタ・ノートアプリ関連のショートカットキーをKeyboard Maestroで統一する
Path Finderを使ってキーボードだけでファイル操作する方法(応用編)
macOSのコマンドパレット比較!SpotlightとAlfred、Raycastどれを使えばいい?
1つのノートアプリにすべて集約するのをやめた理由|2025年時点のノートアプリの使い分け
Notionログイン時の「マジックリンク」「ログインコード」をやめて普通のパスワードを使う
AlfredでNotion内の検索ができるようになるワークフロー「Notion Search」
Gitで1行しか変更していないはずのに全行変更した判定になってしまう