Computer >> Máy Tính >  >> Phần mềm >> Thư

Cách tạo biểu mẫu liên hệ với SendGrid và Next.js

Biểu mẫu liên hệ rất hữu ích trên các trang web nếu bạn muốn người dùng có thể tương tác với bạn qua email. Và có rất nhiều cách để xây dựng chúng.

Theo truyền thống, bạn sẽ sử dụng PHP để gửi email qua máy chủ hoặc một số dịch vụ của bên thứ ba sẽ xử lý logic email.

Nhưng trong bài viết này, chúng ta sẽ nói về cách gửi email từ ứng dụng Next.js của bạn bằng API SendGrid.

Chúng tôi sẽ tạo một trang đơn giản - một biểu mẫu liên hệ được xây dựng bằng React - có các trường đầu vào mà chúng tôi sẽ xác thực trước khi gửi. Chúng tôi sẽ kết nối biểu mẫu với API SendGrid, API này sẽ đảm nhận việc gửi email cho bạn. Sau đó, vào cuối ngày, tất cả những gì bạn phải làm là kiểm tra email của mình để tìm các truy vấn đó.

Tuy nhiên, nếu bạn chưa có dự án Next.js, bạn có thể dễ dàng tạo một dự án và tích hợp nó với Vercel bằng cách làm theo các bước được đề cập dưới đây:

  1. Tạo tài khoản trên Vercel và nhấp vào New Project
Cách tạo biểu mẫu liên hệ với SendGrid và Next.js

2. Chọn mẫu là Next.js :

Cách tạo biểu mẫu liên hệ với SendGrid và Next.js

3. Đặt tên cho kho lưu trữ của bạn bất kỳ thứ gì bạn muốn và nhấp vào tạo dự án. (Chọn GitHub, GitLab hoặc BitBucket để lập phiên bản mã từ xa của bạn)

Cách tạo biểu mẫu liên hệ với SendGrid và Next.js

Làm theo ba điểm trên, bạn sẽ có một kho lưu trữ trên tài khoản lập phiên bản của mình.

Tủ công nghệ mà chúng tôi sẽ sử dụng

  • Next.js để tạo trang đích biểu mẫu liên hệ
  • TailwindCSS để tạo kiểu cho các thành phần
  • SendGrid để gửi email bằng API của họ
  • Vercel để lưu trữ ứng dụng và CI / CD của chúng tôi

Chúng tôi sẽ sử dụng các tuyến API của Nextjs để xử lý các sự kiện biểu mẫu. Các mô-đun API cung cấp một cách linh hoạt để xử lý logic phụ trợ trong ứng dụng Next.js của chúng tôi.

Bất kỳ mã nào chúng ta viết trong thư mục API sẽ được triển khai dưới dạng một hàm Serverless trên Vercel để lưu trữ. Bạn có thể đọc thêm về các tuyến API Next.js tại đây

Nếu bạn đã có một dự án Next.js mà bạn muốn thiết lập một biểu mẫu liên hệ làm việc, điều đó thật tuyệt. Trong trường hợp đó, bạn sẽ dễ dàng tạo các trang và bắt đầu ngay lập tức.

Nhưng nếu bạn chưa thiết lập một dự án nào, thì không sao - hãy truy cập Vercel và tạo một dự án khởi động Next.js và sao chép kho lưu trữ.

Luồng ứng dụng

Hãy cùng xem quy trình ứng dụng - hoặc cách gửi email thực sự hoạt động:

  • Người dùng cuối điền vào 4 trường bắt buộc và nhấp vào gửi.
  • Khi gửi, handleSubmit chức năng được kích hoạt.
  • handleSubmit xác thực biểu mẫu cho các trường đầu vào và kiểm tra xem chúng có trống không.
  • Nếu các trường biểu mẫu không trống, một lệnh gọi API được thực hiện tới api/sendgrid nơi logic của việc gửi email.
  • Trong api/sendgrid , @sendgrid/mail mô-đun khởi tạo một send hàm lấy khóa API của ứng dụng của bạn và gửi email với các trường bắt buộc.
  • Nếu email được gửi thành công, 200 phản hồi được gửi đến máy khách, nếu không thì 400 phản hồi được gửi đến khách hàng.
  • Các phản hồi được xử lý ở giao diện người dùng và các thông báo thích hợp sẽ được hiển thị.

Cách thiết lập TailwindCSS

Việc thiết lập TailwindCSS khá dễ dàng và bạn có thể thực hiện theo hai cách đơn giản.

  1. Cài đặt TailwindCSS làm phụ thuộc trong dự án của bạn:
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest

