【個人開発】Next.jsでのWebサイト制作 #5（最終回）　EmailJSを使ってフォームの送信内容をメールに飛ばす方法

こんにちは、Naotoです！
Next.jsでのWebサイト制作 #5（最終回）　は、EmailJSを使ってフォームの送信内容をメールに飛ばす方法について紹介いたします！

これまで４記事にわたって投稿してきた、「【個人開発】Next.jsによるWebサイト制作」も、本記事がラストの投稿となりますので、ぜひお読みいただければと思います。

## 本WebサイトのContactページ

Webサイト上のコンタクトページにて、今回紹介するEmailJSの機能を使用しています。

以下問合せフォームを送信すると、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/8baff529-7e95-a4f6-2be0-32e48bb57049.png)

設定したメールアドレスにフォームの内容が送られます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/47f910ff-fb88-f4f5-fc34-fff21db994a3.png)

では早速、上記のような仕組みを実現できるEmailJSについて紹介していきたいと思います！

## EmailJSとは？
EmailJSとは、メールサーバを用意しなくても、フロントエンドの実装のみでメールを送信可能にするサービスです。

https://www.emailjs.com/

## EmailJS GUIの設定

①アカウント作成後、ログインすると、以下のようなダッシュボードが開かれます。（本Webページのサービスがすでに作られていますが、無視してください。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/a58b802d-0de0-51d8-8ac0-ff35e322d943.png)

②Email Service > Add New Service から、どのメールサービスのメアドにメールを飛ばすか選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/949b7767-05bc-279f-1487-69723377b117.png)

③サービス名を決め（自由）、「Connect Account」から、アカウントと紐づけた後、チェックボックスにチェックをいれ、「Create Service」する。
（Service IDは勝手に決められる。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/6bd2ae72-a1cf-fb97-37a8-3f4b17d9867a.png)

④Email Templates　> Create New Template からテンプレートを作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/19f55eab-c21f-1a4e-0f81-36ade5526a13.png)

Subject：
自由

Contents：
Contentsに書かれた内容がそのままメールとして送られます。
また、{{変数}}となっている部分では、フロントエンドから送られてきた変数の中身を表示することができます。

（Template IDは勝手に決められる。）


以上でEmailJSのGUIでの最低限の設定は完了です。

## フロントエンドの実装
次にフロントエンドの実装方法について説明します。

①インポート
```
npm install @emailjs/browser --save
```
②envファイルに、ServiceID, TemplateID, PublicIDを記載。（各IDは、EmailJSのGUI上から確認可能。）

```
NEXT_PUBLIC_REACT_APP_EMAILJS_SERVICE_ID=ここにServiceIDを記載。
NEXT_PUBLIC_REACT_APP_EMAILJS_TEMPLATE_ID=ここにTemplateIDを記載。
NEXT_PUBLIC_REACT_APP_EMAILJS_PUBLIC_ID=ここにPublicIDを記載。
```

③コンポーネントの実装（本WebサイトのContactページでの実装例）

