KiSAKU
技術系4分で読めます

届かない問い合わせ

公開

問い合わせフォームを作りました。

実装そのものは小さいのですが、決めることが3つありました。どれも「動くかどうか」ではなく「壊れたときにどう見えるか」の話でした。

この記事で扱うこと

メールアドレスを載せない選択、送信先が未設定のときにフォームを出すかどうか、そして失敗をどう伝えるか。共通しているのは「成功したように見える失敗」をどう防ぐかです。

1. メールアドレスを直接載せない

いちばん簡単なのは、ページにメールアドレスを書くことです。実装が要らず、壊れる要素もありません。

ただし、公開した以上は自動で収集され、迷惑メールが届き始めます。個人サイトでも例外ではありません。

そこで、フォームの送信先だけを外部サービスに任せる形にしました。受け取り用のアドレスがブラウザ側に出ません。

方式 手間 アドレスの露出
アドレスを載せる ゼロ する
自前でメール送信 サーバーと送信サービスの契約が必要 しない
外部サービスへ送信 登録して1行設定するだけ しない

自前で用意する案もありましたが、問い合わせ1つのために管理するものが増えます。メール送信サービスの契約、鍵の管理、送信失敗時の扱い。得られるものに対して重すぎると判断しました。

2. 送信先が未設定のとき、フォームを出すか

ここが今回いちばん考えた点です。

外部サービスの送信先URLは、環境変数で渡します。つまり設定を入れるまでは、送信先が空のままです。

このとき、フォームをどう扱うか。素直に実装すると、こうなります。

何も考えずに書くと
フォームは表示される
   ↓
入力して送信できる
   ↓
送信先が空 → どこにも届かない
   ↓
それでも「送信しました」と表示される

これが最悪の状態です。

送った側は、届いたと思って返信を待ちます。こちらには何も残りません。問い合わせが来なかったのか、届かなかったのかも分かりません。

届かない問い合わせは、無いより悪い

フォームが無ければ、相手は別の連絡手段を探すか、諦めます。どちらにしても相手は状況を把握できます。

しかし届かないフォームは、相手に「連絡した」と誤認させます。返信が来ないことで、対応が悪いという印象だけが残ります。何もしないより損をしています。

そこで、設定が無いときはフォームごと出さないことにしました。

実装
const ENDPOINT = process.env.NEXT_PUBLIC_CONTACT_ENDPOINT;

if (!ENDPOINT) {
  return <p>お問い合わせ先は準備中です。</p>;
}

3行です。「準備中」と正直に出すほうが、動くように見えて届かないより、はるかにましです。

3. 失敗を隠さない

設定が正しくても、送信は失敗します。通信が切れる、外部サービスが落ちている、上限に達している。

このとき、画面をどうするか。「送信しました」と出してしまうのは簡単です。実装が楽ですし、その場では体験が滑らかに見えます。

しかし結果は2番目と同じで、相手は届いたと思って待ちます。

失敗したときは失敗したと表示し、時間をおいて試すよう伝える形にしました。気まずさより、事実のほうが役に立ちます。

3つに共通していたこと

並べてみると、判断の軸は1つでした。

避けたかった状態
うまくいったように見えて、実は何も起きていない

この状態が厄介なのは、誰も気づけないことです。エラーも出ず、画面も正常で、記録も残りません。問題があること自体が分からないので、直しようがありません。

失敗するなら、見えるところで失敗させる

機能が動かないことより、動かないのに動いて見えることのほうが高くつきます。「準備中です」と出ていれば、設定を入れ忘れていることに自分でも気づけます。静かに成功したふりをする実装は、自分自身も欺きます。

今回の学び

まず、簡単な方法には、たいてい代償があること。アドレスを直接載せるのは実装ゼロですが、迷惑メールという継続的なコストを払います。手間の総量で比べる必要があります。

次に、未設定の状態を、設計に含めること。設定が入った状態だけを想定して作ると、入っていない期間の挙動が事故になります。「まだ設定していない」は必ず通る道です。

そして、成功の表示は、成功したときだけ出すこと。当たり前に聞こえますが、実装を楽にするために崩れやすい原則でもあります。表示は事実に従わせるべきです。

最後に、静かに失敗する仕組みを作らないこと。これは今回に限らず、繰り返し出てくる主題です。エラーが出る失敗は直せます。直せないのは、失敗したことが分からない失敗のほうです。

← ブログ一覧へ戻る