JavaScriptで文字列に改行を含める方法といえば\nが定番ですが、テンプレートリテラル(バッククォート)を使えばエスケープなしで改行をそのまま書けます。
この記事では、テンプレートリテラルの基本から、配列 + join、String.raw、改行を含む正規表現まで、エスケープせずに改行を扱う方法を網羅的に解説します。
この記事で学べること
- テンプレートリテラルで改行をそのまま含める基本構文
- 式の埋め込み(
${})と複数行文字列の組み合わせ
- 配列 + joinで改行を挿入する方法
- String.rawでエスケープシーケンスを無効化する方法
- HTMLテンプレート生成の実務パターン
\n vs テンプレートリテラルの比較と使い分け
- 改行を含む文字列の注意点とインデント対策
テンプレートリテラルで改行を含める(基本)
ES2015(ES6)で導入されたテンプレートリテラルは、バッククォート(`)で囲む文字列です。ソースコード上の改行がそのまま文字列に含まれます。
テンプレートリテラルで改行
const message = `1行目
2行目
3行目`;
console.log(message);
ダブルクォートやシングルクォートで同じことを書くと、\nを使う必要があります。
従来の方法(\nが必要)
// \n を使ったエスケープが必要
const message = "1行目\n2行目\n3行目";
// 文字列連結で改行を入れる方法もあるが冗長
const message2 = "1行目\n" +
"2行目\n" +
"3行目";
ポイント:テンプレートリテラルを使えば\nや+による連結が不要になり、コードの可読性が大幅に向上します。
式の埋め込み(${})と複数行文字列
テンプレートリテラルの最大の特徴は、改行と式の埋め込みを同時に使えることです。
変数・式の埋め込み
const name = "田中";
const age = 30;
const profile = `名前: ${name}
年齢: ${age}歳
来年: ${age + 1}歳`;
console.log(profile);
実行結果
名前: 田中
年齢: 30歳
来年: 31歳
${}の中には変数だけでなく、関数呼び出しや三項演算子などの式も書けます。
式・関数の埋め込み
const items = ["りんご", "みかん", "バナナ"];
const report = `商品数: ${items.length}個
一覧: ${items.join(", ")}
先頭: ${items[0].toUpperCase()}`;
console.log(report);
実行結果
商品数: 3個
一覧: りんご, みかん, バナナ
先頭: りんご
HTMLテンプレートの生成(実務パターン)
テンプレートリテラルが最も活躍するのがHTML文字列の生成です。改行とインデントをそのまま書けるため、HTMLの構造が一目で分かります。
HTMLテンプレートの生成
function createCard(user) {
return `<div class="card">
<h2>${user.name}</h2>
<p>${user.email}</p>
<span class="role">${user.role}</span>
</div>`;
}
const html = createCard({
name: "田中太郎",
email: "tanaka@example.com",
role: "管理者"
});
console.log(html);
実行結果
<div class="card">
<h2>田中太郎</h2>
<p>tanaka@example.com</p>
<span class="role">管理者</span>
</div>
配列をループしてリストを生成
mapとjoinでリスト生成
const fruits = ["りんご", "みかん", "バナナ"];
const list = `<ul>
${fruits.map(f => ` <li>${f}</li>`).join("\n")}
</ul>`;
console.log(list);
実行結果
<ul>
<li>りんご</li>
<li>みかん</li>
<li>バナナ</li>
</ul>
配列 + join で改行を挿入する
テンプレートリテラルとは別のアプローチとして、配列の各要素を改行文字で結合する方法があります。
配列 + join
const lines = [
"1行目: ヘッダー",
"2行目: 本文",
"3行目: フッター"
];
const text = lines.join("\n");
console.log(text);
実行結果
1行目: ヘッダー
2行目: 本文
3行目: フッター
この方法は動的に行を追加・削除したい場合に便利です。
条件に応じて行を追加
const isAdmin = true;
const lines = [
"ユーザー: 田中太郎",
"メール: tanaka@example.com",
];
// 条件に応じて行を追加
if (isAdmin) {
lines.push("権限: 管理者");
}
console.log(lines.join("\n"));
実行結果
ユーザー: 田中太郎
メール: tanaka@example.com
権限: 管理者
String.raw でエスケープを無効化する
String.rawはタグ付きテンプレートリテラルの一種で、\nや\tなどのエスケープシーケンスをそのままの文字列として扱います。
String.raw の動作
// 通常のテンプレートリテラル → \n が改行になる
const normal = `Line1\nLine2`;
console.log(normal);
// Line1
// Line2
// String.raw → \n がそのまま文字列になる
const raw = String.raw`Line1\nLine2`;
console.log(raw);
// Line1\nLine2
String.raw の活用場面
ファイルパスや正規表現を書きやすくする
// Windowsのファイルパス(\をエスケープ不要)
const path = String.raw`C:\Users\tanaka\Documents`;
console.log(path);
// C:\Users\tanaka\Documents
// 正規表現パターンの記述
const pattern = String.raw`\d{3}-\d{4}`;
const regex = new RegExp(pattern);
console.log(regex.test("123-4567"));
// true
注意:String.rawはエスケープシーケンスを無効化しますが、${}による式の埋め込みは通常通り動作します。
改行を含める方法の比較
| 方法 |
構文 |
特徴 |
適した場面 |
| \n エスケープ |
"行1\n行2" |
ES5以前でも使える |
短い文字列、レガシー環境 |
| テンプレートリテラル |
`行1(改行)行2` |
改行・式埋め込みが自然 |
HTML生成、複数行テキスト |
| 配列 + join |
["行1","行2"].join("\n") |
動的に行を操作可能 |
条件付きの行追加・削除 |
| String.raw |
String.raw`\n` |
エスケープを無効化 |
パス、正規表現パターン |
注意点:インデントが文字列に含まれる
テンプレートリテラルはソースコードの改行・空白がそのまま文字列に入ります。関数内で使うと不要なインデントが含まれることがあります。
インデントが含まれる問題
function getMessage() {
return `1行目
2行目
3行目`; // ← 2行目・3行目の先頭にスペースが入る
}
console.log(getMessage());
対策1: 行頭を揃える
行頭を左端に揃える
function getMessage() {
return `1行目
2行目
3行目`; // ← 見た目は崩れるが出力は正しい
}
対策2: 共通インデントを除去するヘルパー関数
dedent関数で共通インデントを除去
function dedent(str) {
const lines = str.split("\n");
const nonEmpty = lines.filter(l => l.trim());
const minIndent = Math.min(
...nonEmpty.map(l => l.match(/^\s*/)[0].length)
);
return lines.map(l => l.slice(minIndent)).join("\n").trim();
}
const html = dedent(`
<div>
<p>Hello</p>
</div>
`);
console.log(html);
実行結果
<div>
<p>Hello</p>
</div>
ポイント:npmパッケージのdedentを使えば、同様の処理をより手軽に実現できます。
タグ付きテンプレートリテラル
テンプレートリテラルの前に関数名を付けると、文字列の処理をカスタマイズできます。これをタグ付きテンプレートリテラルと呼びます。
タグ付きテンプレートリテラルの例
function highlight(strings, ...values) {
return strings.reduce((result, str, i) => {
const value = values[i] !== undefined
? `<strong>${values[i]}</strong>`
: "";
return result + str + value;
}, "");
}
const name = "田中";
const role = "管理者";
const msg = highlight`${name}さんは
${role}です`;
console.log(msg);
実行結果
<strong>田中</strong>さんは
<strong>管理者</strong>です
タグ付きテンプレートの活用例
- String.raw: エスケープ無効化(前述)
- HTMLエスケープ: XSS対策として埋め込み値をサニタイズ
- 国際化(i18n): 翻訳キーの解決
- CSS-in-JS: styled-componentsなどで使用
ブラウザ対応状況
| ブラウザ / 環境 |
テンプレートリテラル |
String.raw |
| Chrome |
41+ |
41+ |
| Firefox |
34+ |
34+ |
| Safari |
9+ |
9+ |
| Edge |
12+ |
12+ |
| Node.js |
4+ |
4+ |
| IE 11 |
非対応 |
非対応 |
ポイント:IE11を除くすべてのモダンブラウザで対応しています。IE11対応が必要な場合はBabelなどのトランスパイラを使用してください。
よくある質問(FAQ)
Q. JavaScriptで複数行文字列を1行にまとめるには?
A. replace(/\n/g, ” “)で改行をスペースに置換するか、split(“\n”).join(” “)で分割後結合します。複数の連続スペースはreplace(/\s+/g, ” “)で1つにまとめられます。
Q. テンプレートリテラルの余分なインデントを取り除くには?
A. 各行を分割してtrim()し、再度join(“\n”)します。またはdedentライブラリを使う方法もあります。ES2025で提案中のString.dedent()が将来的に標準化される予定です。
Q. 改行の種類(\r\n、\n、\r)を統一するには?
A. replace(/\r\n|\r/g, “\n”)でWindowsとMacの改行コードをUnix形式に統一できます。逆にWindows形式にするにはreplace(/\n/g, “\r\n”)を使います。
まとめ
| 用途 |
推奨方法 |
理由 |
| 複数行テキスト・HTML生成 |
テンプレートリテラル |
改行と式埋め込みが自然 |
| 動的な行の追加・削除 |
配列 + join |
条件に応じた行操作が容易 |
| パス・正規表現パターン |
String.raw |
\をエスケープ不要 |
| レガシー環境(IE11) |
\n エスケープ |
ES5互換 |
改行を含む文字列を扱う場面では、まずテンプレートリテラルを検討しましょう。\nのエスケープが不要になり、コードの可読性と保守性が向上します。
関連記事