BLOG POSTS
Using Axios in Vanilla JS: A Beginner’s Guide

Using Axios in Vanilla JS: A Beginner’s Guide

Axios is a promise-based HTTP client library that makes API requests cleaner and more manageable than the traditional XMLHttpRequest or even the newer fetch API. While many developers associate Axios with React or Node.js environments, it works perfectly in vanilla JavaScript projects, offering automatic JSON data transformation, request/response interceptors, and better error handling out of the box. This guide will walk you through integrating Axios into your vanilla JS projects, covering everything from basic GET requests to advanced interceptor configurations and real-world troubleshooting scenarios.

How Axios Works in Vanilla JavaScript

Axios operates as a wrapper around XMLHttpRequest in browsers, providing a promise-based interface that simplifies HTTP operations. Unlike fetch(), Axios automatically handles JSON parsing, throws errors for HTTP error status codes, and provides more intuitive request/response transformation options.

The library can be included in vanilla JavaScript projects through a CDN link or by downloading the standalone file. Once loaded, Axios exposes a global object with methods corresponding to HTTP verbs (GET, POST, PUT, DELETE, etc.), plus configuration options for headers, timeouts, and interceptors.

Feature Axios Fetch API XMLHttpRequest
JSON Handling Automatic Manual (.json()) Manual (JSON.parse)
Error Handling Throws on 4xx/5xx Only network errors Manual status checking
Request Timeout Built-in Requires AbortController Built-in
Interceptors Yes No No
Browser Support IE11+ Modern browsers All browsers

Step-by-Step Implementation Guide

Getting started with Axios in vanilla JavaScript requires minimal setup. Here’s how to integrate it into your project:

Installation and Basic Setup

Add Axios to your HTML file via CDN:

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

Or download and host it locally:

<script src="./js/axios.min.js"></script>

Basic GET Request

Start with a simple GET request to fetch data from an API:

// Basic GET request
axios.get('https://jsonplaceholder.typicode.com/posts/1')
  .then(response => {
    console.log('Data:', response.data);
    console.log('Status:', response.status);
    console.log('Headers:', response.headers);
  })
  .catch(error => {
    console.error('Error:', error.message);
  });

POST Request with Data

Sending data to an API endpoint:

const postData = {
  title: 'New Post',
  body: 'This is the post content',
  userId: 1
};

axios.post('https://jsonplaceholder.typicode.com/posts', postData)
  .then(response => {
    console.log('Created:', response.data);
    document.getElementById('result').innerHTML = 
      `<p>Post created with ID: ${response.data.id}</p>`;
  })
  .catch(error => {
    console.error('Failed to create post:', error);
  });

Advanced Configuration

Create an Axios instance with custom configuration:

const apiClient = axios.create({
  baseURL: 'https://api.example.com/v1',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your-token-here'
  }
});

// Use the configured instance
apiClient.get('/users')
  .then(response => {
    displayUsers(response.data);
  })
  .catch(handleApiError);

Real-World Examples and Use Cases

Dynamic Content Loading

A common use case is loading content dynamically without page refresh:

class ContentLoader {
  constructor(baseUrl) {
    this.api = axios.create({
      baseURL: baseUrl,
      timeout: 5000
    });
  }

  async loadArticle(articleId) {
    try {
      const response = await this.api.get(`/articles/${articleId}`);
      this.renderArticle(response.data);
    } catch (error) {
      this.showError('Failed to load article');
    }
  }

  renderArticle(article) {
    document.getElementById('article-content').innerHTML = `
      <h1>${article.title}</h1>
      <p>${article.content}</p>
      <small>Published: ${article.publishedAt}</small>
    `;
  }

  showError(message) {
    document.getElementById('error-message').style.display = 'block';
    document.getElementById('error-message').textContent = message;
  }
}

Form Submission with Validation

Handle form submissions with proper error handling and user feedback:

document.getElementById('contact-form').addEventListener('submit', async (e) => {
  e.preventDefault();
  
  const formData = new FormData(e.target);
  const data = Object.fromEntries(formData.entries());
  
  // Show loading state
  const submitBtn = document.getElementById('submit-btn');
  submitBtn.disabled = true;
  submitBtn.textContent = 'Sending...';
  
  try {
    const response = await axios.post('/api/contact', data, {
      headers: {
        'Content-Type': 'application/json'
      }
    });
    
    showSuccessMessage('Message sent successfully!');
    e.target.reset();
  } catch (error) {
    if (error.response && error.response.status === 422) {
      showValidationErrors(error.response.data.errors);
    } else {
      showErrorMessage('Failed to send message. Please try again.');
    }
  } finally {
    submitBtn.disabled = false;
    submitBtn.textContent = 'Send Message';
  }
});

Using Interceptors for Global Handling

Interceptors are powerful features that allow you to handle requests and responses globally:

// Request interceptor - add auth token to all requests
axios.interceptors.request.use(
  config => {
    const token = localStorage.getItem('authToken');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => Promise.reject(error)
);

// Response interceptor - handle common errors
axios.interceptors.response.use(
  response => response,
  error => {
    if (error.response?.status === 401) {
      // Redirect to login page
      window.location.href = '/login';
    } else if (error.response?.status === 500) {
      showGlobalError('Server error. Please try again later.');
    }
    return Promise.reject(error);
  }
);

Best Practices and Common Pitfalls

Best Practices

  • Use async/await for cleaner code instead of chaining .then() calls
  • Set appropriate timeouts to prevent hanging requests
  • Implement proper error handling for different HTTP status codes
  • Use interceptors for cross-cutting concerns like authentication
  • Create configured instances rather than using the global axios object
  • Validate data before sending requests to reduce server errors

Common Pitfalls and Solutions

CORS Issues: When making requests to different domains, ensure the server includes proper CORS headers. You cannot fix CORS issues from the client side:

// This won't work for CORS issues
axios.get('https://external-api.com/data', {
  headers: {
    'Access-Control-Allow-Origin': '*' // Don't do this
  }
});

Memory Leaks with Interceptors: Always remove interceptors when they’re no longer needed:

// Store the interceptor ID
const requestInterceptor = axios.interceptors.request.use(config => config);

// Remove it later
axios.interceptors.request.eject(requestInterceptor);

Handling Network Errors: Distinguish between network errors and HTTP errors:

axios.get('/api/data')
  .catch(error => {
    if (error.response) {
      // Server responded with error status
      console.log('Server Error:', error.response.status);
    } else if (error.request) {
      // Request made but no response received
      console.log('Network Error:', error.request);
    } else {
      // Something else happened
      console.log('Error:', error.message);
    }
  });

Performance Considerations

Axios adds approximately 40KB to your bundle size (minified), which is reasonable for the features it provides. However, consider these optimizations:

  • Request Cancellation: Use AbortController for cancelling requests when components unmount or when new requests supersede old ones
  • Response Caching: Implement caching for frequently requested data to reduce server load
  • Connection Pooling: Axios automatically reuses connections, but be mindful of concurrent request limits
// Request cancellation example
const source = axios.CancelToken.source();

axios.get('/api/search', {
  cancelToken: source.token,
  params: { q: searchQuery }
}).catch(thrown => {
  if (axios.isCancel(thrown)) {
    console.log('Request cancelled');
  }
});

// Cancel the request if needed
if (newSearchQuery !== searchQuery) {
  source.cancel('Operation cancelled by user');
}

Troubleshooting Common Issues

Request Timeout Errors: Increase timeout values for slow APIs or implement retry logic:

const axiosRetry = async (url, options = {}, retries = 3) => {
  try {
    return await axios.get(url, { timeout: 5000, ...options });
  } catch (error) {
    if (retries > 0 && error.code === 'ECONNABORTED') {
      console.log(`Retrying... ${retries} attempts left`);
      return axiosRetry(url, options, retries - 1);
    }
    throw error;
  }
};

Content-Type Issues: Ensure you’re sending the correct Content-Type header:

// For form data
const formData = new FormData();
formData.append('file', fileInput.files[0]);

axios.post('/upload', formData, {
  headers: {
    'Content-Type': 'multipart/form-data'
  }
});

// For URL-encoded data
const params = new URLSearchParams();
params.append('key', 'value');

axios.post('/api/form', params, {
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
});

For comprehensive documentation and advanced usage patterns, check the official Axios documentation. The library’s GitHub repository also contains extensive examples and troubleshooting guides for complex scenarios.



This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.

This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.

Leave a reply

Your email address will not be published. Required fields are marked