Passing Custom Metadata in Axios Request Config
Passing custom metadata through the Axios HTTP client allows developers to attach contextual information—such as request start times, tracking IDs, or retry counts—directly to an individual request. This article explains how Axios handles custom properties within its request configuration object, how to access that metadata inside request and response interceptors, and how to properly type custom configuration fields using TypeScript.
How the Metadata Mechanism Works
Axios creates an internal configuration object for every HTTP
request. Any custom properties added to the configuration object during
a request call are preserved throughout the entire lifecycle of that
request. When a response is received, Axios attaches the original
configuration object to response.config.
Because the configuration object persists from dispatch to response, it serves as the primary transport mechanism for passing state and metadata across interceptors.
Attaching Metadata to a Request
To pass custom metadata, add custom properties directly to the config object when executing a request:
import axios from 'axios';
axios.get('https://api.example.com/data', {
metadata: {
startTime: Date.now(),
requestId: 'req-12345',
skipAuth: false
}
});You can also assign custom properties to an Axios instance default configuration or inside a request interceptor.
Accessing Metadata in Interceptors
Interceptors allow you to read, modify, and act on the metadata before the request is sent or after the response arrives.
Measuring Request Latency (Example)
A common use case is measuring network latency by setting a timestamp before dispatch and calculating the delta upon response:
import axios from 'axios';
const apiClient = axios.create();
// Request Interceptor: Record start time
apiClient.interceptors.request.use((config) => {
config.metadata = { startTime: new Date().getTime() };
return config;
}, (error) => {
return Promise.reject(error);
});
// Response Interceptor: Calculate duration
apiClient.interceptors.response.use((response) => {
const startTime = response.config.metadata?.startTime;
if (startTime) {
const duration = new Date().getTime() - startTime;
console.log(`Request to ${response.config.url} took ${duration} ms`);
}
return response;
}, (error) => {
if (error.config?.metadata?.startTime) {
const duration = new Date().getTime() - error.config.metadata.startTime;
console.error(`Failed request took ${duration} ms`);
}
return Promise.reject(error);
});TypeScript Module Augmentation
In TypeScript, adding unknown properties to
AxiosRequestConfig can trigger type errors. To support
custom metadata with full type safety, use module augmentation to extend
the Axios interface:
import axios from 'axios';
declare module 'axios' {
export interface AxiosRequestConfig {
metadata?: {
startTime?: number;
requestId?: string;
retryCount?: number;
};
}
export interface InternalAxiosRequestConfig {
metadata?: {
startTime?: number;
requestId?: string;
retryCount?: number;
};
}
}By extending both AxiosRequestConfig (for initial
requests) and InternalAxiosRequestConfig (used inside
modern Axios interceptors), your custom metadata properties become fully
typed across your application.