Send URL Encoded Data in Axios

Sending application/x-www-form-urlencoded request payloads is a standard requirement when communicating with traditional HTML form endpoints and OAuth2 authentication servers. In modern versions of the Axios HTTP client (v1.x and late v0.x), sending form-encoded data can be done natively without extra libraries using URLSearchParams or plain JavaScript objects with appropriate headers, as well as with third-party serializers like qs for complex data structures.


The most robust and universally supported method in modern environments (both Node.js and modern browsers) is the standard URLSearchParams interface. When a URLSearchParams object is passed as the request body, Axios automatically sets the Content-Type header to application/x-www-form-urlencoded;charset=utf-8.

import axios from 'axios';

const params = new URLSearchParams();
params.append('username', 'johndoe');
params.append('password', 'secret_token');
params.append('grant_type', 'password');

axios.post('https://api.example.com/oauth/token', params)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error(error);
  });

Alternatively, you can initialize URLSearchParams directly with a key-value object:

const params = new URLSearchParams({
  username: 'johndoe',
  password: 'secret_token',
  grant_type: 'password'
});

await axios.post('https://api.example.com/oauth/token', params);

Method 2: Plain Objects with Axios Automatic Serialization (v1.x+)

Modern Axios (v1.0.0 and newer) includes an internal form serializer. If you supply a plain JavaScript object and explicitly specify the application/x-www-form-urlencoded header, Axios will automatically serialize the payload for you.

import axios from 'axios';

const payload = {
  username: 'johndoe',
  password: 'secret_token'
};

axios.post('https://api.example.com/login', payload, {
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
})
.then(response => console.log(response.data))
.catch(error => console.error(error));

Method 3: Using the qs Library (for Nested Objects)

URLSearchParams only supports flat key-value pairs. If your API expects nested objects or arrays encoded into form data, use the qs serialization library.

npm install qs
import axios from 'axios';
import qs from 'qs';

const data = {
  user: {
    name: 'John Doe',
    roles: ['admin', 'editor']
  },
  active: true
};

axios.post('https://api.example.com/users', qs.stringify(data), {
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
})
.then(response => console.log(response.data))
.catch(error => console.error(error));

Method 4: Configuring Global or Instance Defaults

If an entire Axios instance communicates with a backend expecting form-encoded data, set the formSerializer config or use transformRequest:

import axios from 'axios';
import qs from 'qs';

const apiClient = axios.create({
  baseURL: 'https://api.example.com',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  transformRequest: [(data) => qs.stringify(data)]
});

// Automatically serialized as application/x-www-form-urlencoded
apiClient.post('/submit', { field1: 'value1', field2: 'value2' });