Configure Custom Path Parameters in Axios
By default, the Axios HTTP client natively serializes the
params object into URL query parameters rather than
dynamically substituting path parameters in the request URL. This guide
demonstrates how to implement a clean, automated path parameter
replacement mechanism in Axios using request interceptors. By
configuring this logic, you can define URLs with placeholders such as
/users/:id or /posts/{postId} and have them
resolved automatically at runtime.
Understanding the Problem
Axios maps the params configuration directly to the
query string:
// Default behavior
axios.get('/users/:id', { params: { id: 42 } });
// Resulting URL: /users/:id?id=42 (Not /users/42)To resolve placeholders in the path, you must intercept the request configuration before it is dispatched and replace tokens matching your chosen naming convention.
Step 1: Create a Request Interceptor
Using an Axios request interceptor is the most efficient way to achieve custom path substitution globally or on a specific Axios instance.
Here is the implementation supporting both :param and
{param} syntax:
import axios from 'axios';
// Create an Axios instance
const apiClient = axios.create({
baseURL: 'https://api.example.com',
});
// Add the path parameter replacement interceptor
apiClient.interceptors.request.use((config) => {
if (!config.url || !config.pathParams) {
return config;
}
let url = config.url;
const pathParams = config.pathParams;
// Replace :paramName or {paramName} placeholders
Object.entries(pathParams).forEach(([key, value]) => {
const encodedValue = encodeURIComponent(String(value));
const colonPattern = new RegExp(`:${key}(?=[/?#]|$)`, 'g');
const bracePattern = new RegExp(`\\{${key}\\}`, 'g');
url = url.replace(colonPattern, encodedValue).replace(bracePattern, encodedValue);
});
config.url = url;
return config;
});
export default apiClient;Step 2: Making Requests with Path Parameters
With the interceptor configured, supply the pathParams
property inside the request configuration object:
import apiClient from './apiClient';
// Example using colon syntax
apiClient.get('/users/:userId/posts/:postId', {
pathParams: {
userId: 123,
postId: 456,
},
params: {
includeComments: true, // Still works for query parameters
},
});
// Dispatched URL: https://api.example.com/users/123/posts/456?includeComments=true
// Example using curly brace syntax
apiClient.delete('/organizations/{orgId}/members/{memberId}', {
pathParams: {
orgId: 'acme-corp',
memberId: 99,
},
});
// Dispatched URL: https://api.example.com/organizations/acme-corp/members/99Step 3: TypeScript Support (Optional)
If you are using TypeScript, extend the
AxiosRequestConfig interface via module augmentation to
ensure type safety for the pathParams field:
import axios from 'axios';
declare module 'axios' {
export interface AxiosRequestConfig {
pathParams?: Record<string, string | number | boolean>;
}
}Key Considerations
- URL Encoding: Always pass values through
encodeURIComponentto avoid breaking the URL structure when values contain special characters or spaces. - Separation of Concerns: Keep path parameters in a
dedicated
pathParamsobject rather than overloadingparamsto avoid unintended query string generation. - Unmatched Placeholders: If required, add a
validation check inside the interceptor to throw an error if any
unreplaced
:paramor{param}tokens remain inconfig.urlafter processing.