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を使う場合は、最初から全てのパスをこの方法で統一するのが良さそうです。


GUIコンパイラのPreprosを使ってSassのコンパイルを行う
Dart Sassの変数の基本的な使い方|Dart Sass入門
.htaccessを使って、httpからhttpsへリダイレクトする設定方法
PubSubHubbubを利用してWebサイトの更新をリアルタイムに通知しよう
CSSでclassがついていないタグにだけスタイルを当てる方法
Local by FlywheelでWordPressのローカル開発環境構築のハードルが一気に下がる
Vue.jsを使う人が最低限導入しておきたいVisual Studio Codeの拡張機能
Visual Studio Codeの拡張機能「Trailing Spaces」でコードの中にある余計なスペースを表示する
「epel-release」インストール後にyum installで「Cannot retrieve metalink for repository」と表示される場合の対処法
Visual Studio CodeでToDoコメントを一覧で表示する拡張機能「Todo Tree」
iTerm2で「Use System Window Restoration Setting」を設定しているとアラートが表示されて機能しない
Google Chromeのサイト内検索(カスタム検索)機能を別のプロファイルに移行する方法
iPadで入力モードを切り替えずに数字や記号をすばやく入力する方法
iPhoneやiPadでYouTubeの再生速度を3倍速や4倍速にする方法
Keynoteで有効にしているはずのフォントが表示されない現象
MacのKeynoteにハイライトされた状態でコードを貼り付ける方法
AirPodsで片耳を外しても再生が止まらないようにする方法
iTerm2でマウスやトラックパッドの操作を設定できる環境設定の「Pointer」タブ
DeepLで「インターネット接続に問題があります」と表示されて翻訳できないときに確認すること
Ulyssesの「第2のエディタ」表示を使って2つのシートを横並びに表示する
かゆいところに手が届く「Supercharge」でMac環境を便利にカスタマイズする
超軽量なコードエディタ 「Zed」をサブエディタとして活用する
Bartender 6で追加されたWidgets機能で自作メニューバーアイテムを簡単に作成する
Googleカレンダーを便利に活用するための小技集(祝日だけを表示・月末の繰り返しイベントを追加)
Obsidianを使った「自己流PKM」で行う知識トレーニング
テキストエディタ・ノートアプリ関連のショートカットキーをKeyboard Maestroで統一する
Path Finderを使ってキーボードだけでファイル操作する方法(応用編)
macOSのコマンドパレット比較!SpotlightとAlfred、Raycastどれを使えばいい?
1つのノートアプリにすべて集約するのをやめた理由|2025年時点のノートアプリの使い分け