How to Integrate Axios with Vue.js

Connecting Vue.js with the Axios HTTP client is the industry standard for fetching and mutating API data. This article outlines the recommended approach to integrating Axios into a modern Vue 3 application, covering installation, setting up a centralized Axios instance, managing request and response interceptors, and consuming API endpoints cleanly using the Composition API.

Step 1: Install Axios

Install Axios into your Vue project using your preferred package manager:

npm install axios
# or
yarn add axios
# or
pnpm add axios

Step 2: Create a Centralized Axios Instance

The best practice is to avoid importing Axios directly into individual components with hardcoded URLs. Instead, create a dedicated HTTP service file (e.g., src/services/api.js or src/plugins/axios.js) to configure a base URL, default headers, and timeouts.

// src/services/api.js
import axios from 'axios';

const apiClient = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || 'https://api.example.com/v1',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
    Accept: 'application/json',
  },
});

export default apiClient;

Step 3: Configure Request and Response Interceptors

Interceptors allow you to inject authentication tokens before a request leaves the browser and handle common errors (like 401 Unauthorized or 500 Internal Server Error) globally.

// src/services/api.js (continued)

// Attach Authorization token to every outgoing request
apiClient.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem('auth_token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => Promise.reject(error)
);

// Handle global responses and errors
apiClient.interceptors.response.use(
  (response) => response,
  (error) => {
    if (error.response && error.response.status === 401) {
      // Handle logout or token refresh logic
    }
    return Promise.reject(error);
  }
);

Step 4: Define API Endpoints in Service Modules

Organize endpoint calls into modular service files rather than writing raw Axios calls inside components.

// src/services/userService.js
import apiClient from './api';

export default {
  getUsers() {
    return apiClient.get('/users');
  },
  getUserById(id) {
    return apiClient.get(`/users/${id}`);
  },
  createUser(data) {
    return apiClient.post('/users', data);
  },
};

Step 5: Consume the API in Vue Components

Use the standard Composition API syntax to call the service inside your components during lifecycle events or user actions.

<script setup>
import { ref, onMounted } from 'vue';
import userService from '@/services/userService';

const users = ref([]);
const loading = ref(false);
const error = ref(null);

const fetchUsers = async () => {
  loading.value = true;
  error.value = null;
  try {
    const response = await userService.getUsers();
    users.value = response.data;
  } catch (err) {
    error.value = err.message || 'Failed to load users';
  } finally {
    loading.value = false;
  }
};

onMounted(() => {
  fetchUsers();
});
</script>

<template>
  <div>
    <p v-if="loading">Loading data...</p>
    <p v-else-if="error">{{ error }}</p>
    <ul v-else>
      <li v-for="user in users" :key="user.id">{{ user.name }}</li>
    </ul>
  </div>
</template>

Summary

The standard approach to integrating Axios into Vue.js relies on:

  1. Creating a single Axios instance with custom configuration.
  2. Managing authentication tokens and global errors via interceptors.
  3. Encapsulating API requests into dedicated service modules.
  4. Calling those service methods within Vue components using the Composition API.