2. Khởi tạo tệp cấu hình TailwindCSS cho dự án của bạn. Điều này sẽ tạo ra một tailwind.config.js tệp trong thư mục gốc:

npx tailwindcss init

Sau đó, bạn sẽ cần chỉnh sửa tệp cấu hình, bao gồm purge và bật jit chế độ:

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: [],
  }

Bạn sử dụng purge để xóa các kiểu không mong muốn khỏi dự án của bạn tại thời điểm xây dựng. Sẽ rất hữu ích nếu bạn muốn giảm kích thước gói CSS.

jit là chế độ TailwindCSS mới, nơi bạn có thể chỉ định tên lớp động trong chính mã.

Ví dụ:nếu bạn muốn có kích thước văn bản của mình là 10px (chưa có trong mô-đun TailwindCSS), bạn có thể viết text-[10px] trong tên lớp của bạn và nó sẽ phản ánh tự động. Không cần phải viết các thuộc tính kiểu tùy chỉnh nữa. 💯

Tiếp theo, nhập các kiểu Tailwind trong thư mục gốc của bạn _app.js tệp:

// pages/_app.js
 import '../styles/globals.css'
 import 'tailwindcss/tailwind.css'

  function MyApp({ Component, pageProps }) {
    return <Component {...pageProps} />
  }

  export default MyApp

Sau đó, bao gồm CSS cốt lõi của Tailwind trong biểu định kiểu cấp gốc của bạn như sau:

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

Với điều này, bạn đã thiết lập thành công TailwindCSS cho dự án của mình.

Đánh dấu và Tạo kiểu cho Trang Liên hệ

Cách tạo biểu mẫu liên hệ với SendGrid và Next.js

Chúng tôi sẽ xây dựng trang web hoàn toàn bằng Tailwind. Tôi lấy trang trực tiếp từ Bộ công cụ Tailwind Master Kit, đây là thư viện mẫu và thành phần dành cho các dự án web Tailwind.

Hãy xem qua HTML của trang (về cơ bản là biểu mẫu liên hệ) để hiểu cách mọi thứ được triển khai:

<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>

Biểu mẫu có 4 trường:

  • Họ và Tên
  • Email
  • Chủ đề
  • Tin nhắn

Tất cả các trường là bắt buộc - và chúng tôi cũng sẽ xác thực chúng sau này. Bạn sẽ mong đợi người dùng của mình cung cấp cho bạn tất cả thông tin chi tiết của họ khi gửi email.

Để nắm bắt các trường, chúng tôi sẽ sử dụng hook useState () của React để đảm bảo rằng dữ liệu của chúng tôi được duy trì trong ứng dụng.

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>
	)
}

Lưu ý thuộc tính biểu mẫu onSubmit={handleSubmit} . Đây là chức năng mà chúng ta sẽ thực sự gửi email thông qua SendGrid. Nhưng trước đó, hãy tạo một Dự án SendGrid và truy xuất API keys .

Cách thiết lập dự án SendGrid

Cách tạo biểu mẫu liên hệ với SendGrid và Next.js

Đầu tiên, bạn chỉ cần truy cập trang chủ của SendGrid và đăng ký tài khoản (nếu bạn chưa có).

Sau khi tạo tài khoản thành công, hãy đăng ký API Key. Bạn có thể làm điều đó tại đây.

Sendgrid yêu cầu bạn tạo Danh tính Người gửi để bảo vệ khỏi thư rác và thư độc hại. Để làm như vậy, hãy truy cập trang Sendgrid Identity và nhấp vào Create New Sender để tạo danh tính người gửi.

Bạn sẽ phải điền vào một biểu mẫu chi tiết. Chỉ cần hoàn thành biểu mẫu và nhấn gửi. Cuối cùng, chỉ cần xác minh địa chỉ email của bạn và bạn đã hoàn tất.

Khi bạn đã truy xuất API keys , tạo một .env.local tệp trong môi trường cục bộ của bạn và dán mã sau:

SENDGRID_API_KEY= YOUR_API_KEY_HERE

Thay thế YOUR_API_KEY_HERE với khóa API bạn vừa truy xuất.

Cách tạo một tuyến API không máy chủ

Tạo một tuyến API không máy chủ khá dễ dàng với Next.js.

Đi tới /pages/api và bên trong api thư mục tạo một tệp có tên 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 yêu cầu chúng tôi khởi tạo sendgrid đối tượng với các khóa API với setApiKey() phương pháp. Khởi tạo đối tượng bằng khóa API của bạn và bạn có thể gửi email bằng send() phương pháp.