※以下コードを理解するには、useFormの知識が必要です。
```tsx
"use client";
import { useForm } from "react-hook-form";
import emailjs from "@emailjs/browser";

// 問い合わせページ

export default function Contact() {
  // useForm関連
  const {
    register,
    handleSubmit,
    formState: { errors },
    reset,
  } = useForm({ mode: "onSubmit" });

  // EmailJsを使ったメールの送信
  const onSubmit = async (data: Record<string, unknown>) => {
    // EmailJsへの接続
    // GUIで設定したServiceへの接続
    const serviceId: string =
      process.env.NEXT_PUBLIC_REACT_APP_EMAILJS_SERVICE_ID!;
    // GUIで設定したTemplateへの接続
    const templateId: string =
      process.env.NEXT_PUBLIC_REACT_APP_EMAILJS_TEMPLATE_ID!;
    // EmailJSアカウントのPublic Keyへの接続
    const publicId: string =
      process.env.NEXT_PUBLIC_REACT_APP_EMAILJS_PUBLIC_ID!;
    // send関数によってメールを送信する。以下data内の、name, email, messageのデータ内容が、GUI上のTemplateの{{変数}}として、置き換わる。
    try {
      await emailjs.send(serviceId, templateId, data, publicId);
      window.alert("送信しました。");
    } catch (error) {
      window.alert("エラーが出ました" + error);
    }
    // useFormをリセット
    reset();
  };

  return (
    <main className=" w-10/12 mt-5 mb-10 bg-gray-200 border-4 text-black border-black rounded-xl max-w-4xl mx-auto p-4 sm:p-6 lg:p-8">
      {/* タイトル */}
      <h1 className="text-3xl font-bold mb-6 text-center">お問い合わせ</h1>
      <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
        {/* 名前 */}
        <div className="space-y-2">
          <label
            htmlFor="name"
            className="block text-lg font-bold text-gray-700 "
          >
            名前
          </label>
          <input
            type="text"
            // useForm用の記述
            {...register("name", { required: "氏名は必須です。" })}
            id="name"
            name="name"
            className=" p-2 mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
          />
          {/* バリデーションエラー時のメッセージ */}
          <p className="text-red-500 text-xs font-bold ">
            {errors.name?.message as React.ReactNode}
          </p>
        </div>
        {/* メアド */}
        <div className="space-y-2">
          <label
            htmlFor="email"
            className="block text-lg font-bold text-gray-700"
          >
            メールアドレス
          </label>
          <input
            type="email"
            // useForm用の記述
            {...register("email", {
              required: "※メールアドレスを入力してください。",
              pattern: {
                value:
                  /^[a-zA-Z0-9_.+-]+@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$/,
                message: "※正しいメールアドレスを入力してください。",
              },
            })}
            id="email"
            name="email"
            className=" p-2 mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
          />
          {/* バリデーションエラー時のメッセージ */}
          <p className="text-red-500 text-xs font-bold ">
            {errors.email?.message as React.ReactNode}
          </p>
        </div>
        {/* 問い合わせ内容 */}
        <div className="space-y-2">
          <label
            htmlFor="message"
            className="block text-lg font-bold text-gray-700"
          >
            問い合わせ内容
          </label>
          <textarea
            id="message"
            // useForm用の記述
            {...register("message", {
              required: "問い合わせ内容は必須です。",
            })}
            name="message"
            rows={14}
            className=" p-2 mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
          />
          {/* バリデーションエラー時のメッセージ */}
          <p className="text-red-500 text-xs font-bold ">
            {errors.message?.message as React.ReactNode}
          </p>
        </div>
        <div>
          ＊回答は記載いただいたメールアドレスに返信させていただきます。
        </div>
        {/* 送信ボタン */}
        <div className="flex justify-end">
          <button
            type="submit"
            className="inline-flex items-center px-4 py-2 border border-transparent text-base font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
          >
            送信
          </button>
        </div>
      </form>
    </main>
  );
}

```

上記のように、emailjsのsend関数の引数に、ServiceID, TemplateID, PublicID, 送りたいデータを渡して実行するだけで、
GUI上のServiceに設定したメールアドレスに対し、フロントエンドから送られてきたdataを反映したTemplateの内容をメールで送ることができます。


## まとめ
以上が、EmailJSを使ってフォームの送信内容をメールに飛ばす方法の解説でした。

EmailJSを使用することで、メールサーバを用意することなく簡単にメール送信機能を実装することができ、開発の手間を大幅に削減できます。
また、フロントエンドのみで実現できるため、バックエンドの知識がなくても導入しやすいのも大きなメリットです。

ぜひ皆さんも使用してみてください！！

## 最後に
これにて、全5回にわたってお送りしてきた「【個人開発】Next.jsによるWebサイト制作」のシリーズは終了となります。

個人開発したプロダクトの内容をQiitaに発信することで、自分自身の復習や、アウトプットによる知識定着に繋げることができたと思っております。

過去記事含め、理解が浅い部分や、間違っている部分等、多くあると思いますので、質問やフィードバックがありましたら、ぜひコメント欄にてお知らせいただけると幸いです。


今後は、別プロジェクトとして作成した、Webアプリケーション「Task Manager」について、今回同様シリーズ化して、アウトプットしたいと思っております。

ぜひ、お読みいただければ幸いです。

ありがとうございました！！！