How to use fetch in laravel?

In Laravel, you cannot simply use "fetch" and then request the API; otherwise, you will encounter an error due to the CSRF middleware.

const handleClickSend = async () => {
  try {
    const response = await fetch("/post", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${ApiKeyHelper.getKey()}`,
      },
      body: JSON.stringify({
        title: "Sample",
        body: "Contents"
      }),
    });

    if (!response.ok) {
      console.error(`Error: ${response.statusText}`);
      return;
    }

    const data = await response.json();
    console.log(data);
  } catch (e) {
    console.error(e);
  }
};

This code will not work. It will give you 419 error expired.

How to fix it?

So to fix this issue we can just put csrf token into the header request.

First add csrf token into the meta header element of html in blade.

<meta name="csrf-token" content="{{{ csrf_token() }}}">

Then get the csrf token value.

const metaElements = document.querySelectorAll('meta[name="csrf-token"]');
const csrf = metaElements.length > 0 ? metaElements[0].content : "";

Now we can just put the csrf token into the header.

headers: {
    ...
    "X-CSRF-Token": csrf
}

And just like that your problem is solved.

Here's the full fetch code.

const metaElements = document.querySelectorAll('meta[name="csrf-token"]');
const csrf = metaElements.length > 0 ? metaElements[0].content : "";

const handleClickSend = async () => {
  try {
    const response = await fetch("/post", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${ApiKeyHelper.getKey()}`,
        "X-CSRF-Token": csrf
      },
      body: JSON.stringify({
        title: "Sample",
        body: "Contents"
      }),
    });

    if (!response.ok) {
      console.error(`Error: ${response.statusText}`);
      return;
    }

    const data = await response.json();
    console.log(data);
  } catch (e) {
    console.error(e);
  }
};