Về cơ bản có bốn trường được yêu cầu trong send() phần thân của phương thức:

  • to - Địa chỉ email mà bạn muốn gửi email của mình
  • from - Email SendGrid của bạn mà bạn đã sử dụng để Xác minh Danh tính Người gửi. Email của bạn sẽ được gửi từ email này.
  • subject - Dòng chủ đề của email
  • message - nội dung thư của email

Chúng tôi sẽ tự xây dựng bốn thông số này để có thể hiểu email của mình tốt hơn. Đây là mã được cập nhật từ cùng một đoạn mã ở trên:

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;

Nếu bạn muốn gửi html trong nội dung email, bạn cũng sẽ phải sử dụng các kiểu nội tuyến có trong ví dụ.

Ở đây, về cơ bản chúng tôi đang sử dụng send() của SendGrid phương pháp được cung cấp bởi API SendGrid để gửi email. Chúng tôi sử dụng send() với sendgrid đối tượng mà chúng tôi đã khởi tạo bằng khóa API. Điều này đảm bảo rằng các email của chúng tôi được bảo mật và chỉ được gửi khi có sự cho phép của chúng tôi.

Ngoài ra, chúng tôi đã bọc mã trong một try - catch khối. Điều này đảm bảo rằng ứng dụng của chúng tôi có thể xử lý các ngoại lệ và lỗi một cách chính xác. Nếu do bất kỳ thay đổi nào mà việc gửi email không thành công, thì mã sẽ ngay lập tức rơi vào catch() chặn và chúng tôi trả về một error sự vật. Điều này cho thấy rằng đã có một số vấn đề ở phía sau.

Nhìn vào phản hồi API từ back-end, front-end sẽ phản hồi tương ứng và giao diện người dùng thay đổi.

Kiểu đi vào html thuộc tính bên trong của send() phần thân của phương thức. Bạn muốn tạo kiểu email như thế nào hoàn toàn phụ thuộc vào bạn. Ở đây, tôi đã bao gồm một mẫu đơn giản có chân trang cho Twitter, Instagram, GitHub và trang web của mình, cùng với nội dung thư gốc mà người dùng cuối gửi.

Bây giờ tuyến API của chúng tôi đã được thiết lập, vì vậy hãy chuyển sang giao diện người dùng và tìm hiểu cách xử lý phản hồi một cách chính xác.

Cách Gọi API và Xử lý Phản hồi

Vì tuyến API của chúng tôi đã được thiết lập, nên bây giờ chúng tôi sẽ gọi API không máy chủ của mình và tìm nạp phản hồi.

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>
  );
}

Ở đây chúng tôi đang gọi API mà chúng tôi vừa tạo bằng fetch , được cung cấp bởi React.

Tìm nạp gọi API không máy chủ với phần thân như sau:

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

Đây là các trường biểu mẫu của chúng tôi với dữ liệu biểu mẫu đã được điền (hãy nhớ useState() ?) hiện có sẵn cho chúng tôi.

API phản hồi thành công hoặc thất bại. Nếu thành công, email sẽ được gửi - nếu không, thư sẽ không được gửi.

Để người dùng cuối biết trạng thái biểu mẫu, chúng tôi cần hiển thị một số phần tử giao diện người dùng. Nhưng trước đó, chúng ta cần xử lý những gì sẽ xảy ra nếu có các trường trống.

Cách xử lý xác thực biểu mẫu và khiến giao diện người dùng phản hồi API phản hồi

Cách tạo biểu mẫu liên hệ với SendGrid và Next.js

Chúng ta cần đảm bảo 3 điều ở đây:

  1. Tất cả các trường phải được điền vào - nghĩa là chúng tôi không thể gửi biểu mẫu nếu bất kỳ trường nào trống. Ngoài ra, người dùng phải biết lý do tại sao biểu mẫu không được gửi. Vì vậy, chúng tôi sẽ hiển thị các thông báo lỗi.
  2. Trong khi biểu mẫu đang được gửi, người dùng phải biết rằng một số quá trình xử lý đang diễn ra. Vì vậy, chúng tôi sẽ thay đổi văn bản của nút khi biểu mẫu đang trong quá trình gửi.
  3. Khi biểu mẫu được gửi thành công hoặc nếu không thành công, chúng tôi sẽ hiển thị trạng thái cuối cùng ở cuối biểu mẫu.

Hãy tạo một phương thức handleValidation() để kiểm tra xác thực:


  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;
  };

Hàm khá đơn giản:nó kiểm tra tất cả các trường và trả về một boolean isValid nếu biểu mẫu hợp lệ.

