tailwind.config = {
theme: {
extend: {
fontFamily: {
sans: [‘”Noto Sans JP”‘, ‘sans-serif’],
},
colors: {
base: ‘#f4f9fc’, /* Clean light blue-gray background */
surface: ‘#ffffff’, /* Card background */
primary: ‘#3a8bcd’, /* Sky Blue */
secondary: ‘#b3daf1’, /* Soft pastel blue */
accent: ‘#1ca0a0’, /* Refreshing teal/mint for highlights */
textMain: ‘#2c3e50’, /* Deep slate blue for high readability */
textMuted: ‘#5e7388’ /* Cool gray-blue for secondary text */
}
}
}
}
body {
background-color: #f4f9fc;
color: #2c3e50;
}
/* Custom Scrollbar for a polished look matching the water theme */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: #f4f9fc;
}
::-webkit-scrollbar-thumb {
background: #b3daf1;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: #3a8bcd;
}.chart-container {
position: relative;
width: 100%;
max-width: 1000px; /* Expanded max-width for wider view */
margin-left: auto;
margin-right: auto;
height: 350px;
max-height: 450px;
}
@media (min-width: 768px) {
.chart-container {
height: 400px;
}
}.glossary-card {
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.glossary-card:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px -5px rgba(58, 139, 205, 0.1);
border-color: #3a8bcd;
}.category-btn.active {
background-color: #3a8bcd;
color: #ffffff;
border-color: #3a8bcd;
}
.fade-in {
animation: fadeIn 0.4s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
Delivered -> Opened -> Clicked.
– Interaction: Dynamic slider inputs that recalculate values in real-time.
– Technology: Chart.js with responsive configuration, wrapped in styled wide containers.
–>
✉️はじめてのメールマーケティング
初心者向けの用語集と、成果が感覚でわかるシミュレーター
このアプリケーションについて
メールマーケティングは、顧客との継続的なコミュニケーションを築く上で最も強力な手法の一つです。しかし、「開封率」や「オプトイン」「SPF認証」など、専門用語が多くて戸惑うことも少なくありません。
このツールでは、基礎用語をわかりやすく整理した辞典に加え、実際の数字がどのように顧客アクションへ繋がっていくのかを視覚的に体験できるシミュレーターを用意しました。まずは上の数値を操作して仕組みを体感し、各ステップの意味を用語集で深掘りしてみましょう。
数値シミュレーター:配信からクリックまでの流れ
リスト数や到達率、開封率を調整して、最終的に何人がサイトへ遷移(クリック)するかシミュレーションしてみましょう。
各種パラメータ設定
3 %
全体配信数に対し、リンクを押した割合
メールマーケティング基礎用語辞典
実務でよく使われる重要な専門用語を噛み砕いて解説します。
オプトイン
Opt-in
ユーザーが企業に対して「メールマガジンなどを送っても良いですよ」と事前に許可を出すこと。日本の法律(特電法)では、原則としてこのオプトインを得ていない相手への広告メール送信は禁止されています。
例:「メルマガを受け取る」のチェックボックスにチェックを入れる行為。
オプトアウト
Opt-out
ユーザーが「もうメールを送らないでください」と受信拒否(配信停止)をすること。メールの文末に必ず配信停止できるリンク(オプトアウト導線)を設置することが法律で義務付けされています。
例:メルマガの下部にある「配信停止はこちら」のリンクをクリックすること。
セグメンテーション
Segmentation
顧客リストを特定の条件(年齢、性別、購入履歴、居住地など)でグループ分けすること。全員に同じメールを送るのではなく、グループごとに興味を持ちそうな内容を送るために行います。
例:「過去半年間に購入がない20代女性」だけを抽出して特別なクーポンを送る。
パーソナライズ
Personalization
メールの内容を、受信者一人ひとりに合わせてカスタマイズすること。一番簡単な例は、件名や本文に「〇〇様」と相手の名前を自動で挿入することです。
例:件名:「山田様へ、お誕生日月限定の特別オファーです」
HTMLメール
HTML Email
Webページのように、画像を入れたり、文字の色や大きさを変えたり、ボタンを配置したりできるデザイン性の高いメールのこと。開封率を正確に計測できるのが大きなメリットです。
例:ネットショップから届く、写真付きの綺麗なレイアウトのメルマガ。
テキストメール
Text Email
文字と記号だけで構成されたシンプルなメール。容量が軽く、どんな環境でも確実に表示されるのがメリットですが、画像は使えず、開封率の計測もできません。
例:システムからの注文完了通知や、業務連絡のようなシンプルなメール。
ステップメール
Step Email
ユーザーが特定のアクション(資料請求や購入など)をした日を起点として、あらかじめ準備しておいた複数のメールを、スケジュール通りに順番に自動配信する仕組み。
例:会員登録直後に「お礼」、3日後に「使い方の案内」、7日後に「プレミアムプランの案内」を自動で送る。
バウンス (エラーメール)
Bounce
宛先不明や受信箱がいっぱいなどの理由で、相手に届かずに戻ってきてしまったエラーメールのこと。バウンスを放置して送り続けると、スパム業者と判定されるリスクが高まります。
例:退職して使われなくなったアドレス宛に送り、エラーで返ってくる状態(ハードバウンス)。
到達率 (配信成功率)
Delivery Rate
送信したメールのうち、エラーにならずに無事に相手のサーバーまで届いた割合。これが低い場合は、リストが古くなっている(無効なアドレスが多い)可能性があります。
例:式:到達数 ÷ 送信総数 × 100
開封率
Open Rate
無事に届いたメールのうち、実際に開いて読まれた割合。メールの「件名(タイトル)」と「送信者名」の魅力度が、この数字を大きく左右します。
例:式:開封数 ÷ 到達数 × 100
クリック率 (CTR)
Click Through Rate
メールが届いた人(または開封した人)のうち、メール内のURLやボタンがクリックされた割合。メールの「本文の内容(オファー)」が魅力的だったかを測る指標です。
例:式:クリック数 ÷ 到達数 × 100 (※開封数を分母にする場合もあります)
コンバージョン率 (CVR)
Conversion Rate
メールのリンクをクリックしてWebサイトに訪れた人のうち、最終的な目標(商品購入、資料請求、会員登録など)を達成した人の割合。
例:式:目標達成数 ÷ クリック数 × 100
迷惑メール (スパム)
Spam
受信者の許可なく一方的に大量送信されるメールのこと。ISP(プロバイダ)の迷惑メールフィルターに引っかかると、正当なメールであっても迷惑メールフォルダに入ってしまいます。
例:件名が過激だったり、怪しいリンクが大量に含まれているメール。
特定電子メール法
Anti-Spam Law (Japan)
迷惑メールを防ぐための日本の法律。「事前の同意(オプトイン)を得ること」「送信者情報の表示義務」「配信停止(オプトアウト)導線の設置義務」などが定めされています。違反すると罰則があります。
例:メルマガを始める際、必ず守らなければならないルールの基本。
送信ドメイン認証 (SPF/DKIM/DMARC)
Sender Authentication
「なりすましメール」ではない、本物の企業からのメールであることを証明するための技術的な仕組み。これらが正しく設定されていないと、Gmailなどに届きにくくなります。
例:メールの身分証明書のようなもの。システム担当者に確認すべき重要事項。
「」に一致する用語は見つかりませんでした。
キーワードを変更して、もう一度お試しください。
// — Data: Glossary Terms —
const glossaryData = [
{
id: “opt-in”,
name: “オプトイン”,
phonetic: “Opt-in”,
category: “basic”,
categoryLabel: “基本概念”,
description: “ユーザーが企業に対して「メールマガジンなどを送っても良いですよ」と事前に許可を出すこと。日本の法律(特電法)では、原則としてこのオプトインを得ていない相手への広告メール送信は禁止されています。”,
example: “「メルマガを受け取る」のチェックボックスにチェックを入れる行為。”
},
{
id: “opt-out”,
name: “オプトアウト”,
phonetic: “Opt-out”,
category: “basic”,
categoryLabel: “基本概念”,
description: “ユーザーが「もうメールを送らないでください」と受信拒否(配信停止)をすること。メールの文末に必ず配信停止できるリンク(オプトアウト導線)を設置することが法律で義務付けされています。”,
example: “メルマガの下部にある「配信停止はこちら」のリンクをクリックすること。”
},
{
id: “segmentation”,
name: “セグメンテーション”,
phonetic: “Segmentation”,
category: “basic”,
categoryLabel: “基本概念”,
description: “顧客リストを特定の条件(年齢、性別、購入履歴、居住地など)でグループ分けすること。全員に同じメールを送るのではなく、グループごとに興味を持ちそうな内容を送るために行います。”,
example: “「過去半年間に購入がない20代女性」だけを抽出して特別なクーポンを送る。”
},
{
id: “personalize”,
name: “パーソナライズ”,
phonetic: “Personalization”,
category: “basic”,
categoryLabel: “基本概念”,
description: “メールの内容を、受信者一人ひとりに合わせてカスタマイズすること。一番簡単な例は、件名や本文に「〇〇様」と相手の名前を自動で挿入することです。”,
example: “件名:「山田様へ、お誕生日月限定の特別オファーです」”
},
{
id: “html-email”,
name: “HTMLメール”,
phonetic: “HTML Email”,
category: “delivery”,
categoryLabel: “配信・システム”,
description: “Webページのように、画像を入れたり、文字の色や大きさを変えたり、ボタンを配置したりできるデザイン性の高いメールのこと。開封率を正確に計測できるのが大きなメリットです。”,
example: “ネットショップから届く、写真付きの綺麗なレイアウトのメルマガ。”
},
{
id: “text-email”,
name: “テキストメール”,
phonetic: “Text Email”,
category: “delivery”,
categoryLabel: “配信・システム”,
description: “文字と記号だけで構成されたシンプルなメール。容量が軽く、どんな環境でも確実に表示されるのがメリットですが、画像は使えず、開封率の計測もできません。”,
example: “システムからの注文完了通知や、業務連絡のようなシンプルなメール。”
},
{
id: “step-email”,
name: “ステップメール”,
phonetic: “Step Email”,
category: “delivery”,
categoryLabel: “配信・システム”,
description: “ユーザーが特定のアクション(資料請求や購入など)をした日を起点として、あらかじめ準備しておいた複数のメールを、スケジュール通りに順番に自動配信する仕組み。”,
example: “会員登録直後に「お礼」、3日後に「使い方の案内」、7日後に「プレミアムプランの案内」を自動で送る。”
},
{
id: “bounce”,
name: “バウンス (エラーメール)”,
phonetic: “Bounce”,
category: “delivery”,
categoryLabel: “配信・システム”,
description: “宛先不明や受信箱がいっぱいなどの理由で、相手に届かずに戻ってきてしまったエラーメールのこと。バウンスを放置して送り続けると、スパム業者と判定されるリスクが高まります。”,
example: “退職して使われなくなったアドレス宛に送り、エラーで返ってくる状態(ハードバウンス)。”
},
{
id: “delivery-rate”,
name: “到達率 (配信成功率)”,
phonetic: “Delivery Rate”,
category: “metrics”,
categoryLabel: “効果測定 (KPI)”,
description: “送信したメールのうち、エラーにならずに無事に相手のサーバーまで届いた割合。これが低い場合は、リストが古くなっている(無効なアドレスが多い)可能性があります。”,
example: “式:到達数 ÷ 送信総数 × 100”
},
{
id: “open-rate”,
name: “開封率”,
phonetic: “Open Rate”,
category: “metrics”,
categoryLabel: “効果測定 (KPI)”,
description: “無事に届いたメールのうち、実際に開いて読まれた割合。メールの「件名(タイトル)」と「送信者名」の魅力度が、この数字を大きく左右します。”,
example: “式:開封数 ÷ 到達数 × 100”
},
{
id: “ctr”,
name: “クリック率 (CTR)”,
phonetic: “Click Through Rate”,
category: “metrics”,
categoryLabel: “効果測定 (KPI)”,
description: “メールが届いた人(または開封した人)のうち、メール内のURLやボタンがクリックされた割合。メールの「本文の内容(オファー)」が魅力的だったかを測る指標です。”,
example: “式:クリック数 ÷ 到達数 × 100 (※開封数を分母にする場合もあります)”
},
{
id: “cvr”,
name: “コンバージョン率 (CVR)”,
phonetic: “Conversion Rate”,
category: “metrics”,
categoryLabel: “効果測定 (KPI)”,
description: “メールのリンクをクリックしてWebサイトに訪れた人のうち、最終的な目標(商品購入、資料請求、会員登録など)を達成した人の割合。”,
example: “式:目標達成数 ÷ クリック数 × 100”
},
{
id: “spam”,
name: “迷惑メール (スパム)”,
phonetic: “Spam”,
category: “law”,
categoryLabel: “法律・セキュリティ”,
description: “受信者の許可なく一方的に大量送信されるメールのこと。ISP(プロバイダ)の迷惑メールフィルターに引っかかると、正当なメールであっても迷惑メールフォルダに入ってしまいます。”,
example: “件名が過激だったり、怪しいリンクが大量に含まれているメール。”
},
{
id: “tokuden-law”,
name: “特定電子メール法”,
phonetic: “Anti-Spam Law (Japan)”,
category: “law”,
categoryLabel: “法律・セキュリティ”,
description: “迷惑メールを防ぐための日本の法律。「事前の同意(オプトイン)を得ること」「送信者情報の表示義務」「配信停止(オプトアウト)導線の設置義務」などが定めされています。違反すると罰則があります。”,
example: “メルマガを始める際、必ず守らなければならないルールの基本。”
},
{
id: “sender-auth”,
name: “送信ドメイン認証 (SPF/DKIM/DMARC)”,
phonetic: “Sender Authentication”,
category: “law”,
categoryLabel: “法律・セキュリティ”,
description: “「なりすましメール」ではない、本物の企業からのメールであることを証明するための技術的な仕組み。これらが正しく設定されていないと、Gmailなどに届きにくくなります。”,
example: “メールの身分証明書のようなもの。システム担当者に確認すべき重要事項。”
}
];// — Application State —
let currentCategory = ‘all’;
let currentSearchQuery = ”;// — DOM Elements —
const gridContainer = document.getElementById(‘glossaryGrid’);
const searchInput = document.getElementById(‘searchInput’);
const categoryButtons = document.querySelectorAll(‘.category-btn’);
const noResultsMsg = document.getElementById(‘noResultsMsg’);
const searchQueryDisplay = document.getElementById(‘searchQueryDisplay’);// — Initialize App —
function init() {
renderGrid(glossaryData);
setupEventListeners();
initChart();
updateSimulator();
}// — Rendering Logic —
function renderGrid(data) {
gridContainer.innerHTML = ”;
if (data.length === 0) {
gridContainer.classList.add(‘hidden’);
noResultsMsg.classList.remove(‘hidden’);
searchQueryDisplay.textContent = currentSearchQuery;
} else {
gridContainer.classList.remove(‘hidden’);
noResultsMsg.classList.add(‘hidden’);
data.forEach((item, index) => {
// Category Badge Color Logic (Adapted for Blue Theme)
let badgeColor = ‘bg-slate-100 text-slate-700 border-slate-200’;
if (item.category === ‘basic’) badgeColor = ‘bg-sky-50 text-sky-700 border-sky-200’;
if (item.category === ‘delivery’) badgeColor = ‘bg-teal-50 text-teal-700 border-teal-200’;
if (item.category === ‘metrics’) badgeColor = ‘bg-blue-50 text-blue-800 border-blue-200’;
if (item.category === ‘law’) badgeColor = ‘bg-indigo-50 text-indigo-700 border-indigo-200’;const card = document.createElement(‘article’);
card.className = `glossary-card bg-surface border border-secondary/40 rounded-xl p-5 flex flex-col h-full fade-in`;
card.style.animationDelay = `${index * 0.04}s`; // Smooth staggered cascade
card.innerHTML = `
${item.name}
${item.phonetic}
${item.categoryLabel}
💡 わかりやすい例:${item.example}
`;
gridContainer.appendChild(card);
});
}
}// — Filtering & Search Logic —
function filterData() {
let filtered = glossaryData;// Apply Search
if (currentSearchQuery) {
const q = currentSearchQuery.toLowerCase();
filtered = filtered.filter(item =>
item.name.toLowerCase().includes(q) ||
item.phonetic.toLowerCase().includes(q) ||
item.description.toLowerCase().includes(q)
);
}// Apply Category
if (currentCategory !== ‘all’) {
filtered = filtered.filter(item => item.category === currentCategory);
}renderGrid(filtered);
}function setupEventListeners() {
// Search Input
searchInput.addEventListener(‘input’, (e) => {
currentSearchQuery = e.target.value.trim();
filterData();
});// Category Buttons
categoryButtons.forEach(btn => {
btn.addEventListener(‘click’, (e) => {
categoryButtons.forEach(b => {
b.classList.remove(‘active’, ‘bg-primary’, ‘text-white’);
b.classList.add(‘bg-surface’, ‘text-textMain’);
b.style.backgroundColor = ”;
b.style.color = ”;
b.style.borderColor = ”;
});
const target = e.currentTarget;
target.classList.add(‘active’);
target.classList.remove(‘bg-surface’, ‘text-textMain’);
// Set theme dynamic active colors
target.style.backgroundColor = ‘#3a8bcd’;
target.style.color = ‘#ffffff’;
target.style.borderColor = ‘#3a8bcd’;currentCategory = target.getAttribute(‘data-category’);
filterData();
});
});// Simulator Sliders
[‘sendCount’, ‘deliveryRate’, ‘openRate’, ‘clickRate’].forEach(id => {
document.getElementById(id).addEventListener(‘input’, updateSimulator);
});
}// — Chart.js Logic (Simulator with Wide Funnel setup) —
let funnelChart;function initChart() {
const ctx = document.getElementById(‘funnelChart’).getContext(‘2d’);
Chart.defaults.font.family = ‘”Noto Sans JP”, sans-serif’;
Chart.defaults.color = ‘#5e7388’;funnelChart = new Chart(ctx, {
type: ‘bar’,
data: {
labels: [‘① 送信リスト数’, ‘② 到達数’, ‘③ 開封数’, ‘④ サイト流入数’],
datasets: [{
label: ‘合計件数 / 人数’,
data: [0, 0, 0, 0],
backgroundColor: [
‘rgba(179, 218, 241, 0.4)’, // Soft secondary
‘rgba(179, 218, 241, 0.8)’, // Stronger secondary
‘rgba(58, 139, 205, 0.7)’, // Primary
‘rgba(28, 160, 160, 0.9)’ // Accent Teal
],
borderColor: [
‘#b3daf1’,
‘#88c0e7’,
‘#3a8bcd’,
‘#1ca0a0’
],
borderWidth: 1.5,
borderRadius: 6,
barPercentage: 0.6
}]
},
options: {
indexAxis: ‘y’, // Keep it horizontal for natural funnel scanning left-to-right
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
tooltip: {
backgroundColor: ‘rgba(44, 62, 80, 0.95)’,
titleFont: { size: 13, weight: ‘bold’ },
bodyFont: { size: 14 },
padding: 12,
callbacks: {
label: function(context) {
return ‘ ‘ + context.parsed.x.toLocaleString() + ‘ 人/件’;
}
}
}
},
scales: {
x: {
beginAtZero: true,
grid: {
color: ‘rgba(58, 139, 205, 0.08)’,
drawBorder: false
},
ticks: {
callback: function(value) {
return value.toLocaleString();
}
}
},
y: {
grid: {
display: false
},
ticks: {
font: { weight: ‘bold’, size: 12 }
}
}
},
animation: {
duration: 500,
easing: ‘easeOutExpo’
}
}
});
}function updateSimulator() {
// Get values
const sendCount = parseInt(document.getElementById(‘sendCount’).value);
const deliveryRate = parseFloat(document.getElementById(‘deliveryRate’).value) / 100;
const openRate = parseFloat(document.getElementById(‘openRate’).value) / 100;
const clickRate = parseFloat(document.getElementById(‘clickRate’).value) / 100;// Calculate funnel logic
const delivered = Math.round(sendCount * deliveryRate);
const opened = Math.round(delivered * openRate);
const clicked = Math.round(sendCount * clickRate); // Click Through Rate based on total sent as per standard simulator formula// Update DOM labels
document.getElementById(‘sendCountVal’).textContent = sendCount.toLocaleString();
document.getElementById(‘deliveryRateVal’).textContent = (deliveryRate * 100).toFixed(0);
document.getElementById(‘openRateVal’).textContent = (openRate * 100).toFixed(0);
document.getElementById(‘clickRateVal’).textContent = (clickRate * 100).toFixed(1);
// Animate number change for final result
animateValue(“finalResult”, parseInt(document.getElementById(‘finalResult’).textContent.replace(/,/g, ”)), clicked, 500);// Update Chart
if (funnelChart) {
funnelChart.data.datasets[0].data = [sendCount, delivered, opened, clicked];
funnelChart.update();
}
}// Helper function for smooth transition number counters
function animateValue(id, start, end, duration) {
const obj = document.getElementById(id);
if (start === end) {
obj.innerHTML = `${end.toLocaleString()}
人`;
return;
}
let startTimestamp = null;
const step = (timestamp) => {
if (!startTimestamp) startTimestamp = timestamp;
const progress = Math.min((timestamp – startTimestamp) / duration, 1);
const currentVal = Math.floor(progress * (end – start) + start);
obj.innerHTML = `${currentVal.toLocaleString()}
人`;
if (progress < 1) {
window.requestAnimationFrame(step);
} else {
obj.innerHTML = `${end.toLocaleString()}
人`;
}
};
window.requestAnimationFrame(step);
}// Init App on content load
window.addEventListener(‘DOMContentLoaded’, init);