Getting Started with Axios in Nuxt

Learn how to integrate Axios into your Nuxt.js applications for seamless API communication and server-side data fetching

Building modern web applications requires efficient communication with backend APIs. Axios has become the de facto standard for making HTTP requests in JavaScript applications, and when combined with Nuxt.js, it provides a powerful solution for both client-side and server-side data fetching.

Unlike the native Fetch API, Axios offers a more feature-rich and consistent API across different JavaScript environments. It provides automatic data transformation, built-in request and response interceptors, and robust error handling out of the box. The dedicated Nuxt Axios module further simplifies integration by handling base URL management, proxy support, and automatic token injection for authenticated requests.

This guide covers everything you need to know to integrate Axios into your Nuxt project effectively, from initial installation to advanced patterns for authentication and error management. Whether you're building a simple content site or a complex web application, mastering Axios will help you create more efficient, maintainable, and user-friendly applications.

What Is Axios?

A promise-based HTTP client for browser and Node.js

Promise-Based Architecture

Clean async/await syntax for handling asynchronous requests with proper error handling and chainable operations

Automatic Data Transformation

Built-in JSON parsing and request/response data transformation without manual parsing

Request Interceptors

Modify requests globally before they are sent, perfect for adding auth tokens and logging

Response Interceptors

Handle responses globally for logging, error handling, or data normalization across all requests

Client-Side XSRF Protection

Built-in protection against cross-site request forgery attacks for secure form submissions

Request Cancellation

Cancel pending requests to prevent memory leaks and unnecessary processing on page transitions

Installing and Configuring Axios in Nuxt

For Nuxt 2

The official Nuxt Axios module provides seamless integration with your Nuxt 2 project. Install it using your preferred package manager:

npm install @nuxtjs/axios
# or
yarn add @nuxtjs/axios

Once installed, add the module to your nuxt.config.js file. The module handles automatic base URL configuration for both client-side and server-side requests, eliminating the need for separate URL handling logic:

modules: [
 '@nuxtjs/axios',
],

axios: {
 // Base URL for all API requests
 baseURL: 'https://api.example.com/',
 // Automatically retry failed requests
 retry: true,
 // Delay between retry attempts in milliseconds
 retryDelay: 1000,
 // Progress tracking for file uploads
 progress: true
}

For Nuxt 3

Nuxt 3 introduces a native $fetch API that handles HTTP requests without requiring external dependencies. This built-in approach provides similar functionality for most use cases and is the recommended approach for new Nuxt 3 projects:

// Using Nuxt 3's native useFetch composable
const { data } = await useFetch('https://api.example.com/users')

However, if you prefer Axios or need specific Axios features like interceptors, you can still install it manually in Nuxt 3:

npm install axios

According to the official Nuxt 3 documentation, the built-in $fetch API is designed to handle common HTTP request patterns while providing better tree-shaking and smaller bundle sizes.

Environment Variables

Managing different API endpoints across development, staging, and production environments is essential. Use environment variables to keep your configuration flexible and secure:

// nuxt.config.js
axios: {
 baseURL: process.env.API_URL || 'https://api.default.com/',
}

Create a .env file in your project root to store your API URLs:

API_URL=https://api.yourdomain.com/

This approach ensures your production API endpoint remains separate from development endpoints, preventing accidental data corruption and simplifying team collaboration.

Making HTTP Requests with Axios

GET Requests

GET requests are used to retrieve data from a server. In Nuxt, you can use the $axios instance injected by the module to fetch data both on the server and client side. The module provides convenient shortcut methods like $get that automatically parse the JSON response:

export default {
 async asyncData({ $axios }) {
 const users = await $axios.$get('/users')
 return { users }
 },
 methods: {
 async fetchUser(id) {
 const user = await this.$axios.get(`/users/${id}`)
 return user.data
 }
 }
}

The $get method is a convenience wrapper that returns just the response data, while the standard get method returns the full response object including status and headers.