Ngoài ra, chúng tôi đang duy trì trạng thái cho tất cả các trường hiển thị thông báo lỗi ở cuối - về cơ bản, chúng tôi đang lưu các trường có lỗi.

Mã cuối cùng trông giống như thế này, với văn bản nút, thông báo lỗi và xác thực biểu mẫu:

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>
  );
}

Khi biểu mẫu được gửi thành công, chúng tôi nhận được phản hồi tốt tại giao diện người dùng. Để gửi phản hồi đó, chúng tôi có showSuccessMessageshowFailureMessage Những trạng thái. Nếu phản hồi từ tuyến API phía sau KHÔNG chứa thuộc tính error , điều đó có nghĩa là gửi biểu mẫu thành công và email đã được gửi.

Trong trường hợp đó, showSuccessMessage được đặt thành True, hiển thị đánh dấu tương ứng ngay bên dưới hộp Biểu mẫu. Nếu nội dung phản hồi chứa thuộc tính của error , showFailureMessage được đặt thành Đúng và thông báo tương ứng được hiển thị trên màn hình.

Trong cả trường hợp thành công và thất bại, chúng tôi phải đặt lại văn bản nút thành send thay vì sending... . Đối với điều đó, chúng tôi đang sử dụng trạng thái setButtonText('send') đặt văn bản nút trong trường hợp thất bại hoặc thành công. Chúng tôi đặt văn bản nút thành sending... khi nút Gửi được nhấp.

Cách nhận email và phản hồi giao diện người dùng

Khi email được gửi thành công, chúng tôi sẽ nhận được thông báo thành công trong chính biểu mẫu liên hệ.

Cách tạo biểu mẫu liên hệ với SendGrid và Next.js

Và bạn sẽ nhận được thành công một email với mẫu mà chúng tôi vừa tạo, được gửi an toàn bởi SendGrid 💯

Cách tạo biểu mẫu liên hệ với SendGrid và Next.js

Biến môi trường

Xin lưu ý rằng chúng tôi đang sử dụng các khóa API và các khóa này rất nhạy cảm. Điều này có nghĩa là chúng tôi phải luôn lưu trữ khóa bí mật hoặc khóa API trong các biến môi trường.

Vì chúng ta đã có .env.local đối với môi trường cục bộ của chúng tôi, nhà cung cấp dịch vụ lưu trữ cũng cần biết về các khóa API.

Vercel cung cấp một cách dễ dàng để lưu trữ các khóa API trên chính bảng điều khiển lưu trữ.

Để lưu trữ các khóa API một cách an toàn trong tài khoản Vercel của bạn, hãy làm như sau:

  • Truy cập trang dự án của bạn
  • Đi tới cài đặt
  • Chuyển đến Biến môi trường
  • Thêm tên của biến môi trường, trong trường hợp của chúng tôi là SENDGRID_API_KEY và thêm khóa API tương ứng vào trường giá trị.
  • Triển khai lại ứng dụng của bạn và dự án của bạn sẽ hoạt động trong môi trường sản xuất.

Bản trình diễn trực tiếp và mã nguồn

Đây là mã nguồn và bản demo trực tiếp của ứng dụng:

Bản thử trực tiếp
Mã nguồn

Kết luận

SendGrid là một tùy chọn tuyệt vời để sử dụng để gửi email từ một trang web. Khi bạn tích hợp nó với Next.js và các tuyến API không máy chủ của họ, việc tích hợp các biểu mẫu vào bất kỳ phần nào trên trang web của bạn trở nên cực kỳ dễ dàng.

SendGrid cũng cung cấp cho bạn một tùy chọn để tích hợp các mẫu nơi bạn có thể có các chủ đề tùy chỉnh cho email của mình.

Cũng có các tùy chọn khác để gửi email như Nodemailer mà tôi đã sử dụng trước đây và vẫn đang sử dụng cho một số dự án của mình.

Tôi đã mất khoảng một giờ để xây dựng ứng dụng này từ đầu - tất cả là nhờ Next.js, TailwindCSS và SendGrid vì quy trình làm việc và ngữ nghĩa API cực kỳ trực quan của họ. Đồng thời, cảm ơn Bộ công cụ Tailwind Master cho giao diện người dùng Trang liên hệ đẹp mắt.

Nếu bạn thích blog này, hãy thử triển khai nó trong trang web của riêng bạn để bạn có thể tiếp cận với người dùng cuối của mình.

Nếu bạn muốn đưa ra bất kỳ phản hồi nào, hãy liên hệ với tôi tại bộ phận xử lý Twitter của tôi hoặc truy cập Trang web của tôi

Chúc bạn viết mã vui vẻ. :)