50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
import axios, { type AxiosError, type AxiosInstance } from 'axios';
|
|
|
|
// SSR-safe guard for browser-only features
|
|
const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
|
|
function getCsrfTokenFromMeta(): string | null {
|
|
if (!isBrowser) return null;
|
|
const el = document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement | null;
|
|
return el?.content ?? null;
|
|
}
|
|
|
|
// Create a preconfigured Axios instance for the app
|
|
const http: AxiosInstance = axios.create({
|
|
baseURL: '/',
|
|
withCredentials: true, // include cookies for same-origin requests
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest',
|
|
Accept: 'application/json',
|
|
},
|
|
// If you use Laravel Sanctum's CSRF cookie, these defaults help automatically send it
|
|
xsrfCookieName: 'XSRF-TOKEN',
|
|
xsrfHeaderName: 'X-XSRF-TOKEN',
|
|
timeout: 30000,
|
|
});
|
|
|
|
// Attach CSRF token from Blade <meta name="csrf-token" ...> when present
|
|
http.interceptors.request.use((config) => {
|
|
const token = getCsrfTokenFromMeta();
|
|
if (token) {
|
|
// Laravel will accept either X-CSRF-TOKEN (meta) or X-XSRF-TOKEN (cookie)
|
|
config.headers = config.headers ?? {};
|
|
(config.headers as Record<string, string>)['X-CSRF-TOKEN'] = token;
|
|
}
|
|
return config;
|
|
});
|
|
|
|
// Basic error passthrough; customize as needed
|
|
http.interceptors.response.use(
|
|
(response) => response,
|
|
async (error: AxiosError) => {
|
|
// Example handling: if (error.response?.status === 401) { /* redirect to login */ }
|
|
// Example handling: if (error.response?.status === 419) { /* CSRF token mismatch */ }
|
|
return Promise.reject(error);
|
|
},
|
|
);
|
|
|
|
export { http };
|
|
export type { AxiosError, AxiosInstance };
|
|
export default http;
|