'Hiding URL in fetch request on client-side in Next.js

I have a simple contact form in Next.js that sends an email by using the FormSubmit api when the submit button is clicked: The code for the onSubmit handler is as follows:

const handleSubmit = async (e) => {
  e.preventDefault();
  const res = await fetch("https://formsubmit.co/ajax/[email protected]", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Accept: "application/json",
    },
    body: JSON.stringify({
      name: "FormSubmit",
      message: "I'm from Devro LABS",
    }),
  })
    .then((response) => response.json())
    .then((data) => console.log(data))
    .catch((error) => console.log(error));
};

I want to hide the fetch request URL i.e., https://formsubmit.co/ajax/[email protected] on the client side, which is visible from the DevTools when the fetch request is made. I can't figure out how to do so in Next.js. Is there a way to do it?



Solution 1:[1]

While you can't hide the request made from the browser, you can use an API route to mask the URL of the external service.

Create an API route (let's say /api/form-submit) which calls https://formsubmit.co/ajax/[email protected], and will act as a proxy.

// /pages/api/form-submit
export default function handler(req, res) {
    if (req.method !== "POST") {
        res.setHeader('Allow', ["POST"])
        return res.status(405).end(`Method ${req.method} Not Allowed`)
    }

    try {
        const res = await fetch("https://formsubmit.co/ajax/[email protected]", {
            method: "POST",
            headers: req.headers, // Headers passed from the client-side
            body: req.body // Body passed from the client-side
        })
        const data = await res.json()
        res.status(200).json(data)
    } catch(e) {
        res.status(500).end(`An error occurred: ${e}`)
    }
}

Then from the client-side, make a request against the newly created API route instead.

const handleSubmit = async (e) => {
    e.preventDefault();
    await fetch("/api/form-submit", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Accept: "application/json"
            },
            body: JSON.stringify({
                name: "FormSubmit",
                message: "I'm from Devro LABS"
            })
        })
        .then((response) => response.json())
        .then((data) => console.log(data))
        .catch((error) => console.log(error));
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 juliomalves