Computer >> คอมพิวเตอร์ >  >> ซอฟต์แวร์ >> จดหมาย

วิธีสร้างแบบฟอร์มการติดต่อด้วย SendGrid และ Next.js

แบบฟอร์มการติดต่อมีประโยชน์ในเว็บไซต์หากคุณต้องการให้ผู้ใช้โต้ตอบกับคุณทางอีเมลได้ และมีหลายวิธีในการสร้าง

ตามเนื้อผ้า คุณจะใช้ PHP ในการส่งอีเมลผ่านเซิร์ฟเวอร์หรือบริการของบุคคลที่สามที่จะดูแลตรรกะของอีเมล

แต่ในบทความนี้ เราจะพูดถึงวิธีส่งอีเมลจากแอปพลิเคชัน Next.js ของคุณด้วย SendGrid API

เรากำลังจะสร้างหน้าธรรมดา – แบบฟอร์มการติดต่อที่สร้างด้วย React – ที่มีช่องใส่ซึ่งเราจะตรวจสอบก่อนส่ง เราจะเชื่อมต่อแบบฟอร์มกับ SendGrid API ซึ่งจะดูแลการส่งอีเมลถึงคุณ จากนั้นเมื่อสิ้นสุดวัน สิ่งที่คุณต้องทำคือตรวจสอบอีเมลเพื่อค้นหาคำถามเหล่านั้น

อย่างไรก็ตาม หากคุณยังไม่มีโปรเจ็กต์ Next.js คุณสามารถสร้างโปรเจ็กต์และรวมเข้ากับ Vercel ได้อย่างง่ายดายโดยทำตามขั้นตอนที่กล่าวถึงด้านล่าง:

  1. สร้างบัญชีบน Vercel และคลิกที่ New Project
วิธีสร้างแบบฟอร์มการติดต่อด้วย SendGrid และ Next.js

2. เลือกเทมเพลตเป็น Next.js :

วิธีสร้างแบบฟอร์มการติดต่อด้วย SendGrid และ Next.js

3. ตั้งชื่อที่เก็บของคุณตามที่คุณต้องการและคลิกที่สร้างโครงการ (เลือก GitHub, GitLab หรือ BitBucket สำหรับการกำหนดเวอร์ชันโค้ดจากระยะไกล)

วิธีสร้างแบบฟอร์มการติดต่อด้วย SendGrid และ Next.js

ตามสามประเด็นข้างต้น คุณจะมีที่เก็บในบัญชีการกำหนดเวอร์ชันของคุณ

Tech Stack ที่เราจะใช้

  • Next.js สำหรับสร้างหน้า Landing Page ของแบบฟอร์มการติดต่อ
  • TailwindCSS สำหรับใส่สไตล์ส่วนประกอบ
  • SendGrid สำหรับการส่งอีเมลโดยใช้ API
  • Vercel สำหรับโฮสต์แอปพลิเคชันของเราและ CI/CD

เราจะใช้เส้นทาง API ของ Nextjs เพื่อจัดการกับเหตุการณ์ในแบบฟอร์ม โมดูล API เป็นวิธีที่ยืดหยุ่นในการจัดการกับตรรกะของแบ็กเอนด์ในแอปพลิเคชัน Next.js ของเรา

รหัสใดก็ตามที่เราเขียนในโฟลเดอร์ API จะถูกปรับใช้เป็นฟังก์ชัน Serverless บน Vercel สำหรับการโฮสต์ คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเส้นทาง Next.js API ได้ที่นี่

หากคุณมีโปรเจ็กต์ Next.js อยู่แล้วซึ่งต้องการตั้งค่าแบบฟอร์มการติดต่อที่ใช้งานได้ ถือว่าเยี่ยมมาก ในกรณีนั้น การสร้างเพจและเริ่มต้นใช้งานได้ง่ายสำหรับคุณ

แต่ถ้าคุณยังไม่ได้ตั้งค่าโปรเจ็กต์ ก็ไม่เป็นไร ไปที่ Vercel แล้วสร้างโปรเจ็กต์เริ่มต้น Next.js และโคลนที่เก็บ

ขั้นตอนการสมัคร

มาดูขั้นตอนการสมัครกัน – หรือการส่งอีเมลทำงานอย่างไร:

  • ผู้ใช้ปลายทางกรอกข้อมูลในฟิลด์บังคับ 4 ช่องแล้วคลิกส่ง
  • เมื่อส่ง handleSubmit ฟังก์ชันถูกทริกเกอร์
  • handleSubmit ตรวจสอบแบบฟอร์มสำหรับช่องใส่และตรวจสอบว่าไม่ว่างเปล่า
  • ถ้าช่องกรอกไม่ว่างเปล่า จะมีการเรียก API ไปที่ api/sendgrid ที่ซึ่งตรรกะของการส่งอีเมลมีชีวิตอยู่
  • ใน api/sendgrid , @sendgrid/mail โมดูลเริ่มต้น send ฟังก์ชันที่ใช้คีย์ API ของแอปพลิเคชันของคุณและส่งอีเมลพร้อมช่องที่ต้องกรอก
  • หากส่งอีเมลสำเร็จ 200 การตอบสนองจะถูกส่งไปยังไคลเอนต์ มิฉะนั้น 400 คำตอบจะถูกส่งไปยังไคลเอนต์
  • การตอบกลับจะได้รับการจัดการที่ส่วนหน้าและข้อความที่เหมาะสมจะปรากฏขึ้น

