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


npm-scriptsでSCSSをコンパイルする環境を構築する方法
gulp 4.0から新しく加わったseriesとparallelについての備忘録
WordPressのメディアライブラリで画像を追加するときに表示される「HTTP エラー」の解消方法
「Dart Sass」「LibSass」「Ruby Sass」などSassの種類や記法に関するまとめ
様々な作業を自動化するgulpの基礎と導入方法
「とりあえず無料版!」ではなく、機能を知った上で判断したいMAMPとMAMP PROの比較
PS Auto Sitemapを使って自分のブログのサイトマップを作成する
Visual Studio Codeの拡張機能「Trailing Spaces」でコードの中にある余計なスペースを表示する
スクロールしてもテーブルヘッダーが追尾するテーブルの作り方
Vue.jsで値段を表示するときに3桁ごとにカンマを入れる方法
iTerm2で「Use System Window Restoration Setting」を設定しているとアラートが表示されて機能しない
Google Chromeのサイト内検索(カスタム検索)機能を別のプロファイルに移行する方法
iPadで入力モードを切り替えずに数字や記号をすばやく入力する方法
iPhoneやiPadでYouTubeの再生速度を3倍速や4倍速にする方法
Keynoteで有効にしているはずのフォントが表示されない現象
MacのKeynoteにハイライトされた状態でコードを貼り付ける方法
AirPodsで片耳を外しても再生が止まらないようにする方法
iTerm2でマウスやトラックパッドの操作を設定できる環境設定の「Pointer」タブ
DeepLで「インターネット接続に問題があります」と表示されて翻訳できないときに確認すること
Ulyssesの「第2のエディタ」表示を使って2つのシートを横並びに表示する
テキストエディタ・ノートアプリ関連のショートカットキーをKeyboard Maestroで統一する
Path Finderを使ってキーボードだけでファイル操作する方法(応用編)
macOSのコマンドパレット比較!SpotlightとAlfred、Raycastどれを使えばいい?
1つのノートアプリにすべて集約するのをやめた理由|2025年時点のノートアプリの使い分け
Notionログイン時の「マジックリンク」「ログインコード」をやめて普通のパスワードを使う
AlfredでNotion内の検索ができるようになるワークフロー「Notion Search」
Gitで1行しか変更していないはずのに全行変更した判定になってしまう
Macでアプリごとに音量を調節できるアプリ「Background Music」
Macのターミナルでパスワード付きのZIPファイルを作成する方法