SyntaxStudy
Sign Up
Vue.js Beginner 1 min read

Using Axios in Vue 3

Axios is a popular HTTP client library that offers a cleaner API than `fetch` for common tasks: automatic JSON serialisation/deserialisation, request and response interceptors, timeout support, and built-in request cancellation via `CancelToken` or the newer `AbortController` integration. Install it with `npm install axios`. The recommended pattern is to create a shared Axios instance in `src/lib/axios.ts` configured with your API's `baseURL`, default headers, and global interceptors. The request interceptor is ideal for attaching the authentication bearer token from a Pinia store; the response interceptor can normalise error shapes or redirect to the login page on 401 responses. In Vue components, call your configured instance inside async actions or composables. Avoid placing Axios calls directly in component `setup` or `onMounted` for complex apps — push the HTTP logic into a Pinia store action or a composable so the component remains concerned only with display.
Example
// src/lib/axios.ts
import axios from 'axios';
import { useAuthStore } from '@/stores/auth';

const api = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL ?? 'https://api.example.com',
  timeout: 10_000,
  headers: { 'Content-Type': 'application/json' },
});

// Attach token on every request
api.interceptors.request.use((config) => {
  const auth = useAuthStore();
  if (auth.token) config.headers.Authorization = `Bearer ${auth.token}`;
  return config;
});

// Global error handler
api.interceptors.response.use(
  (res) => res,
  (err) => {
    if (err.response?.status === 401) {
      const auth = useAuthStore();
      auth.logout();
    }
    return Promise.reject(err);
  }
);

export default api;

// ── Component using the shared instance ───────
<script setup>
import { ref, onMounted } from 'vue';
import api from '@/lib/axios';

const post      = ref(null);
const isLoading = ref(false);

onMounted(async () => {
  isLoading.value = true;
  const { data }  = await api.get('/posts/1');
  post.value      = data;
  isLoading.value = false;
});
</script>