วิธีการตั้งค่า TailwindCSS

การตั้งค่า TailwindCSS นั้นค่อนข้างง่าย และคุณสามารถทำได้สองวิธีง่ายๆ

  1. ติดตั้ง 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

จากนั้นรวม CSS หลักของ Tailwind ไว้ในสไตล์ชีตระดับรูทของคุณดังนี้:

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

ด้วยเหตุนี้ คุณจึงตั้งค่า TailwindCSS สำหรับโปรเจ็กต์ของคุณสำเร็จ

มาร์กอัปและการจัดรูปแบบสำหรับหน้าติดต่อ

วิธีสร้างแบบฟอร์มการติดต่อด้วย SendGrid และ Next.js

เราจะสร้างหน้าเว็บอย่างสมบูรณ์ด้วย Tailwind ฉันได้รับหน้านั้นโดยตรงจาก Tailwind Master Kit ซึ่งเป็นไลบรารีส่วนประกอบและเทมเพลตสำหรับโปรเจ็กต์เว็บของ 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 ช่อง:

  • ชื่อเต็ม
  • อีเมล
  • เรื่อง
  • ข้อความ

ฟิลด์ทั้งหมดเป็นฟิลด์บังคับ – และเราจะตรวจสอบความถูกต้องในภายหลังด้วย คุณคาดหวังให้ผู้ใช้ให้รายละเอียดทั้งหมดแก่คุณขณะส่งอีเมล

ในการจับภาพฟิลด์ เราจะใช้ useState() hook ของ React เพื่อให้แน่ใจว่าข้อมูลของเรายังคงอยู่ในแอปพลิเคชัน

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 Project และดึงข้อมูล API keys . กันก่อน .

วิธีการตั้งค่าโปรเจ็กต์ SendGrid

วิธีสร้างแบบฟอร์มการติดต่อด้วย SendGrid และ Next.js

ขั้นแรก คุณต้องไปที่หน้าแรกของ SendGrid และลงชื่อสมัครใช้บัญชี (หากคุณยังไม่มี)

หลังจากสร้างบัญชีสำเร็จแล้ว ให้ลงทะเบียนสำหรับคีย์ API สามารถทำได้ที่นี่

Sendgrid ต้องการให้คุณสร้าง Sender Identity เพื่อป้องกันสแปมและอีเมลที่เป็นอันตราย โดยไปที่หน้า Sendgrid Identity และคลิกที่ Create New Sender เพื่อสร้างตัวตนผู้ส่ง

คุณจะถูกขอให้กรอกแบบฟอร์มโดยละเอียด เพียงกรอกแบบฟอร์มและกดส่ง สุดท้าย เพียงยืนยันที่อยู่อีเมลของคุณ เท่านี้ก็เสร็จเรียบร้อย

เมื่อคุณได้รับ 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: "mannuarora7000@gmail.com", // Your email where you'll receive emails
      from: "manuarorawork@gmail.com", // 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 ออบเจ็กต์ที่มีคีย์ API พร้อม setApiKey() กระบวนการ. เริ่มต้นวัตถุด้วยคีย์ API ของคุณและคุณสามารถส่งอีเมลด้วย send() วิธีการ

โดยพื้นฐานแล้วมีสี่ฟิลด์ที่จำเป็นใน send() เนื้อหาของเมธอด:

  • to – ที่อยู่อีเมลที่คุณต้องการให้ส่งอีเมล์
  • from – อีเมล SendGrid ของคุณที่คุณใช้สำหรับการยืนยันตัวตนของผู้ส่ง อีเมลของคุณจะถูกส่งจากอีเมลนี้
  • subject – หัวเรื่องของอีเมล
  • message – เนื้อความของอีเมล

เราจะสร้างพารามิเตอร์ทั้งสี่นี้ด้วยตนเองเพื่อให้เราเข้าใจอีเมลของเราได้ดีขึ้น นี่คือรหัสที่อัปเดตจากตัวอย่างเดียวกันด้านบน:

import sendgrid from "@sendgrid/mail";

sendgrid.setApiKey(process.env.SENDGRID_API_KEY);

