<aside> 🌿 cors対策でAPI Routes経由でGoogleフォームに送信する Contact.js → API Routes → Googleフォーム

corsについて

なんとなく CORS がわかる...はもう終わりにする。 - Qiita

</aside>

■目次

必要パッケージをインストールする

react-hook-formとaxiosをnpmインストールする

npm install react-hook-form
npm install axios

Googleフォーム情報をファイルにまとめる

libフォルダ内にContactGoogleForm.jsファイルを作成し、Googleフォーム作成時に取得した送信先URLやデータ格納先をまとめる

export const ContactGoogleForm = {
  action:
    "<https://docs.google.com/forms/u/0/d/e/1FAIpQLScCFvJMU3J882bktGtGV0c_1Xq7Z3ysnGDpz1WLH4FqUUKqkg/formResponse>",
  companyName: "entry.1580407982",
  name: "entry.1140952699",
  mail: "entry.382526683",
  radio: "entry.259792052",
  textarea: "entry.1370165325",
};

送信するための処理を記述する

フォームコンポーネントを記述しているファイル(Contact.js)を開き、送信するための処理を記述する

<aside> 🌿 各input、textareaタグはuseStateで値更新できるようにしておこう スニペットにコードはあるよ

ここには送信処理のみ記述

</aside>

// contact送信関連に必要
import { useForm } from "react-hook-form";
import { ContactGoogleForm } from "../../lib/ContactGoogleForm";
import axios from "axios";

export default function Contact() {

// useForm
  const { handleSubmit } = useForm({
    mode: "onChange",
  });

  const submit = async () => {    
    // axios.postのParam生成
    const submitParams = new FormData();
    submitParams.append(ContactGoogleForm.companyName, companyName); //inputのvalueに入れている変数(=state)
    submitParams.append(ContactGoogleForm.name, name);
    submitParams.append(ContactGoogleForm.mail, mail);
    submitParams.append(ContactGoogleForm.radio, radio);
    submitParams.append(ContactGoogleForm.textarea, textarea);
    
    // 実行
    await axios
      .post(`/api/proxy/cors`, submitParams) // API Routesに値を渡す
      .then(() => {
        window.location.href = "/thanks"; // 成功時
      })
      .catch((error) => {
        console.log(error.response); // 失敗時
      });
  };

return (
		<form **onSubmit={handleSubmit(submit)}** className={styles.form}>
		// input要素を記述
		</form>);
}

API Routesを作成する

<aside> 🌿 マーカー部分は一つでも欠けると400エラーになるので要注意

</aside>

import axios from "axios";
import { ContactGoogleForm } from "../../../lib/ContactGoogleForm";

// multipart/form-data を使用するのに必要。ないとtext/plainに変換されてしまう。
**export const config = {
  api: {
    bodyParser: false,
  },
};**

export default async function handler(req, res) {
  const formData = req; // Contact.jsから受け取ったフォームデータ諸々
  try {
    await axios.post(ContactGoogleForm.action, **formData**, {
      **headers: {
        "Content-type": req.headers["content-type"],
      },**
    });
    res.status(200).json();
  } catch (error) {
    console.log(error.response);
    return res.status(error.status || 500).end(error.message);
  }
}

参考

▼API RoutesでフォームデータをPOST送信する書き方

How could I use A Multipart-Form In Next.js using API Routes with Django in back end · Discussion #36153 · vercel/next.js