Adding a parameter to the URL with JavaScript

852,636

Solution 1

A basic implementation which you'll need to adapt would look something like this:

function insertParam(key, value) {
    key = encodeURIComponent(key);
    value = encodeURIComponent(value);

    // kvp looks like ['key1=value1', 'key2=value2', ...]
    var kvp = document.location.search.substr(1).split('&');
    let i=0;

    for(; i<kvp.length; i++){
        if (kvp[i].startsWith(key + '=')) {
            let pair = kvp[i].split('=');
            pair[1] = value;
            kvp[i] = pair.join('=');
            break;
        }
    }

    if(i >= kvp.length){
        kvp[kvp.length] = [key,value].join('=');
    }

    // can return this or...
    let params = kvp.join('&');

    // reload page with new params
    document.location.search = params;
}

This is approximately twice as fast as a regex or search based solution, but that depends completely on the length of the querystring and the index of any match


the slow regex method I benchmarked against for completions sake (approx +150% slower)

function insertParam2(key,value)
{
    key = encodeURIComponent(key); value = encodeURIComponent(value);

    var s = document.location.search;
    var kvp = key+"="+value;

    var r = new RegExp("(&|\\?)"+key+"=[^\&]*");

    s = s.replace(r,"$1"+kvp);

    if(!RegExp.$1) {s += (s.length>0 ? '&' : '?') + kvp;};

    //again, do what you will here
    document.location.search = s;
}

Solution 2

You can use one of these:

Example:

var url = new URL("http://foo.bar/?x=1&y=2");

// If your expected result is "http://foo.bar/?x=1&y=2&x=42"
url.searchParams.append('x', 42);

// If your expected result is "http://foo.bar/?x=42&y=2"
url.searchParams.set('x', 42);

You can use url.href or url.toString() to get the full URL

Solution 3

You can use URLSearchParams

const urlParams = new URLSearchParams(window.location.search);

urlParams.set('order', 'date');

window.location.search = urlParams;

.set first agrument is the key, the second one is the value.

Note: this is not supported in any version of Internet Explorer (but is supported in Edge)

Solution 4

This is very simple solution. Its doesn't control parameter existence, and it doesn't change existing value. It adds your parameter to end, so you can get latest value in your back-end code.

function addParameterToURL(param){
    _url = location.href;
    _url += (_url.split('?')[1] ? '&':'?') + param;
    return _url;
}

Solution 5

Thank you all for your contribution. I used annakata code and modified to also include the case where there is no query string in the url at all. Hope this would help.

function insertParam(key, value) {
        key = escape(key); value = escape(value);

        var kvp = document.location.search.substr(1).split('&');
        if (kvp == '') {
            document.location.search = '?' + key + '=' + value;
        }
        else {

            var i = kvp.length; var x; while (i--) {
                x = kvp[i].split('=');

                if (x[0] == key) {
                    x[1] = value;
                    kvp[i] = x.join('=');
                    break;
                }
            }

            if (i < 0) { kvp[kvp.length] = [key, value].join('='); }

            //this will reload the page, it's likely better to store this until finished
            document.location.search = kvp.join('&');
        }
    }
Share:
852,636
Lessan Vaezi
Author by

Lessan Vaezi

Updated on July 14, 2022