POST Requests

POST requests send data to create new resources. Always implement proper error handling when creating resources to provide meaningful feedback to users and handle validation errors gracefully:

async createUser(userData) {
 try {
 const response = await this.$axios.$post('/users', userData)
 return response
 } catch (error) {
 console.error('Error creating user:', error.response?.data)
 throw error
 }
}

PUT and PATCH Requests

Understanding the difference between PUT and PATCH is important for building proper REST APIs. PUT replaces an entire resource with the data you provide, while PATCH performs partial updates, modifying only the fields you specify:

// PUT - Replace entire user resource
async updateUser(id, userData) {
 const response = await this.$axios.put(`/users/${id}`, userData)
 return response.data
}

// PATCH - Partial update, only changes provided fields
async patchUser(id, updates) {
 const response = await this.$axios.patch(`/users/${id}`, updates)
 return response.data
}

DELETE Requests

DELETE requests remove resources from the server. Unlike other methods, DELETE typically doesn't require a request body, though some APIs accept one for audit or cascading delete purposes:

async deleteUser(id) {
 await this.$axios.delete(`/users/${id}`)
 return true
}

As demonstrated in the Smashing Magazine tutorial on Axios Nuxt integration, implementing consistent request patterns across your application improves maintainability and makes error tracking easier.

Server-Side Data Fetching

Using asyncData

The asyncData method is one of Nuxt's most powerful features for server-side rendering. It runs on the server during initial page load and on the client during navigation, allowing you to fetch data before the page renders. This prevents the flash of loading content and improves both user experience and SEO:

export default {
 async asyncData({ $axios }) {
 const { data } = await $axios.get('https://api.example.com/posts')
 return {
 posts: data.posts
 }
 }
}

Key characteristics of asyncData include running on both server-side and client-side navigation, the ability to return data directly to the component, full access to Nuxt context including $axios, and preventing loading states by fetching data before page render. This makes it ideal for content-heavy pages where SEO and performance are priorities.

Using fetch

The fetch method offers a simpler alternative that works differently. While asyncData returns data directly, fetch stores the fetched data in the component's data property and provides access to the $fetchState object for tracking loading status:

export default {
 data() {
 return {
 posts: [],
 loading: false
 }
 },
 async fetch() {
 this.loading = true
 this.posts = await this.$axios.$get('https://api.example.com/posts')
 this.loading = false
 }
}

asyncData vs fetch Comparison

FeatureasyncDatafetch
Return data directlyYesNo
Data available on thisYesYes
Loading state trackingNoYes (via $fetchState)
Use in componentsNoYes
SSR + hydration optimizationOptimizedStandard
Prevents page flashYesPartial

As explained in the Smashing Magazine comprehensive guide, choose asyncData when you need data before the page renders and want to avoid loading states. Use fetch when you need more flexibility or want to use the method in reusable components.

Request Configuration and Interceptors

Common Configuration Options

Axios provides extensive configuration options for customizing your HTTP requests. Understanding these options helps you build robust API integrations that handle various edge cases:

await this.$axios.get('/users', {
 headers: {
 Authorization: `Bearer ${token}`,
 'Content-Type': 'application/json',
 'Custom-Header': 'value'
 },
 params: {
 page: 1,
 limit: 10,
 sort: 'createdAt',
 fields: ['id', 'name', 'email']
 },
 timeout: 5000,
 withCredentials: true
})

The params option automatically serializes objects and arrays to URL parameters. For example, passing { ids: [1, 2], type: 'admin' } becomes /users?ids[]=1&ids[]=2&type=admin, handling all URL encoding automatically.

Request Interceptors

Request interceptors allow you to modify requests globally before they are sent. This is essential for adding authentication tokens, logging requests in development, or modifying headers based on application state. Create a plugin file to register your interceptors:

// plugins/axios.js
export default function ({ $axios, store }) {
 $axios.onRequest((config) => {
 if (store.state.auth.token) {
 config.headers.Authorization = `Bearer ${store.state.auth.token}`
 }
 if (process.env.NODE_ENV === 'development') {
 console.log('Making request to:', config.url)
 }
 return config
 })
}

Response Interceptors

Response interceptors enable global handling of responses before they reach your components. Use them for logging, error handling, or data transformation:

export default function ({ $axios }) {
 $axios.onResponse((response) => {
 if (process.env.NODE_ENV === 'development') {
 console.log('Response from:', response.config.url, response.data)
 }
 return response
 })
}

According to the official Axios documentation, interceptors are one of the most powerful features for maintaining consistent API behavior across large applications.

Response Handling and Error Management

Response Schema

Understanding the Axios response structure is crucial for proper data handling. Every Axios response contains several properties beyond just the data payload:

{
 // Server response data (parsed automatically)
 data: { users: [...], total: 100 },
 // HTTP status code
 status: 200,
 // Status text from server
 statusText: 'OK',
 // Response headers (lowercase keys)
 headers: { 'content-type': 'application/json' },
 // Axios request configuration
 config: { method: 'get', url: '/users' },
 // XMLHttpRequest instance
 request: XMLHttpRequest { ... }
}

Error Handling

Robust error handling distinguishes professional applications from hobby projects. Axios errors have a specific structure that helps you determine the appropriate response:

async fetchData() {
 try {
 const response = await this.$axios.get('/data')
 return response.data
 } catch (error) {
 if (error.response) {
 // Server responded with error status (4xx, 5xx)
 console.error('Server error:', error.response.status)
 console.error('Error data:', error.response.data)
 } else if (error.request) {
 // Request made but no response received (network issue)
 console.error('No response received - check network connection')
 } else {
 // Error setting up the request
 console.error('Request error:', error.message)
 }
 // Optionally rethrow for upstream handling
 throw error
 }
}

Global Error Handler

Centralize error handling with a global interceptor that redirects users on authentication failures or shows notifications for server errors. This keeps your components clean and ensures consistent error behavior:

// plugins/axios-error-handler.js
export default function ({ $axios, app }) {
 $axios.onError((error) => {
 const code = parseInt(error.response?.status)
 if (code === 401) {
 app.$toast.error('Please log in to continue')
 navigateTo('/login')
 } else if (code === 403) {
 app.$toast.error('You do not have permission')
 } else if (code >= 500) {
 app.$toast.error('Server error - please try again later')
 }
 return Promise.reject(error)
 })
}

Implementing comprehensive error handling as demonstrated in the Smashing Magazine Axios Nuxt tutorial ensures your application provides a smooth user experience even when things go wrong.

Authentication and Token Management

Setting Authentication Tokens

Secure authentication requires consistent token management across all API requests. The Nuxt Axios module provides multiple approaches, from simple token setting to sophisticated interceptor-based injection:

// Simple approach - set token globally
$axios.setToken(token)

// Interceptor approach - automatic token inclusion
$axios.onRequest((config) => {
 const token = localStorage.getItem('auth_token')
 if (token) {
 config.headers.Authorization = `Bearer ${token}`
 }
 return config
})

The interceptor approach is preferred for applications that refresh tokens periodically, as it allows you to always use the current valid token.

Using with Auth Modules

For Nuxt 2 projects, the @nuxtjs/auth-next module integrates seamlessly with Axios, handling authentication state, route protection, and token refresh automatically:

// nuxt.config.js
modules: [
 '@nuxtjs/axios',
 '@nuxtjs/auth-next'
],

auth: {
 strategies: {
 local: {
 endpoints: {
 login: { url: '/auth/login', method: 'post' },
 user: { url: '/auth/user', method: 'get' },
 logout: { url: '/auth/logout', method: 'post' }
 },
 tokenType: 'Bearer',
 tokenName: 'Authorization'
 }
 },
 redirect: {
 login: '/login',
 logout: '/',
 callback: '/auth/callback'
 }
}

