届かない問い合わせ
問い合わせフォームを作りました。
実装そのものは小さいのですが、決めることが3つありました。どれも「動くかどうか」ではなく「壊れたときにどう見えるか」の話でした。
メールアドレスを載せない選択、送信先が未設定のときにフォームを出すかどうか、そして失敗をどう伝えるか。共通しているのは「成功したように見える失敗」をどう防ぐかです。
1. メールアドレスを直接載せない
いちばん簡単なのは、ページにメールアドレスを書くことです。実装が要らず、壊れる要素もありません。
ただし、公開した以上は自動で収集され、迷惑メールが届き始めます。個人サイトでも例外ではありません。
そこで、フォームの送信先だけを外部サービスに任せる形にしました。受け取り用のアドレスがブラウザ側に出ません。
| 方式 | 手間 | アドレスの露出 |
|---|---|---|
| アドレスを載せる | ゼロ | する |
| 自前でメール送信 | サーバーと送信サービスの契約が必要 | しない |
| 外部サービスへ送信 | 登録して1行設定するだけ | しない |
自前で用意する案もありましたが、問い合わせ1つのために管理するものが増えます。メール送信サービスの契約、鍵の管理、送信失敗時の扱い。得られるものに対して重すぎると判断しました。
2. 送信先が未設定のとき、フォームを出すか
ここが今回いちばん考えた点です。
外部サービスの送信先URLは、環境変数で渡します。つまり設定を入れるまでは、送信先が空のままです。
このとき、フォームをどう扱うか。素直に実装すると、こうなります。
フォームは表示される
↓
入力して送信できる
↓
送信先が空 → どこにも届かない
↓
それでも「送信しました」と表示される
これが最悪の状態です。
送った側は、届いたと思って返信を待ちます。こちらには何も残りません。問い合わせが来なかったのか、届かなかったのかも分かりません。
フォームが無ければ、相手は別の連絡手段を探すか、諦めます。どちらにしても相手は状況を把握できます。
しかし届かないフォームは、相手に「連絡した」と誤認させます。返信が来ないことで、対応が悪いという印象だけが残ります。何もしないより損をしています。
そこで、設定が無いときはフォームごと出さないことにしました。
const ENDPOINT = process.env.NEXT_PUBLIC_CONTACT_ENDPOINT;
if (!ENDPOINT) {
return <p>お問い合わせ先は準備中です。</p>;
}
3行です。「準備中」と正直に出すほうが、動くように見えて届かないより、はるかにましです。
3. 失敗を隠さない
設定が正しくても、送信は失敗します。通信が切れる、外部サービスが落ちている、上限に達している。
このとき、画面をどうするか。「送信しました」と出してしまうのは簡単です。実装が楽ですし、その場では体験が滑らかに見えます。
しかし結果は2番目と同じで、相手は届いたと思って待ちます。
失敗したときは失敗したと表示し、時間をおいて試すよう伝える形にしました。気まずさより、事実のほうが役に立ちます。
3つに共通していたこと
並べてみると、判断の軸は1つでした。
うまくいったように見えて、実は何も起きていない
この状態が厄介なのは、誰も気づけないことです。エラーも出ず、画面も正常で、記録も残りません。問題があること自体が分からないので、直しようがありません。
機能が動かないことより、動かないのに動いて見えることのほうが高くつきます。「準備中です」と出ていれば、設定を入れ忘れていることに自分でも気づけます。静かに成功したふりをする実装は、自分自身も欺きます。
今回の学び
まず、簡単な方法には、たいてい代償があること。アドレスを直接載せるのは実装ゼロですが、迷惑メールという継続的なコストを払います。手間の総量で比べる必要があります。
次に、未設定の状態を、設計に含めること。設定が入った状態だけを想定して作ると、入っていない期間の挙動が事故になります。「まだ設定していない」は必ず通る道です。
そして、成功の表示は、成功したときだけ出すこと。当たり前に聞こえますが、実装を楽にするために崩れやすい原則でもあります。表示は事実に従わせるべきです。
最後に、静かに失敗する仕組みを作らないこと。これは今回に限らず、繰り返し出てくる主題です。エラーが出る失敗は直せます。直せないのは、失敗したことが分からない失敗のほうです。
関連記事

読む邪魔をしない
貼り付いたヘッダーと目次が、読んでいるあいだずっと画面を占めていた。下へ読むときは引っ込むヘッダー、スクロール中だけ薄くなる目次、先頭へ戻るボタン。3つの判断の記録。

上げる先が、ひとつしかなかった
脆弱性28件のうち23件がNext.jsに集約されていた。あとは上げるだけ、のはずが「どこまで上げるか」で手が止まった。サポート期限を調べたら選択肢は実質1つだけ。コードモッドが入れた不要な設定を消し、プレビューで確認してから本番へ入れた記録。
追従する目次と、画面の取り合い
PCで右側に追従させていた目次を、スマホでは上部に貼り付けた。ところが貼り付くものは画面を占め続けるため、本文を読む場所が足りなくなる。情報を消さずに縦を横へ並べ替えた話と、「飛んだ先がバーの裏に隠れる」という副作用への対処。