郵便
 Computer >> コンピューター >  >> ソフトウェア >> 郵便

SendGrid と Next.js でお問い合わせフォームを作成する方法

連絡先フォームは、ユーザーが電子メールでやり取りできるようにする場合に Web サイトで役立ちます。そして、それらを構築する方法はたくさんあります。

従来は、サーバー経由でメールを送信するために PHP を使用するか、メール ロジックを処理するサード パーティのサービスを使用していました。

ただし、この記事では、SendGrid API を使用して Next.js アプリケーションからメールを送信する方法について説明します。

送信前に検証する入力フィールドを持つ単純なページ (React で構築された連絡フォーム) を作成します。フォームを SendGrid API に接続し、メールの送信を処理します。そうすれば、1 日の終わりに、メールをチェックしてそれらのクエリを見つけるだけです。

ただし、Next.js プロジェクトをまだ持っていない場合は、以下の手順に従って簡単に作成し、Vercel と統合できます。

<オール>
  • Vercel でアカウントを作成し、New Project をクリックします。
  • SendGrid と Next.js でお問い合わせフォームを作成する方法

    2. テンプレートを Next.js として選択します :

    SendGrid と Next.js でお問い合わせフォームを作成する方法

    3. リポジトリに好きな名前を付けて、[プロジェクトの作成] をクリックします。 (リモート コードのバージョン管理には GitHub、GitLab、または BitBucket を選択してください)

    SendGrid と Next.js でお問い合わせフォームを作成する方法

    上記の 3 つのポイントに従うと、バージョニング アカウントにリポジトリが作成されます。

    使用する技術スタック

    • お問い合わせフォームのランディング ページを作成するための Next.js
    • コンポーネントをスタイリングするための TailwindCSS
    • API を使用してメールを送信するための SendGrid
    • アプリケーションと CI/CD をホストする Vercel

    Nextjs の API ルートを使用してフォーム イベントを処理します。 API モジュールは、Next.js アプリケーションでバックエンド ロジックを柔軟に処理する方法を提供します。

    API フォルダーに記述したコードは、サーバーレス関数として Vercel にデプロイされてホスティングされます。 Next.js API ルートの詳細については、こちらをご覧ください

    機能する連絡先フォームをセットアップする Next.js プロジェクトが既にある場合は、それで問題ありません。その場合、簡単にページを作成してすぐに始めることができます。

    ただし、まだプロジェクトをセットアップしていない場合でも問題ありません。Vercel に移動して、Next.js スターター プロジェクトを作成し、リポジトリを複製します。

    申し込みの流れ

    アプリケーション フロー、または電子メールの送信が実際にどのように機能するかを見てみましょう:

    • エンドユーザーは必須の 4 つのフィールドに入力し、[送信] をクリックします。
    • 送信時に、handleSubmit 関数がトリガーされます。
    • handleSubmit フォームの入力フィールドを検証し、それらが空でないかどうかをチェックします。
    • フォーム フィールドが空でない場合、api/sendgrid への API 呼び出しが行われます メール送信のロジックが存在する場所
    • api/sendgrid で 、@sendgrid/mail モジュールは send を初期化します アプリケーションの API キーを受け取り、必須フィールドを含むメールを送信する関数
    • メールが正常に配信された場合、200 応答がクライアントに送信されます。それ以外の場合は 400 応答がクライアントに送信されます。
    • 応答はフロントエンドで処理され、適切なメッセージが表示されます。

    TailwindCSS の設定方法

    TailwindCSS のセットアップは非常に簡単で、2 つの簡単な方法で行うことができます。

    <オール>
  • TailwindCSS を依存関係としてプロジェクトにインストールします:
  • npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
    

    2. プロジェクトの TailwindCSS 構成ファイルを初期化します。これにより、tailwind.config.js が作成されます ルート ディレクトリのファイル:

    npx tailwindcss init
    

    次に、構成ファイルを編集して purge を含める必要があります。 パス、および jit を有効にします モード:

    module.exports = {
       purge: [],
       mode: 'jit',
       purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
        darkMode: false, // or 'media' or 'class'
        theme: {
          extend: {},
        },
        variants: {
          extend: {},
        },
        plugins: [],
      }

    purge を使用しています ビルド時にプロジェクトから不要なスタイルを削除します。 CSS バンドルのサイズを小さくしたい場合に役立ちます。

    jit は、コード自体で動的なクラス名を指定できる新しい TailwindCSS モードです。

    たとえば、テキスト サイズを 10px にしたい場合 (TailwindCSS モジュールにはまだありません)、 text-[10px] と書くことができます をクラス名に追加すると、自動的に反映されます。カスタム スタイル属性を記述する必要はもうありません。 💯

    次に、Tailwind スタイルをルート _app.js にインポートします。 ファイル:

    // pages/_app.js
     import '../styles/globals.css'
     import 'tailwindcss/tailwind.css'
    
      function MyApp({ Component, pageProps }) {
        return <Component {...pageProps} />
      }
    
      export default MyApp

    次に、Tailwind のコア CSS を次のようにルート レベルのスタイルシートに含めます。

    /* ./styles/globals.css */
    @tailwind base;
    @tailwind components;
    @tailwind utilities;

    これで、プロジェクトの TailwindCSS が正常にセットアップされました。

    連絡先ページのマークアップとスタイリング

    SendGrid と Next.js でお問い合わせフォームを作成する方法

    Tailwind を使用して Web ページを完全に構築します。このページ自体は、Tailwind Web プロジェクトのコンポーネントおよびテンプレート ライブラリである Tailwind マスター キットから直接取得しました。

    ページの HTML (基本的にはお問い合わせフォーム) を見て、すべてがどのように実装されているかを理解しましょう:

    <form class="rounded-lg shadow-xl flex flex-col px-8 py-8 bg-white dark:bg-blue-500">
          <h1 class="text-2xl font-bold dark:text-gray-50">Send a message</h1>
    
          <label for="fullname" class="text-gray-500 font-light mt-8 dark:text-gray-50">Full name<span class="text-red-500 dark:text-gray-50">*</span></label>
          <input type="text" name="fullname" class="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500" />
    
          <label for="email" class="text-gray-500 font-light mt-4 dark:text-gray-50">E-mail<span class="text-red-500">*</span></label>
          <input type="email" name="email" class="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500" />
    
          <label for="subject" class="text-gray-500 font-light mt-4 dark:text-gray-50">Subject<span class="text-red-500">*</span></label>
          <input type="text" name="subject" class="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500" />
    
          <label for="message" class="text-gray-500 font-light mt-4 dark:text-gray-50">Message<span class="text-red-500">*</span></label>
          <textarea name="message" class="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"></textarea>
          <div class="flex flex-row items-center justify-start">
            <button class="px-10 mt-8 py-2 bg-[#130F49] text-gray-50 font-light rounded-md text-lg flex flex-row items-center">
              Send
              <svg width="24" height="24" viewBox="0 0 24 24" class="text-cyan-500 ml-2" fill="currentColor" xmlns="https://www.w3.org/2000/svg">
                <path d="M9.00967 5.12761H11.0097C12.1142 5.12761 13.468 5.89682 14.0335 6.8457L16.5089 11H21.0097C21.562 11 22.0097 11.4477 22.0097 12C22.0097 12.5523 21.562 13 21.0097 13H16.4138L13.9383 17.1543C13.3729 18.1032 12.0191 18.8724 10.9145 18.8724H8.91454L12.4138 13H5.42485L3.99036 15.4529H1.99036L4.00967 12L4.00967 11.967L2.00967 8.54712H4.00967L5.44417 11H12.5089L9.00967 5.12761Z" fill="currentColor" />
              </svg>
            </button>
          </div>
        </form>

    フォームには 4 つのフィールドがあります:

    • 氏名
    • メール
    • 件名
    • メッセージ

    すべてのフィールドは必須です。後で検証します。ユーザーがメールを送信する際に、すべての詳細を提供することを期待します。

    フィールドをキャプチャするには、React の useState() フックを使用して、データがアプリケーション内で永続化されるようにします。

    export default function ContactUs() {
      const [fullname, setFullname] = useState("");
      const [email, setEmail] = useState("");
      const [subject, setSubject] = useState("");
      const [message, setMessage] = useState("");
    
        return (
    		<form
              onSubmit={handleSubmit}
              className="rounded-lg shadow-xl flex flex-col px-8 py-8 bg-white dark:bg-blue-500"
            >
              <h1 className="text-2xl font-bold dark:text-gray-50">
                Send a message
              </h1>
    
              <label
                htmlFor="fullname"
                className="text-gray-500 font-light mt-8 dark:text-gray-50"
              >
                Full name<span className="text-red-500 dark:text-gray-50">*</span>
              </label>
              <input
                type="text"
                value={fullname}
                onChange={(e) => {
                  setFullname(e.target.value);
                }}
                name="fullname"
                className="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"
              />
             
    
              <label
                htmlFor="email"
                className="text-gray-500 font-light mt-4 dark:text-gray-50"
              >
                E-mail<span className="text-red-500">*</span>
              </label>
              <input
                type="email"
                name="email"
                value={email}
                onChange={(e) => {
                  setEmail(e.target.value);
                }}
                className="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"
              />
              
    
              <label
                htmlFor="subject"
                className="text-gray-500 font-light mt-4 dark:text-gray-50"
              >
                Subject<span className="text-red-500">*</span>
              </label>
              <input
                type="text"
                name="subject"
                value={subject}
                onChange={(e) => {
                  setSubject(e.target.value);
                }}
                className="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"
              />
             
              <label
                htmlFor="message"
                className="text-gray-500 font-light mt-4 dark:text-gray-50"
              >
                Message<span className="text-red-500">*</span>
              </label>
              <textarea
                name="message"
                value={message}
                onChange={(e) => {
                  setMessage(e.target.value);
                }}
                className="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"
              ></textarea>
              
              <div className="flex flex-row items-center justify-start">
                <button
                  type="submit"
                  className="px-10 mt-8 py-2 bg-[#130F49] text-gray-50 font-light rounded-md text-lg flex flex-row items-center"
                >
                  Submit
                  <svg
                    width="24"
                    height="24"
                    viewBox="0 0 24 24"
                    className="text-cyan-500 ml-2"
                    fill="currentColor"
                    xmlns="https://www.w3.org/2000/svg"
                  >
                    <path
                      d="M9.00967 5.12761H11.0097C12.1142 5.12761 13.468 5.89682 14.0335 6.8457L16.5089 11H21.0097C21.562 11 22.0097 11.4477 22.0097 12C22.0097 12.5523 21.562 13 21.0097 13H16.4138L13.9383 17.1543C13.3729 18.1032 12.0191 18.8724 10.9145 18.8724H8.91454L12.4138 13H5.42485L3.99036 15.4529H1.99036L4.00967 12L4.00967 11.967L2.00967 8.54712H4.00967L5.44417 11H12.5089L9.00967 5.12761Z"
                      fill="currentColor"
                    />
                  </svg>
                </button>
              </div>
            </form>
    	)
    }

    フォーム属性 onSubmit={handleSubmit} に注意してください .これは、SendGrid を介して実際にメールを送信する関数です。その前に、SendGrid プロジェクトを作成して、API keys を取得しましょう。 .

    SendGrid プロジェクトの設定方法

    SendGrid と Next.js でお問い合わせフォームを作成する方法

    まず、SendGrid のホームページにアクセスして、アカウントにサインアップするだけです (まだアカウントを持っていない場合)。

    アカウントが正常に作成されたら、API キーを登録します。ここでできます。

    Sendgrid では、スパムや悪意のあるメールから保護するために送信者 ID を作成する必要があります。これを行うには、Sendgrid ID ページに移動し、Create New Sender をクリックします。 送信者 ID を作成します。

    詳細なフォームに記入する必要があります。フォームに入力して送信をクリックするだけです。最後に、メール アドレスを確認するだけで完了です。

    API keys を取得したら、 、 .env.local を作成します ファイルをローカル環境に置き、次のコードを貼り付けます:

    SENDGRID_API_KEY= YOUR_API_KEY_HERE
    

    YOUR_API_KEY_HERE を置き換えます 取得した API キーを使用します。

    サーバーレス API ルートを作成する方法

    サーバーレス API ルートの作成は、Next.js を使用すると非常に簡単です。

    /pages/api に移動 そして api の中 フォルダに sendgrid.js というファイルを作成します .

    import sendgrid from "@sendgrid/mail";
    
    sendgrid.setApiKey(process.env.SENDGRID_API_KEY);
    
    async function sendEmail(req, res) {
      try {
        // console.log("REQ.BODY", req.body);
        await sendgrid.send({
          to: "[email protected]", // Your email where you'll receive emails
          from: "[email protected]", // your website email address here
          subject: `${req.body.subject}`,
          html: `<div>You've got a mail</div>`,
        });
      } catch (error) {
        // console.log(error);
        return res.status(error.statusCode || 500).json({ error: error.message });
      }
    
      return res.status(200).json({ error: "" });
    }
    
    export default sendEmail;
    

    SendGrid では、sendgrid を初期化する必要があります setApiKey() の API キーを持つオブジェクト 方法。 API キーでオブジェクトを初期化すると、send() でメールを送信できます メソッド。

    send() には基本的に 4 つのフィールドが必要です。 メソッドの本体:

    • to – メールの配信先メールアドレス
    • from – Sender Identity Verification に使用した SendGrid メール。メールはこのメールから送信されます。
    • subject – メールの件名
    • message – メールのメッセージ本文

    メールをよりよく理解できるように、これら 4 つのパラメーターを自分で作成します。上記の同じスニペットから更新されたコードは次のとおりです:

    import sendgrid from "@sendgrid/mail";
    
    sendgrid.setApiKey(process.env.SENDGRID_API_KEY);
    
    async function sendEmail(req, res) {
      try {
        await sendgrid.send({
          to: "[email protected]", // Your email where you'll receive emails
          from: "[email protected]", // your website email address here
          subject: `[Lead from website] : ${req.body.subject}`,
          html: `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
          <html lang="en">
          <head>
            <meta charset="utf-8">
          
            <title>The HTML5 Herald</title>
            <meta name="description" content="The HTML5 Herald">
            <meta name="author" content="SitePoint">
          <meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
          
            <link rel="stylesheet" href="css/styles.css?v=1.0">
          
          </head>
          
          <body>
            <div class="img-container" style="display: flex;justify-content: center;align-items: center;border-radius: 5px;overflow: hidden; font-family: 'helvetica', 'ui-sans';">              
                  </div>
                  <div class="container" style="margin-left: 20px;margin-right: 20px;">
                  <h3>You've got a new mail from ${req.body.fullname}, their email is: ✉️${req.body.email} </h3>
                  <div style="font-size: 16px;">
                  <p>Message:</p>
                  <p>${req.body.message}</p>
                  <br>
                  </div>
                  <img src="https://manuarora.in/logo.png" class="logo-image" style="height: 50px;width: 50px;border-radius: 5px;overflow: hidden;">
                  <p class="footer" style="font-size: 16px;padding-bottom: 20px;border-bottom: 1px solid #D1D5DB;">Regards<br>Manu Arora<br>Software Developer<br>+91 9587738861</p>
                  <div class="footer-links" style="display: flex;justify-content: center;align-items: center;">
                    <a href="https://manuarora.in/" style="text-decoration: none;margin: 8px;color: #9CA3AF;">Website</a>
                    <a href="https://manuarora.in/blog/" style="text-decoration: none;margin: 8px;color: #9CA3AF;">Blog</a>
                    <a href="https://github.com/manuarora700/" style="text-decoration: none;margin: 8px;color: #9CA3AF;">GitHub</a>
                    <a href="https://instagram.com/maninthere/" style="text-decoration: none;margin: 8px;color: #9CA3AF;">Instagram</a>
                    <a href="https://linkedin.com/in/manuarora28/" style="text-decoration: none;margin: 8px;color: #9CA3AF;">LinkedIn</a>
                    <a href="https://twitter.com/mannupaaji/" style="text-decoration: none;margin: 8px;color: #9CA3AF;">Twitter</a>
                    
                  </div>
                  </div>
          </body>
          </html>`,
        });
      } catch (error) {
        // console.log(error);
        return res.status(error.statusCode || 500).json({ error: error.message });
      }
    
      return res.status(200).json({ error: "" });
    }
    
    export default sendEmail;
    

    html を送信する場合 メール本文では、例にもあるインライン スタイルを使用する必要があります。

    ここでは、本質的に SendGrid の send() を使用しています。 SendGrid API が提供する、メールを送信するためのメソッド。 send() を使用します sendgrid を使用したメソッド API キーで初期化したオブジェクト。これにより、私たちの電子メールは安全であり、私たちの許可によってのみ配信されます.

    また、コードを try - catch でラップしました ブロック。これにより、アプリケーションが例外とエラーを正しく処理できるようになります。変更によってメール送信が失敗した場合、コードはすぐに catch() に分類されます ブロックし、error を返します 物体。これは、バックエンドで何らかの問題が発生したことを示しています。

    バックエンドからの API 応答を確認すると、それに応じてフロントエンドが応答し、UI が変化します。

    スタイリングは html に入ります send() 内の属性 メソッド本体。メールのスタイルをどのようにするかは、完全にあなた次第です。ここでは、Twitter、Instagram、GitHub、および Web サイトへのフッターを含むシンプルなテンプレートと、エンド ユーザーが送信する元のメッセージ本文を含めました。

    これで API ルートが設定されたので、フロントエンドに移り、応答を正しく処理する方法を学びましょう。

    API を呼び出してレスポンスを処理する方法

    API ルートが設定されたので、サーバーレス API を呼び出して応答をフェッチします。

    import React, { useState } from "react";
    
    export default function ContactUs() {
      const [fullname, setFullname] = useState("");
      const [email, setEmail] = useState("");
      const [subject, setSubject] = useState("");
      const [message, setMessage] = useState("");
    
    
    
      const handleSubmit = async (e) => {
        e.preventDefault();
    
        let isValidForm = handleValidation();
    
         
          const res = await fetch("/api/sendgrid", {
            body: JSON.stringify({
              email: email,
              fullname: fullname,
              subject: subject,
              message: message,
            }),
            headers: {
              "Content-Type": "application/json",
            },
            method: "POST",
          });
    
          const { error } = await res.json();
          if (error) {
            console.log(error);
            return;
          }
        console.log(fullname, email, subject, message);
      };
      return (
        <main>
            <form class="rounded-lg shadow-xl flex flex-col px-8 py-8 bg-white dark:bg-blue-500">
          <h1 class="text-2xl font-bold dark:text-gray-50">Send a message</h1>
    
          <label for="fullname" class="text-gray-500 font-light mt-8 dark:text-gray-50">Full name<span class="text-red-500 dark:text-gray-50">*</span></label>
          <input type="text" name="fullname" class="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500" />
    
          <label for="email" class="text-gray-500 font-light mt-4 dark:text-gray-50">E-mail<span class="text-red-500">*</span></label>
          <input type="email" name="email" class="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500" />
    
          <label for="subject" class="text-gray-500 font-light mt-4 dark:text-gray-50">Subject<span class="text-red-500">*</span></label>
          <input type="text" name="subject" class="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500" />
    
          <label for="message" class="text-gray-500 font-light mt-4 dark:text-gray-50">Message<span class="text-red-500">*</span></label>
          <textarea name="message" class="bg-transparent border-b py-2 pl-4 focus:outline-none focus:rounded-md focus:ring-1 ring-green-500 font-light text-gray-500"></textarea>
          <div class="flex flex-row items-center justify-start">
            <button class="px-10 mt-8 py-2 bg-[#130F49] text-gray-50 font-light rounded-md text-lg flex flex-row items-center">
              Send
              <svg width="24" height="24" viewBox="0 0 24 24" class="text-cyan-500 ml-2" fill="currentColor" xmlns="https://www.w3.org/2000/svg">
                <path d="M9.00967 5.12761H11.0097C12.1142 5.12761 13.468 5.89682 14.0335 6.8457L16.5089 11H21.0097C21.562 11 22.0097 11.4477 22.0097 12C22.0097 12.5523 21.562 13 21.0097 13H16.4138L13.9383 17.1543C13.3729 18.1032 12.0191 18.8724 10.9145 18.8724H8.91454L12.4138 13H5.42485L3.99036 15.4529H1.99036L4.00967 12L4.00967 11.967L2.00967 8.54712H4.00967L5.44417 11H12.5089L9.00967 5.12761Z" fill="currentColor" />
              </svg>
            </button>
          </div>
        </form>
        </main>
      );
    }
    

    ここでは、作成したばかりの API を fetch で呼び出しています。 、React によって提供されます。

    Fetch は、次のような本体でサーバーレス API を呼び出します。

    body: JSON.stringify({
              email: email,
              fullname: fullname,
              subject: subject,
              message: message,
            })

    これらは、フォーム データがすでに入力されているフォーム フィールドです (useState() を思い出してください)。 ?) が利用可能になりました。

    API は、成功または失敗のいずれかで応答します。成功した場合、メールは配信されますが、失敗した場合、メールは配信されません。

    エンドユーザーがフォームのステータスを知るために、いくつかの UI 要素を表示する必要があります。しかしその前に、空のフィールドがある場合に何が起こるかを処理する必要があります.

    フォーム検証を処理し、UI を API レスポンスに応答させる方法

    SendGrid と Next.js でお問い合わせフォームを作成する方法

    ここで 3 つのことを確認する必要があります:

    <オール>
  • すべてのフィールドに入力する必要があります。つまり、いずれかのフィールドが空の場合、フォームを送信できません。また、ユーザーはフォームが送信されない理由を知っている必要があります。そのために、エラー メッセージを表示します。
  • フォームが送信されている間、ユーザーは何らかの処理が行われていることを認識している必要があります。そのために、フォームの送信中にボタンのテキストを変更します。
  • フォームが正常に送信された場合、または送信されなかった場合は、フォームの下部に最終ステータスが表示されます。
  • メソッド handleValidation() を作成しましょう 検証を確認するには:

    
      const handleValidation = () => {
        let tempErrors = {};
        let isValid = true;
    
        if (fullname.length <= 0) {
          tempErrors["fullname"] = true;
          isValid = false;
        }
        if (email.length <= 0) {
          tempErrors["email"] = true;
          isValid = false;
        }
        if (subject.length <= 0) {
          tempErrors["subject"] = true;
          isValid = false;
        }
        if (message.length <= 0) {
          tempErrors["message"] = true;
          isValid = false;
        }
    
        setErrors({ ...tempErrors });
        console.log("errors", errors);
        return isValid;
      };

    この関数は非常に単純です。すべてのフィールドをチェックして、ブール値の isValid を返します。 フォームが有効な場合。

    また、最後にエラー メッセージを表示するために、すべてのフィールドの状態を維持しています。基本的には、エラーを含むフィールドを保存しています。

    最終的なコードは、ボタン テキスト、エラー メッセージ、およびフォームの検証を含む次のようになります。

    import React, { useState } from "react";
    
    export default function ContactUs() {
       // States for contact form fields
      const [fullname, setFullname] = useState("");
      const [email, setEmail] = useState("");
      const [subject, setSubject] = useState("");
      const [message, setMessage] = useState("");
    
      //   Form validation state
      const [errors, setErrors] = useState({});
    
      //   Setting button text on form submission
      const [buttonText, setButtonText] = useState("Send");
    
      // Setting success or failure messages states
      const [showSuccessMessage, setShowSuccessMessage] = useState(false);
      const [showFailureMessage, setShowFailureMessage] = useState(false);
    
      // Validation check method
      const handleValidation = () => {
        let tempErrors = {};
        let isValid = true;
    
        if (fullname.length <= 0) {
          tempErrors["fullname"] = true;
          isValid = false;
        }
        if (email.length <= 0) {
          tempErrors["email"] = true;
          isValid = false;
        }
        if (subject.length <= 0) {
          tempErrors["subject"] = true;
          isValid = false;
        }
        if (message.length <= 0) {
          tempErrors["message"] = true;
          isValid = false;
        }
    
        setErrors({ ...tempErrors });
        console.log("errors", errors);
        return isValid;
      };
    
      //   Handling form submit
    
      const handleSubmit = async (e) => {
        e.preventDefault();
    
        let isValidForm = handleValidation();
    
        if (isValidForm) {
          setButtonText("Sending");
          const res = await fetch("/api/sendgrid", {
            body: JSON.stringify({
              email: email,
              fullname: fullname,
              subject: subject,
              message: message,
            }),
            headers: {
              "Content-Type": "application/json",
            },
            method: "POST",
          });
    
          const { error } = await res.json();
          if (error) {
            console.log(error);
            setShowSuccessMessage(false);
            setShowFailureMessage(true);
            setButtonText("Send");
            return;
          }
          setShowSuccessMessage(true);
          setShowFailureMessage(false);
          setButtonText("Send");
        }
        console.log(fullname, email, subject, message);
      };
      return (
        <main>
          // Rest of the JSX code goes here. (With form fields)
        </main>
      );
    }
    

    フォームが正常に配信されると、UI で適切な応答が得られます。その応答を配信するために、showSuccessMessage があります。 と showFailureMessage 州。バックエンド API ルートからの応答にプロパティ error が含まれていない場合 、これは、フォームの送信が成功し、メールが送信されたことを意味します。

    その場合、showSuccessMessage は True に設定されており、フォーム ボックスのすぐ下に対応するマークアップが表示されます。レスポンスボディに error のプロパティが含まれている場合 、showFailureMessage が True に設定され、対応するメッセージが画面に表示されます。

    成功と失敗の両方のシナリオで、ボタンのテキストを send にリセットする必要があります sending... の代わりに .そのために、状態 setButtonText('send') を使用しています 失敗または成功の場合のボタン テキストを設定します。ボタンのテキストを sending... に設定します 送信ボタンがクリックされたとき。

    メールと UI 応答を受信する方法

    メールが正常に配信されると、連絡フォーム自体に成功メッセージが表示されます。

    SendGrid と Next.js でお問い合わせフォームを作成する方法

    そして、SendGrid によって安全に配信された、作成したばかりのテンプレートを含むメールを正常に受信できます 💯

    SendGrid と Next.js でお問い合わせフォームを作成する方法

    環境変数

    API キーを使用しており、キーは機密情報であることに注意してください。これは、秘密鍵または API キーを常に環境変数に格納する必要があることを意味します。

    すでに .env.local があるので 私たちのローカル環境では、ホスティング プロバイダーは API キーについても知る必要があります。

    Vercel は、ホスティング パネル自体に API キーを保存する簡単な方法を提供します。

    API キーを Vercel アカウントに安全に保存するには、次の手順を実行します。

    • プロジェクト ページに移動
    • 設定に移動
    • 環境変数に移動
    • 環境変数の名前を追加します。この場合は SENDGRID_API_KEY です 、対応する API キーを値フィールドに追加します。
    • アプリケーションを再デプロイすると、プロジェクトが本番環境で機能するようになります。

    ライブ デモとソース コード

    アプリケーションのソース コードとライブ デモは次のとおりです。

    ライブデモ
    ソースコード

    結論

    SendGrid は、Web サイトから電子メールを送信するために使用する優れたオプションです。 Next.js およびそのサーバーレス API ルートと統合すると、Web サイトの任意の部分にフォームを統合することが非常に簡単になります。

    SendGrid には、メールにカスタム テーマを設定できるテンプレートを統合するオプションも用意されています。

    Nodemailer のような電子メールを送信するための他のオプションもあり、過去に使用したり、プロジェクトの一部で使用したりしています.

    このアプリケーションをゼロから構築するのに約 1 時間かかりました。Next.js、TailwindCSS、SendGrid の非常に直感的なワークフローと API セマンティクスのおかげです。美しい連絡先ページ UI の Tailwind Master Kit にも感謝します。

    このブログが気に入った場合は、自分の Web サイトに実装して、エンド ユーザーに連絡できるようにしてください。

    フィードバックをお寄せになりたい場合は、私の Twitter ハンドルに連絡するか、私の Web サイトにアクセスしてください

    ハッピーコーディング。 :)


    1. SendGrid API を使用してメール ニュースレターを送信する方法

      何年もの間、Quincy Larson は、Amazon SES を利用した freeCodeCamp の Mail for Good プラットフォームを通じて、毎週のメールニュースレターを送信しました。 彼は最近、このプロセスを SendGrid に移行しました。この記事では、これを実現するためのツールをどのように構築したかを紹介します。 SendGrid アカウントの設定方法 最初のステップは、SendGrid に登録してアカウントを設定することです。このチュートリアルでは、無料利用枠で十分です。 アプリケーションをスケールアップすると、プラットフォームで利用可能なメールの制限を増

    2. Excel でフォームを使用してデータベースを作成する方法

      多くの場合、データベースの作成が必要になることがあります エクセルで。幸いなことに、Excel にはデータ入力 フォーム が用意されています。 そのようなタスクを伝統的に行うのではなく、効率的に達成すること。この有益なセッションでは、 フォーム を使用して Excel でデータベースを作成する方法を順を追って説明します。 フォームに関連するいくつかの重要事項を含む . Excel のデータ入力フォームとは 通常、ユーザーは Excel でセルごとにデータを入力します。このように入力すると、特に大規模なデータベースを作成する場合に問題が発生する可能性があります。このような状況では、デー