For complex web applications requiring secure authentication, integrating both Axios and an auth module provides the most robust solution with minimal boilerplate code.

Security Best Practices

Never expose sensitive tokens in client-side code. Store tokens in secure, HTTP-only cookies when possible, or use memory-only storage that clears on page refresh. Always validate responses on the server side, and implement proper CORS policies on your API to prevent unauthorized access.

Best Practices

Organization and Maintainability

As your application grows, maintaining a consistent API layer becomes critical. Create a dedicated service layer that encapsulates all API interactions, keeping components focused on presentation logic:

// services/api.js
export const api = {
 users: {
 list: (params) => $axios.$get('/users', { params }),
 get: (id) => $axios.$get(`/users/${id}`),
 create: (data) => $axios.$post('/users', data),
 update: (id, data) => $axios.$put(`/users/${id}`, data),
 delete: (id) => $axios.delete(`/users/${id}`)
 },
 posts: {
 list: (params) => $axios.$get('/posts', { params }),
 get: (id) => $axios.$get(`/posts/${id}`)
 }
}

This approach centralizes API endpoints, making it easy to update base URLs or add request defaults without modifying multiple components.

Performance Considerations

Server-side data fetching through asyncData reduces client-side work and improves initial page load times, which is particularly important for SEO optimization. Implement request cancellation when navigating away from pages to prevent memory leaks and unnecessary network activity:

const CancelToken = $axios.CancelToken
let cancelSource

async loadData() {
 if (cancelSource) cancelSource.cancel()
 cancelSource = CancelToken.source()
 
 this.data = await this.$axios.$get('/data', {
 cancelToken: cancelSource.token
 })
}

beforeDestroy() {
 if (cancelSource) cancelSource.cancel('Component destroyed')
}

Security Best Practices

  • Use HTTPS for all API communications in production
  • Store tokens securely, preferring HTTP-only cookies over localStorage
  • Implement proper CORS policies on your API server
  • Validate and sanitize all response data before using it
  • Use request timeouts to prevent hanging requests
  • Log suspicious activity without exposing sensitive information

Following the patterns recommended in the official Axios documentation ensures your application handles HTTP requests securely and efficiently.

Summary

Axios provides a robust solution for handling HTTP requests in Nuxt applications. Whether you're building a simple content site or a complex web application, understanding how to effectively use Axios with Nuxt will help you create more efficient, maintainable, and user-friendly applications.

The Nuxt Axios module simplifies integration by handling base URL management, automatic retry logic, and seamless integration with Nuxt's server-side rendering capabilities. By using asyncData for SSR-friendly data fetching, implementing proper error handling with global interceptors, and following security best practices for authentication tokens, you can build professional-grade applications that perform well and provide excellent user experiences.

Key Takeaways

  • Axios offers a consistent, feature-rich API for HTTP requests with convenient shortcut methods
  • The Nuxt Axios module simplifies integration and provides automatic base URL handling for both client and server
  • Use asyncData for server-side data fetching to optimize SSR and avoid loading states
  • Implement proper error handling with try/catch blocks and global interceptors for consistent error management
  • Follow security best practices when handling authentication tokens and sensitive data
  • For Nuxt 3 projects, consider the native $fetch API for simpler use cases while Axios remains valuable for complex scenarios

Next Steps

Now that you understand the fundamentals of using Axios in Nuxt, consider exploring these related topics to deepen your knowledge:

  • Practice by building a complete feature that connects to a real REST API
  • Explore advanced interceptor patterns for request/response transformation
  • Learn about lazy loading techniques to optimize application performance
  • Discover how server actions provide alternative approaches to server-side operations
  • Implement proper error handling in your Next.js middleware for comprehensive request management

Frequently Asked Questions

Need Help Building Your Nuxt Application?

Our team of experienced developers can help you implement efficient API integrations, server-side rendering, and best practices for your Nuxt.js project.