async function sendEmail(req, res) {
  try {
    await sendgrid.send({
      to: "youremail@gmail.com", // Your email where you'll receive emails
      from: "youremail@gmail.com", // 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 ในเนื้อหาอีเมล คุณจะต้องใช้รูปแบบอินไลน์ซึ่งมีอยู่ในตัวอย่างด้วย

ที่นี่เราใช้ send() . ของ SendGrid เป็นหลัก วิธีการที่กำหนดโดย SendGrid API เพื่อส่งอีเมล เราใช้ send() วิธีการด้วย sendgrid วัตถุที่เราเริ่มต้นด้วยคีย์ API เพื่อให้แน่ใจว่าอีเมลของเราปลอดภัยและจัดส่งโดยได้รับอนุญาตจากเราเท่านั้น

นอกจากนี้ เราได้รวมโค้ดไว้ใน try - catch บล็อก. เพื่อให้แน่ใจว่าแอปพลิเคชันของเราสามารถจัดการกับข้อยกเว้นและข้อผิดพลาดได้อย่างถูกต้อง หากการเปลี่ยนแปลงใด ๆ การส่งอีเมลล้มเหลว รหัสจะตกไปอยู่ใน catch() . ทันที บล็อกและเราส่งคืน error วัตถุ. นี่แสดงว่ามีปัญหาบางอย่างในแบ็กเอนด์

เมื่อดูการตอบสนองของ API จากส่วนหลัง ส่วนหน้าจะตอบสนองตามนั้นและ UI จะเปลี่ยนไป

ใส่สไตล์เข้าไปใน html แอตทริบิวต์ภายใน send() ร่างกายวิธีการ วิธีที่คุณต้องการจัดรูปแบบอีเมลของคุณขึ้นอยู่กับคุณ ในที่นี้ ฉันได้รวมเทมเพลตอย่างง่ายพร้อมส่วนท้ายของ Twitter, Instagram, GitHub และเว็บไซต์ พร้อมด้วยเนื้อหาข้อความต้นฉบับที่ผู้ใช้ปลายทางส่ง

ตอนนี้เส้นทาง 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

การดึงข้อมูลเรียก API แบบไร้เซิร์ฟเวอร์ด้วยเนื้อหาดังนี้:

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

นี่คือช่องแบบฟอร์มของเราที่มีการกรอกข้อมูลในแบบฟอร์มแล้ว (จำ useState() ?) ซึ่งตอนนี้มีให้เราแล้ว

API ตอบสนองด้วยความสำเร็จหรือความล้มเหลว หากสำเร็จ อีเมลจะถูกส่ง มิฉะนั้น อีเมลจะไม่ถูกส่ง

เพื่อให้ผู้ใช้ปลายทางทราบสถานะแบบฟอร์ม เราจำเป็นต้องแสดงองค์ประกอบ UI บางอย่าง แต่ก่อนหน้านั้นเราจำเป็นต้องจัดการกับสิ่งที่เกิดขึ้นหากมีช่องว่าง

วิธีจัดการการตรวจสอบแบบฟอร์มและทำให้ UI ตอบสนองต่อการตอบสนองของ API

วิธีสร้างแบบฟอร์มการติดต่อด้วย SendGrid และ Next.js

เราต้องแน่ใจว่า 3 สิ่งต่อไปนี้:

  1. ควรกรอกข้อมูลในฟิลด์ทั้งหมด นั่นคือ เราไม่สามารถส่งแบบฟอร์มได้หากฟิลด์ใดว่าง นอกจากนี้ ผู้ใช้ต้องรู้ว่าเหตุใดจึงไม่ส่งแบบฟอร์ม สำหรับสิ่งนั้น เราจะแสดงข้อความแสดงข้อผิดพลาด
  2. ขณะที่กำลังส่งแบบฟอร์ม ผู้ใช้ต้องรู้ว่ากำลังดำเนินการบางอย่างอยู่ สำหรับสิ่งนั้น เราจะเปลี่ยนข้อความปุ่มเมื่อแบบฟอร์มอยู่ในขั้นตอนการส่ง
  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... . เพื่อที่เราใช้ state 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 เป็นตัวเลือกที่ยอดเยี่ยมในการส่งอีเมลจากเว็บไซต์ เมื่อคุณรวมเข้ากับ Next.js และเส้นทาง API แบบไร้เซิร์ฟเวอร์ มันจะกลายเป็นเรื่องง่ายมากที่จะรวมแบบฟอร์มในส่วนใด ๆ ของเว็บไซต์ของคุณ

SendGrid ยังให้ตัวเลือกแก่คุณในการผสานรวมเทมเพลต ซึ่งคุณสามารถกำหนดธีมสำหรับอีเมลของคุณได้

มีตัวเลือกอื่นๆ เช่นกันสำหรับการส่งอีเมล เช่น Nodemailer ที่ฉันเคยใช้และยังคงใช้สำหรับบางโครงการของฉัน

ฉันใช้เวลาประมาณหนึ่งชั่วโมงในการสร้างแอปพลิเคชันนี้ตั้งแต่เริ่มต้น ทั้งหมดนี้ต้องขอบคุณ Next.js, TailwindCSS และ SendGrid สำหรับเวิร์กโฟลว์ที่ใช้งานง่ายและความหมายของ API และต้องขอบคุณ Tailwind Master Kit สำหรับ UI ของหน้าติดต่อที่สวยงาม

หากคุณชอบบล็อกนี้ ให้ลองใช้บล็อกนี้ในเว็บไซต์ของคุณเอง เพื่อให้คุณสามารถเข้าถึงผู้ใช้ปลายทางได้

หากคุณต้องการแสดงความคิดเห็น โปรดติดต่อฉันที่ Twitter หรือเยี่ยมชมเว็บไซต์ของฉัน

มีความสุขในการเข้ารหัส :)