My Nextjs 13 frontend (app router) interacts with a Laravel-powered backend through an api. To handle authentication in the api, I am utilizing Laravel Sanctum as suggested by Laravel for SPAs. This involves setting two cookies (a session and a CSRF token) after login, which must be included in all future requests along with a X-Xsrf-Token header that carries the CSRF token.
To make a request from a client component, I can use the following code:
import cookies from 'js-cookie'
fetch( [url], {
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Origin": [origin],
"X-Requested-With": "XMLHttpRequest",
"X-Xsrf-Token": cookies.get( "XSRF-TOKEN" ),
// Cookies are automatically attached via the 'Cookie' header on browser
},
credentials: 'include'
})
If I need to send a request from a server component, I can do:
import { cookies, headers } from "next/headers"
fetch( [url], {
headers: {
"Cookie": cookies().toString(),
"Referer": headers().get( "referer" ) ?? "",
"X-Xsrf-Token": cookies().get( "XSRF-TOKEN" ).value,
},
})
While both methods work, sometimes I need to send the same request from both server and client components. In such cases, I want to create a single fetcher like this:
import cookies from 'js-cookie'
import { cookies, headers } from "next/headers"
fetch( [url],
isServer
?
{
headers: {
"Cookie": cookies().toString(),
"Referer": headers().get( "referer" ) ?? "",
"X-Xsrf-Token": cookies().get( "XSRF-TOKEN" ).value,
}
}
:
{
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Origin": process.env.NEXT_PUBLIC_APP_URL,
"X-Requested-With": "XMLHttpRequest",
"X-Xsrf-Token": cookies.get( "XSRF-TOKEN" ),
},
credentials: 'include'
}
)
However, this setup causes errors in client components due to restrictions on using cookies() and headers() functions outside of server components. So, my question is how can I create a universal fetcher that functions seamlessly on both server and client components?