51 lines
1.6 KiB
TypeScript
51 lines
1.6 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 type { AxiosError, AxiosInstance }
|
|
export { http }
|
|
export default http
|
|
|