NeuroAgent

Complete Guide: JavaScript Query String Parameters

Learn the native JavaScript method to extract URL parameters using URLSearchParams API. Complete guide with examples and browser compatibility notes.

Question

How can I retrieve query string parameters in JavaScript without using plugins?

What is the native JavaScript method to extract URL parameters from the query string? If no native solution exists, what jQuery plugin or alternative JavaScript approach can be used to parse query string values?

NeuroAgent

The native JavaScript method to extract URL query string parameters is the URLSearchParams API, which was introduced in ES2017 and provides a clean, built-in way to parse query strings without requiring any external libraries. You can access query parameters using new URLSearchParams(window.location.search) and then use methods like get(), getAll(), has(), and entries() to retrieve the values. For older browsers that don’t support URLSearchParams, you can implement a manual parsing function using regular expressions or string manipulation methods.

Contents


Understanding Query Strings

A query string is the part of a URL that contains data passed to web applications. It typically appears after the ? character in a URL and consists of key-value pairs separated by & symbols. For example:

https://example.com/page?name=John&age=30&city=New%20York

In this URL:

  • name=John is a parameter with key “name” and value “John”
  • age=30 is a parameter with key “age” and value “30”
  • city=New%20York is a parameter with key “city” and value “New York” (URL-encoded)

Modern web applications often need to extract these parameters to:

  • Pre-populate forms with user-provided data
  • Implement search functionality
  • Track user behavior and analytics
  • Maintain application state across page reloads

Native URLSearchParams API

The URLSearchParams interface is the most elegant and recommended native solution for working with query strings in modern JavaScript.

Basic Usage

javascript
// Get the current page's query string
const queryString = window.location.search;
// Example: "?name=John&age=30&city=New%20York"

// Create a URLSearchParams object
const urlParams = new URLSearchParams(queryString);

// Get individual parameters
const name = urlParams.get('name'); // "John"
const age = urlParams.get('age');   // "30"
const city = urlParams.get('city'); // "New York"

Key Methods

The URLSearchParams API provides several useful methods:

  • get(name): Returns the first value associated with the given search parameter
  • getAll(name): Returns all values associated with a given search parameter (for multiple values with the same key)
  • has(name): Returns a Boolean indicating if a parameter exists
  • set(name, value): Sets the value for a parameter
  • append(name, value): Appends a new value to an existing parameter
  • delete(name): Deletes a parameter
  • toString(): Returns the query string
  • entries(): Returns an iterator of all key-value pairs
  • keys(): Returns an iterator of all keys
  • values(): Returns an iterator of all values

Working with Multiple Values

javascript
// URL: ?tags=javascript&tags=web&tags=development
const urlParams = new URLSearchParams(window.location.search);

const tags = urlParams.getAll('tags');
// ["javascript", "web", "development"]

// Iterate through all parameters
for (const [key, value] of urlParams.entries()) {
  console.log(`${key}: ${value}`);
}

Browser Compatibility

The URLSearchParams API is widely supported in modern browsers:

  • Chrome: 49+ (2016)
  • Firefox: 29+ (2014)
  • Safari: 10.1+ (2017)
  • Edge: 17+ (2018)
  • Node.js: 10+ (2018)

For older browsers or environments that don’t support URLSearchParams, you’ll need alternative approaches.


Alternative Native Approaches

Manual Parsing with Regular Expressions

javascript
function getQueryParams(url = window.location.search) {
  const params = {};
  const queryString = url.split('?')[1] || '';
  
  queryString.split('&').forEach(param => {
    const [key, value] = param.split('=');
    if (key) {
      // Decode URI components
      const decodedKey = decodeURIComponent(key);
      const decodedValue = value ? decodeURIComponent(value) : '';
      
      // Handle multiple values with the same key
      if (params[decodedKey]) {
        if (Array.isArray(params[decodedKey])) {
          params[decodedKey].push(decodedValue);
        } else {
          params[decodedKey] = [params[decodedKey], decodedValue];
        }
      } else {
        params[decodedKey] = decodedValue;
      }
    }
  });
  
  return params;
}

// Usage
const params = getQueryParams();
const name = params.name; // "John"

String Manipulation Approach

javascript
function parseQueryString() {
  const queryString = window.location.search.substring(1);
  const params = {};
  
  if (queryString) {
    const pairs = queryString.split('&');
    
    for (let i = 0; i < pairs.length; i++) {
      const pair = pairs[i].split('=');
      const key = decodeURIComponent(pair[0]);
      const value = pair.length > 1 ? decodeURIComponent(pair[1]) : '';
      
      if (params[key]) {
        if (Array.isArray(params[key])) {
          params[key].push(value);
        } else {
          params[key] = [params[key], value];
        }
      } else {
        params[key] = value;
      }
    }
  }
  
  return params;
}

Polyfill for URLSearchParams

For older browsers, you can include a polyfill:

javascript
// Simple URLSearchParams polyfill
if (!window.URLSearchParams) {
  window.URLSearchParams = function(queryString) {
    this.params = {};
    
    if (queryString) {
      const pairs = queryString.replace(/^\?/, '').split('&');
      
      pairs.forEach(pair => {
        const [key, value] = pair.split('=');
        if (key) {
          this.params[decodeURIComponent(key)] = value ? decodeURIComponent(value) : '';
        }
      });
    }
  };
  
  URLSearchParams.prototype.get = function(name) {
    return this.params[name] || null;
  };
  
  URLSearchParams.prototype.getAll = function(name) {
    return this.params[name] ? [this.params[name]] : [];
  };
  
  URLSearchParams.prototype.has = function(name) {
    return name in this.params;
  };
}

Handling Complex Query Scenarios

URL Encoding/Decoding

Proper handling of URL-encoded characters is crucial:

javascript
// URL: ?search=javascript%20tutorial
const urlParams = new URLSearchParams(window.location.search);
const searchTerm = urlParams.get('search'); // "javascript tutorial"

// Manual encoding/decoding
const encodedValue = encodeURIComponent('javascript tutorial'); // "javascript%20tutorial"
const decodedValue = decodeURIComponent('javascript%20tutorial'); // "javascript tutorial"

Fragment Parameters

Parameters in URL fragments (after #) won’t appear in window.location.search:

javascript
// URL: https://example.com/#section=about?param=value
const hash = window.location.hash;
const fragmentParams = new URLSearchParams(hash.split('?')[1] || '');

Custom URL Parsing

javascript
function parseUrlParams(url) {
  try {
    const urlObj = new URL(url);
    return new URLSearchParams(urlObj.search);
  } catch (e) {
    // Fallback for invalid URLs or non-browser environments
    const searchMatch = url.match(/\?(.+)$/);
    if (searchMatch) {
      return new URLSearchParams(searchMatch[1]);
    }
    return new URLSearchParams('');
  }
}

// Usage with any URL
const externalUrl = 'https://example.com/page?user=123&lang=en';
const params = parseUrlParams(externalUrl);

Practical Examples

Example 1: Form Pre-population

javascript
function populateForm() {
  const urlParams = new URLSearchParams(window.location.search);
  
  // Find form elements and populate them
  const form = document.getElementById('myForm');
  
  // Get all form inputs
  const inputs = form.querySelectorAll('input, select, textarea');
  
  inputs.forEach(input => {
    const paramName = input.name || input.id;
    const value = urlParams.get(paramName);
    
    if (value !== null) {
      if (input.type === 'checkbox' || input.type === 'radio') {
        input.checked = input.value === value;
      } else {
        input.value = value;
      }
    }
  });
}

// Call when DOM is ready
document.addEventListener('DOMContentLoaded', populateForm);

Example 2: Search Filter Implementation

javascript
class SearchFilter {
  constructor() {
    this.urlParams = new URLSearchParams(window.location.search);
    this.filters = {};
    
    this.initializeFilters();
    this.setupEventListeners();
  }
  
  initializeFilters() {
    // Extract filters from URL
    for (const [key, value] of this.urlParams.entries()) {
      this.filters[key] = value;
    }
    
    // Apply filters to UI
    this.applyFilters();
  }
  
  applyFilters() {
    // Update UI based on current filters
    Object.keys(this.filters).forEach(key => {
      const element = document.querySelector(`[data-filter="${key}"]`);
      if (element) {
        element.value = this.filters[key];
      }
    });
  }
  
  updateUrl() {
    // Update URL with current filters
    const newUrl = new URL(window.location);
    newUrl.search = '';
    
    Object.keys(this.filters).forEach(key => {
      if (this.filters[key]) {
        newUrl.searchParams.set(key, this.filters[key]);
      }
    });
    
    // Update URL without reloading page
    window.history.pushState({}, '', newUrl);
  }
  
  setupEventListeners() {
    // Listen for filter changes
    document.querySelectorAll('[data-filter]').forEach(element => {
      element.addEventListener('change', (e) => {
        const filterKey = e.target.dataset.filter;
        this.filters[filterKey] = e.target.value;
        this.updateUrl();
      });
    });
  }
}

// Initialize the search filter
const searchFilter = new SearchFilter();

Example 3: Analytics and Tracking

javascript
class AnalyticsTracker {
  constructor() {
    this.urlParams = new URLSearchParams(window.location.search);
    this.init();
  }
  
  init() {
    // Track source/medium from UTM parameters
    this.trackUTMParams();
    
    // Track campaign parameters
    this.trackCampaignParams();
    
    // Track custom parameters
    this.trackCustomParams();
  }
  
  trackUTMParams() {
    const utmParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];
    
    utmParams.forEach(param => {
      const value = this.urlParams.get(param);
      if (value) {
        // Send to analytics service
        this.sendToAnalytics('utm_parameter', {
          parameter: param,
          value: value
        });
      }
    });
  }
  
  trackCampaignParams() {
    const campaignParams = ['gclid', 'fbclid', 'msclkid'];
    
    campaignParams.forEach(param => {
      const value = this.urlParams.get(param);
      if (value) {
        this.sendToAnalytics('tracking_parameter', {
          parameter: param,
          value: value
        });
      }
    });
  }
  
  trackCustomParams() {
    // Track any custom parameters that start with 'track_'
    for (const [key, value] of this.urlParams.entries()) {
      if (key.startsWith('track_')) {
        this.sendToAnalytics('custom_parameter', {
          parameter: key,
          value: value
        });
      }
    }
  }
  
  sendToAnalytics(event, data) {
    // Implementation depends on your analytics service
    console.log('Analytics Event:', event, data);
    
    // Example: Google Analytics 4
    if (typeof gtag === 'function') {
      gtag('event', event, data);
    }
  }
}

// Initialize analytics tracking
const analyticsTracker = new AnalyticsTracker();

Sources

  1. MDN Web Docs - URLSearchParams
  2. Can I Use - URLSearchParams
  3. ECMAScript 2017 Specification - URLSearchParams
  4. Web.dev - Working with URLs in JavaScript
  5. Google Developers - Best Practices for URLs

Conclusion

The native URLSearchParams API is the recommended approach for extracting query string parameters in modern JavaScript applications, providing a clean, standardized interface without requiring any external dependencies. For older browser support, manual parsing with regular expressions or string manipulation methods can be implemented as alternatives. When working with query strings, remember to properly handle URL encoding/decoding and consider edge cases like multiple parameters with the same key. Modern web applications should leverage these native methods to build robust URL parameter handling that works across different environments while maintaining clean, maintainable code.