export type CsrfFetchOptions = RequestInit & { headers?: Record }; function getMetaToken(): string | null { const el = document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement | null; return el?.content || null; } /** * fetch wrapper that automatically adds CSRF and common headers, and sends cookies. * - Uses local proxy to avoid Mixed Content (HTTPS -> HTTP) and CORS issues. * - Adds X-CSRF-TOKEN from if present * - Adds X-Requested-With: XMLHttpRequest for Laravel */ export async function csrfFetch(input: RequestInfo | URL, options: CsrfFetchOptions = {}): Promise { const token = getMetaToken(); const headers: Record = { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json', ...(options.headers || {}), }; if (token && !('X-CSRF-TOKEN' in headers)) { headers['X-CSRF-TOKEN'] = token; } const init: RequestInit = { ...options, headers, credentials: options.credentials ?? 'same-origin', }; return fetch(input, init); }