Computer >> 컴퓨터 >  >> 소프트웨어 >> 우편

SendGrid 및 Next.js를 사용하여 연락처 양식을 작성하는 방법

연락처 양식은 사용자가 이메일을 통해 귀하와 상호 작용할 수 있도록 하려는 경우 웹 사이트에서 유용합니다. 그리고 이를 구축하는 방법은 많습니다.

전통적으로 서버를 통해 이메일을 보내기 위해 PHP를 사용했거나 이메일 로직을 처리하는 타사 서비스를 사용했을 것입니다.

하지만 이 기사에서는 SendGrid API를 사용하여 Next.js 애플리케이션에서 이메일을 보내는 방법에 대해 이야기할 것입니다.

보내기 전에 유효성을 검사할 입력 필드가 있는 간단한 페이지(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를 사용하여 연락처 양식을 작성하는 방법

위의 세 가지 사항을 따르면 버전 관리 계정에 저장소가 생깁니다.

우리가 사용할 기술 스택

  • 문의 양식 방문 페이지를 만들기 위한 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 키를 가져와 필수 필드가 포함된 이메일을 보내는 함수입니다.
  • 이메일이 성공적으로 전달되면 Create New Sender 응답은 클라이언트로 전송되고, 그렇지 않으면 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]를 작성할 수 있습니다. 클래스 이름에 자동으로 반영됩니다. 더 이상 사용자 정의 스타일 속성을 작성할 필요가 없습니다. 💯

다음으로 루트 _app.js에서 Tailwind 스타일을 가져옵니다. 파일:

// 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로 웹페이지를 완전히 구축하겠습니다. Tailwind 웹 프로젝트를 위한 구성 요소 및 템플릿 라이브러리인 Tailwind Master Kit에서 직접 페이지를 가져왔습니다.

페이지의 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 경로를 만드는 방법

Next.js를 사용하면 서버리스 API 경로를 만드는 것이 매우 쉽습니다.

/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를 초기화해야 합니다. setApiKey()이 있는 API 키가 있는 객체 방법. API 키로 개체를 초기화하고 send()로 이메일을 보낼 수 있습니다. 방법.

send()에는 기본적으로 4개의 필드가 필요합니다. 메소드 본문:

  • 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을 보내려면 이메일 본문에서는 예제에도 있는 인라인 스타일을 사용해야 합니다.

여기서는 본질적으로 SendGrid의 send()를 사용하고 있습니다. 이메일을 보내기 위해 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>
  );
}

여기서 우리는 fetch로 방금 만든 API를 호출합니다. , React에서 제공합니다.

Fetch는 다음과 같이 본문을 사용하여 서버리스 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... 대신 . 이를 위해 setButtonText('send') 상태를 사용하고 있습니다. 실패 또는 성공의 경우 버튼 텍스트를 설정합니다. 버튼 텍스트를 sending...로 설정합니다. 보내기 버튼을 클릭했을 때.

이메일 및 UI 응답 수신 방법

이메일이 성공적으로 전달되면 문의 양식 자체에 성공 메시지가 표시됩니다.

SendGrid 및 Next.js를 사용하여 연락처 양식을 작성하는 방법

그리고 방금 만든 템플릿이 포함된 이메일을 성공적으로 받게 될 것입니다. SendGrid에서 안전하게 전달합니다 💯

SendGrid 및 Next.js를 사용하여 연락처 양식을 작성하는 방법

환경 변수

API 키를 사용하고 있으며 키는 민감합니다. 이것은 우리가 항상 환경 변수에 비밀 또는 API 키를 저장해야 한다는 것을 의미합니다.

이미 .env.local이 있으므로 로컬 환경의 경우 호스팅 제공업체도 API 키에 대해 알아야 합니다.

Vercel은 호스팅 패널 자체에 API 키를 쉽게 저장할 수 있는 방법을 제공합니다.

Vercel 계정에 API 키를 안전하게 저장하려면 다음을 수행하십시오.

  • 프로젝트 페이지로 이동
  • 설정으로 이동
  • 환경 변수로 이동
  • 환경 변수의 이름을 추가합니다. 이 경우에는 SENDGRID_API_KEY입니다. , 값 필드에 해당 API 키를 추가합니다.
  • 애플리케이션을 다시 배포하면 프로젝트가 프로덕션 환경에서 작동합니다.

라이브 데모 및 소스 코드

다음은 애플리케이션의 소스 코드와 라이브 데모입니다.

라이브 데모
소스 코드

결론

SendGrid는 웹사이트에서 이메일을 보내는 데 사용할 수 있는 훌륭한 옵션입니다. Next.js 및 서버리스 API 경로와 통합하면 웹 사이트의 어느 부분에서나 양식을 통합하기가 매우 쉬워집니다.

또한 SendGrid는 이메일에 대한 사용자 정의 테마를 가질 수 있는 템플릿을 통합하는 옵션을 제공합니다.

Nodemailer와 같은 이메일을 보낼 수 있는 다른 옵션도 있습니다. 예전에 사용했고 여전히 일부 프로젝트에서 사용하고 있습니다.

Next.js, TailwindCSS 및 SendGrid의 매우 직관적인 워크플로 및 API 의미 덕분에 이 애플리케이션을 처음부터 빌드하는 데 약 1시간이 걸렸습니다. 또한 아름다운 연락처 페이지 UI를 제공하는 Tailwind Master Kit에 감사드립니다.

이 블로그가 마음에 들면 최종 사용자에게 다가갈 수 있도록 자신의 웹사이트에 구현해 보십시오.

피드백을 제공하려면 내 Twitter 핸들로 연락하거나 내 웹사이트를 방문하세요.

즐거운 코딩. :)