Comments

  • Lessan Vaezi
    Lessan Vaezi almost 2 years

    In a web application that makes use of AJAX calls, I need to submit a request but add a parameter to the end of the URL, for example:

    Original URL:

    http://server/myapp.php?id=10

    Resulting URL:

    http://server/myapp.php?id=10&enabled=true

    Looking for a JavaScript function which parses the URL looking at each parameter, then adds the new parameter or updates the value if one already exists.

    • csl
      csl over 15 years
      Have you searched for javascript url parsers ? You could make your own, splitting on every &-character, but it's probably easier just to use existing code.
    • Cerebrus
      Cerebrus over 15 years
      I had a similar scenario once and I found this article by Peter Bromberg very helpful :
    • Rutunj sheladiya
      Rutunj sheladiya over 8 years
      window.history.pushState('page2', 'Title', document.location+'/page2.php'); will do your work without loading page
    • rkb
      rkb over 7 years
      This question have better answers here stackoverflow.com/questions/6953944/…
    • bohr
      bohr almost 6 years
      unbelievable this isnt native in this poor language that JS is....
    • Piotr Kowalski
      Piotr Kowalski over 4 years
      This is very nice and lightweight library: medialize.github.io/URI.js
  • Jens Roland
    Jens Roland over 13 years
    Nice function, annakata :) but in many cases, url parameters are case insensitive. Wouldn't it be wise to make the function case insensitive as well?
  • Antonin Hildebrand
    Antonin Hildebrand almost 13 years
    Using escape() to escape URL parameters is wrong. It breaks for values with "+" in them. You should be using encodeURIComponent instead. Full discussion: xkr.us/articles/javascript/encode-compare
  • sumit
    sumit almost 13 years
    I am calling this function and the page is reloading in infinite loop. Please help!
  • ip.
    ip. over 12 years
    @iSumitG instead of location.search you can use location.hash so it won't reload ... just replace all the instances of location.search with location.hash
  • Muhd
    Muhd over 12 years
    +1 I like how you can specify something other than document.location.search
  • Muhd
    Muhd over 12 years
    @Darwin I wouldn't say it is wrong, just different from what you might expect. One could just as easily say it is wrong to use values with + in them.
  • Muhd
    Muhd over 12 years
    Top implementation doesn't handle empty location.search properly. See Mehdi's answer for updated solution.
  • kanzure
    kanzure about 12 years
    you should also account for "#" in the url.. here's some code slop: url = (url.indexOf("?") != -1 ? url.split("?")[0]+"?"+part+"&"+url.split("?")[1] : (url.indexOf("#") != -1 ? url.split("#")[0]+"?"+part+"#"+ url.split("#")[1] : url+'?'+part));
  • Roy Toledo
    Roy Toledo over 11 years
    when no parameters are already in the url you get a ?&param=value
  • Chad von Nau
    Chad von Nau over 11 years
    @kanzure this thing looks evil as hell, but it's exactly what I wanted. Thanks.
  • Murtaza Khursheed Hussain
    Murtaza Khursheed Hussain about 11 years
    and this function doesn't support multiple addition of querystring.
  • hemp
    hemp over 10 years
    Small memory leak - you'll want to remove the anchor element that was added to the document before returning.
  • hemp
    hemp over 10 years
    @freedev, Nope, I'm not sure. ;) I'm having a hard time finding an authoritative source but the evidence suggests that you are correct. Since the created element is never attached to the DOM, it should be cleaned up once the variable goes out of scope. The DOM API isn't particularly well designed when it comes to side effects, so I'm overly cautious.
  • JMTyler
    JMTyler over 10 years
    +1 Awesome, I agree that legibility is more important than micro-optimization in this case and I'm glad to see someone took that approach. @Muhd Maybe that was a bug in the JS engine when you wrote that comment, but I just tested '$1' in this context and it works fine.
  • Adrian Pronk
    Adrian Pronk almost 10 years
    Shouldn't you be using encodeURIComponent rather than encodeURI? Otherwise any characters like =, & in your name or value will corrupt the URI.
  • drzaus
    drzaus almost 10 years
    why split the url to check for the existence of a single character? also don't forget to encode...something more like function appendQs(url, key, value) { return url + (url.indexOf('?') >= 0 ? "&" : '?') + encodeURIComponent(key) + "=" + encodeURIComponent(value); };
  • Aligma
    Aligma over 9 years
    404 - The requested URL /p/jsuri/ was not found on this server. That’s all we know.
  • Charlie Liang Yuan
    Charlie Liang Yuan over 9 years
    Looks like it's been moved. I've updated the url. Best of luck!
  • Codebryo
    Codebryo over 9 years
    Thanks a lot for the solution, though I also get stuck if I want to replace a value and there is already a parameter there. Instead a & it writes $1
  • Jonathan
    Jonathan over 9 years
    Thanks for sharing your code, Lessan. I've been using this and it's worked great! I've uploaded a gist of my own version, edited to be slightly more succinct and pass JSHint validation. gist.github.com/jonathanconway/02a183920506acd9890a
  • opyh
    opyh about 9 years
    Garrett: Could you fix your answer so it replaces existing parameters correctly? It's just a matter of replacing [\?&] with ([\?&]) in the RegExp (I'd just edit it myself but I'm not sure if the community policy allows fixing bugs in answers).
  • kolobok
    kolobok over 8 years
    It would be better to change from escape(key) and escape(value) to encodeURIComponent function.
  • user706420
    user706420 about 8 years
    This is not working with url like "domain.tld" its add "&" instead of "?"
  • user706420
    user706420 about 8 years
    This is not working with url like "domain.tld#anchor"; its add "&" after the anchor
  • jave.web
    jave.web almost 8 years
    I was inspired by the first solution - good idea, but not-readable code and it does not support more params at once, so I've made a new one that does accept an object with key: value, pairs and it is easily understand-able jsfiddle.net/1u9fqad3/1 UPDATE: fixed case when document.location.search is empty or 1 char
  • Adam Leggett
    Adam Leggett over 7 years
    Not sure why someone downvoted you. This is one of the more reliable solutions, although it's way more code than necessary.
  • Adam Leggett
    Adam Leggett over 7 years
    This solution adds a trailing slash to URLs that have no path and reorders parameters, which are unnecessary and possibly undesirable changes. It also appends rather than replacing existing parameters that have no value (e.g. http://abc.def/?a&b&b).
  • freedev
    freedev over 7 years
    @AdamLeggett Thanks for pointing the bug that happens when a request parameter have no value, I have just fixed my answer. The remaining strange behaviors you're talking about, if you're right, are generated by HTML anchor object which usually is a standard browser component. I suggest to double check because very unlikely a browser adds unnecessary or undesirable behaviors.
  • Adam Leggett
    Adam Leggett over 7 years
    The browser is appending the trailing slash. You are reordering parameters yourself by appending the desired value at the end every time. This isn't wrong per se, but I'd prefer a solution that doesn't do it. You should also not be matching against &amp;, as this is not a separator; it is part of the value. Beyond that, this solution just does more work and has more code than necessary.
  • Adam Leggett
    Adam Leggett over 7 years
    Excuse me, &amp; is not part of the value either. It is just an incorrectly encoded query string.
  • freedev
    freedev over 7 years
    @AdamLeggett regarding the &amp; I had few problems with w3c HTML validators and had to use &amp; in place of & when writing URLs in HTML. htmlhelp.com/tools/validator/problems.html#amp stackoverflow.com/questions/4441594/… these problems affected this routine too.
  • freedev
    freedev over 7 years
    @AdamLeggett A properly written application will find a given query parameter in any order and it shouldn't be order sensitive. Anyway, I have to admit that this solution waste a little of resources manipulating the parameters, so I have just written a new version that it seems to be more efficient. :)
  • Adam Leggett
    Adam Leggett over 7 years
    @freedev I agree that an application shouldn't be order sensitive (except the order when a parameter appears multiple times), but my preference is to not modify the order. Anyway, your code could be easily changed to not modify the order. Please see my answer below, it's my attempt to reduce the solution to the smallest code size possible. However, mine modifies the first instance if there are multiple instances.
  • Jay
    Jay over 7 years
    Fix it. This function does not check whether the parameter is already supplied. I tested this and got https://localhost/preview/inventory.html?sortci=priceASC&sor‌​tci=priceASC&sortci=‌​stitle.
  • Alig
    Alig over 7 years
    Calling the function multiple times with the same parameter and value will add the parameter multiple times to the url. I added a check, if the url already contains the parameter and value: if (url.indexOf(str) === -1)
  • freedev
    freedev over 7 years
    The purpose of addParam function is indeed add multiple times a parameter, and maybe you should know you can pass same parameter even with same value multiple times. stackoverflow.com/questions/24059773/…
  • Daij-Djan
    Daij-Djan over 7 years
    downvoted because it has bugs that were never fixed :)
  • Charles L.
    Charles L. over 7 years
    should this actually check if (kvp.length==1 && kvp[0]="") ?
  • MAXE
    MAXE over 6 years
    It seems that this is not supported in any version of Internet Explorer
  • stillatmylinux
    stillatmylinux over 6 years
    Ideal for mobile. When Internet Explorer shows up on my mobile device, I'll throw it away. :-)
  • T04435
    T04435 over 6 years
    @MAXE you are right IE/EDGE do not support much. Supported in
  • Abdull
    Abdull over 6 years
    I'd like to add a query parameter without a value, e.g. adding XML to http://foo.bar/?x=1&y=2 so that the end result is http://foo.bar/?x=1&y=2&XML. Is this possible? I tried url.searchParams.set('XML');, url.searchParams.set('XML', null);, and url.searchParams.set('XML', undefined); - but none worked in Chrome 63.
  • kanji
    kanji about 6 years
    Thanks! Too bad it is not supported by iOS, yet. developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
  • spedy
    spedy about 6 years
    Too bad IE doesn't support it.
  • MJeffryes
    MJeffryes about 6 years
    iOS does now support URLSearchParams (since 9 days after @kanji's comment)
  • Vianney Bajart
    Vianney Bajart about 6 years
    Good news @MJeffryes! Still not supported by IE and Netscape.
  • Az.Youness
    Az.Youness about 5 years
    Yes it's bad supported by IE, but there is a polyfill that can handle that: github.com/lifaon74/url-polyfill
  • jhpratt
    jhpratt about 5 years
    Please include the relevant details in your answer, not just a link.
  • jhpratt
    jhpratt about 5 years
    Please include the relevant details in your answer, not just a link.
  • Juan Solano
    Juan Solano over 4 years
    Love the simplicity of this and that it uses native browser methods
  • Mike Lippert
    Mike Lippert over 4 years
    Are you sure you can modify the URLs searchParams like that? The doc says the property is readonly allowing get access.
  • Vianney Bajart
    Vianney Bajart over 4 years
    url.searchParams is a read-only reference to a URLSearchParams object. It means than you cannot do: url.searchParam = new URLSearchParam(); But you can modify in-place the content of the object using .set(). It's like: const a = {b: 0} You cannot modify the reference: a = {b: 1} but you can modify the content of the object in-place: a.b = 1 Try it in your JS console ;-)
  • Anthony
    Anthony over 4 years
    This is the correct answer and should be top-voted. This new API is the definitive for URL processing
  • amphetamachine
    amphetamachine about 4 years
    url.searchParams is the pre-initialized parameter list for that URL object.
  • amphetamachine
    amphetamachine about 4 years
    If you use var u = new URL(window.location), usp = u.searchParams; you don't have to use any fancy string-splitting.
  • amphetamachine
    amphetamachine about 4 years
    While your solution will work for most things, it will mangle the URL if it has a question mark in a parameter value: setUrlParams('https://example.com?foo=thing???&bar=baz', 'baz', 'qux') => "https://example.com?foo=thing&baz=qux???&bar=baz"
  • stephen
    stephen almost 4 years
    @Jay, why does it need fixing? Check your assumptions. Duplicate query string parameters are legal, the same as duplicate form fields. This is how checkbox lists are implemented.in HTML and these will get passed via query string if the form method=get.
  • Jay
    Jay almost 4 years
    @stephen got it :) Turns out I was a dumb kid in '16 :)
  • Lyubimov Roman
    Lyubimov Roman almost 4 years
    @CharlesL. better is if (document.location.search)
  • Kevin
    Kevin over 3 years
    The URLSearchParams in this answer is not supported by IE. docs
  • amarinediary
    amarinediary over 3 years
    Is IE still relevant? As Edge is here now?
  • Emzaw
    Emzaw over 3 years
    This is definitely the best answer in 2020 (2021) - if your target browser(s) don't support it, I suggest using a polyfill (e.g. from polyfill.io)
  • Andrey Mikhaylov - lolmaus
    Andrey Mikhaylov - lolmaus about 3 years
    @Abdull, have you tried url.searchParams.set('XML', '')?
  • Abdull
    Abdull about 3 years
    @AndreyMikhaylov-lolmaus, certainly, you haven't tried url.searchParams.set('XML', '') either, because it doesn't work.
  • Andrey Mikhaylov - lolmaus
    Andrey Mikhaylov - lolmaus about 3 years
    @Abdull You're right, I hadn't tried it. But I've tried it just now and it does work. Why wouldn't it? const foo = new URLSearchParams(); foo.set('XML', ''); foo.toString() // => "XML="
  • Abdull
    Abdull about 3 years
    @AndreyMikhaylov-lolmaus, read my initial question again. XML vs XML=.
  • Vipertecpro
    Vipertecpro almost 3 years
    Great thank you so much man this works great :D
  • Marcos Buarque
    Marcos Buarque almost 3 years
    IE is still relevant if you are targeting Government (June, 2021).
  • MayTheSForceBeWithYou
    MayTheSForceBeWithYou almost 3 years
    Worked great! Also implemented a removeParam by replacing the for/if section with a .splice(idx, 1) and removing the if(i >= kvp.length){ block
  • David Spector
    David Spector almost 3 years
    Wow, this is so long.
  • Vlad Lego
    Vlad Lego almost 3 years
    you have my 150 upvotes. Also, have a cookie!
  • Nicolas Appriou
    Nicolas Appriou over 2 years
    url.searchParams is read-only according to mdn.
  • AmerllicA
    AmerllicA over 2 years
    @NicolasAppriou, Ok, is here any code that is against the link you mentioned?
  • Vsevolod Golovanov
    Vsevolod Golovanov over 2 years
    Kinda clunky for a definitive API. Wish it was a one liner.
  • AmerllicA
    AmerllicA over 2 years
    @MuhammedMoussa, Thanks for your great edit, really thanks. but bro, what is IE then?
  • gogaz
    gogaz over 2 years
    if you use searchParams.add('x', null) it will generate ?x=null which will most likely not be what you expect
  • FreeSoftwareServers
    FreeSoftwareServers over 2 years
    My query is full of duplicate strings lol, only one primary key. There's so many duplicate strings I have to break up the posts occasionally
  • Reneesh Kurian
    Reneesh Kurian about 2 years
    updated code which support mutiple params. function insertCustomParams(input) { var output = []; var i = 0; Object.entries(input).forEach(function (k, v) { output[i++] = k.join("="); }); var kvp = document.location.search.substr(1).split("&"); var j = 0; for (; j < kvp.length; j++) { let pair = kvp[j].split("="); if (!Object.keys(input).includes(pair[0])) { output[i++] = pair.join("="); } } document.location.search = output.join("&"); }
  • Matěj Husák
    Matěj Husák almost 2 years
    overcomplicated for this use case
  • TomSawyer
    TomSawyer almost 2 years
    Doesn't work on url has no query, like /abc/