14

I'm wondering how I can add a new parameter to an existing url. The problem is: the url may also contain an anchor.

For example:

http://www.example.com?foo=bar#hashme

And I want to add another parameter to it, so it results in this:

http://www.example.com?foo=bar&x=y#hashme
skerit
  • 17,691
  • 22
  • 92
  • 138
  • 1
    possible duplicate of [Adding a parameter to the URL with JavaScript](http://stackoverflow.com/questions/486896/adding-a-parameter-to-the-url-with-javascript) – Bertrand Marron Aug 05 '11 at 09:18
  • I found that at first, but the question does not deal with anchors AND it deals with the document's current url. Here I have to deal with anchors and I use external urls. – skerit Aug 05 '11 at 09:38
  • It only overrides `document.location.search`. – Bertrand Marron Aug 05 '11 at 09:43

9 Answers9

24

I used parts of The Awesome One's solution, and a solution found on this question:

Adding a parameter to the URL with JavaScript

Combining them into this script:

function addParameter(url, parameterName, parameterValue, atStart/*Add param before others*/){
    replaceDuplicates = true;
    if(url.indexOf('#') > 0){
        var cl = url.indexOf('#');
        urlhash = url.substring(url.indexOf('#'),url.length);
    } else {
        urlhash = '';
        cl = url.length;
    }
    sourceUrl = url.substring(0,cl);

    var urlParts = sourceUrl.split("?");
    var newQueryString = "";

    if (urlParts.length > 1)
    {
        var parameters = urlParts[1].split("&");
        for (var i=0; (i < parameters.length); i++)
        {
            var parameterParts = parameters[i].split("=");
            if (!(replaceDuplicates && parameterParts[0] == parameterName))
            {
                if (newQueryString == "")
                    newQueryString = "?";
                else
                    newQueryString += "&";
                newQueryString += parameterParts[0] + "=" + (parameterParts[1]?parameterParts[1]:'');
            }
        }
    }
    if (newQueryString == "")
        newQueryString = "?";

    if(atStart){
        newQueryString = '?'+ parameterName + "=" + parameterValue + (newQueryString.length>1?'&'+newQueryString.substring(1):'');
    } else {
        if (newQueryString !== "" && newQueryString != '?')
            newQueryString += "&";
        newQueryString += parameterName + "=" + (parameterValue?parameterValue:'');
    }
    return urlParts[0] + newQueryString + urlhash;
};

Example: addParameter('http://www.example.com?foo=bar#hashme', 'bla', 'valuebla', false)

Results in http://www.example.com?foo=bar&bla=valuebla#hashme

Community
  • 1
  • 1
skerit
  • 17,691
  • 22
  • 92
  • 138
  • works good. I changed `if (urlParts.length > 1)` to `if (urlParts.length > 1 && urlParts[1] != '')` because my URL sometimes ends with ? without anything behind it, which caused something like myurl?=&x=1 – Flion Jan 29 '13 at 18:35
  • 1
    Were those global vars intended? – Sisir Feb 22 '16 at 10:58
  • 1
    Use `url.lastIndexOf('#')` to add support for urls with hash in path. See my answer. – rkb Jan 12 '17 at 05:56
  • You split on ?, but a URL can have multiple "?"s in it: https://www.bing.com/?q=ques?tion – Michael Tontchev Feb 06 '19 at 19:39
10

This can be another good solution, this version is even able to replace the parameter if it already exists, add parameter without value:

function addParam(url, param, value) {
   var a = document.createElement('a'), regex = /(?:\?|&amp;|&)+([^=]+)(?:=([^&]*))*/g;
   var match, str = []; a.href = url; param = encodeURIComponent(param);
   while (match = regex.exec(a.search))
       if (param != match[1]) str.push(match[1]+(match[2]?"="+match[2]:""));
   str.push(param+(value?"="+ encodeURIComponent(value):""));
   a.search = str.join("&");
   return a.href;
}

url = "http://www.example.com#hashme";
newurl = addParam(url, "ciao", "1");
alert(newurl);

http://jsfiddle.net/bknE4/81/

freedev
  • 17,230
  • 4
  • 83
  • 98
  • I tried your solution but I didn't love it since it only ADD the parameter but don't merge them if they already exist. – RPDeshaies Apr 14 '14 at 20:07
  • 1
    Hi @Tareck117 I have added a new version able to replace the parameter in query string if it already exists – freedev Apr 15 '14 at 09:09
  • 1
    Thank you for your solution! However, this doesn't work on IE8 since a.search assignment (a.search = ...) in your code above failed as "invalid URL"... – Fumisky Wells Mar 24 '15 at 07:16
  • 1
    @FumiskyWells Hi, thanks for your feedback. I have fixed the problem in this new version. Please take a look at jsfiddle. – freedev Apr 01 '15 at 23:11
3

You can use this JS lib called URI.JS

// mutating URLs
URI("http://example.org/foo.html?hello=world")
    .username("rodneyrehm") 
        // -> http://rodneyrehm@example.org/foo.html?hello=world
    .username("") 
        // -> http://example.org/foo.html?hello=world
    .directory("bar")
        // -> http://example.org/bar/foo.html?hello=world
    .suffix("xml")    
        // -> http://example.org/bar/foo.xml?hello=world
    .hash("hackernews")
        // -> http://example.org/bar/foo.xml?hello=world#hackernews
    .fragment("")
        // -> http://example.org/bar/foo.xml?hello=world
    .search("") // alias of .query()
        // -> http://example.org/bar/foo.xml
    .tld("com")
        // -> http://example.com/bar/foo.xml
    .search({ foo: "bar", hello: ["world", "mars"] });
        // -> http://example.com/bar/foo.xml?foo=bar&hello=world&hello=mars

or

URI("?hello=world")
    .addSearch("hello", "mars")
        // -> ?hello=world&hello=mars
    .addSearch({ foo: ["bar", "baz"] })
        // -> ?hello=world&hello=mars&foo=bar&foo=baz
    .removeSearch("hello", "mars")
        // -> ?hello=world&foo=bar&foo=baz
    .removeSearch("foo")
        // -> ?hello=world
Srinivas Gowda
  • 261
  • 2
  • 15
3

Try this:

location.href = location.href.replace(location.hash, '') + '&x=y' + location.hash

Update

What about this:

var a = document.createElement('a');
a.href = "http://www.example.com?foo=bar#hashme";

var url = a.href.replace(a.hash, '') + '&x=y' + a.hash;

I found out that the location object can be created by an anchor element(from Creating a new Location object in javascript).

Community
  • 1
  • 1
Sanghyun Lee
  • 17,726
  • 18
  • 88
  • 118
1

@freedev answer is great, but if you need something very simple (to insert key=value pair to the url and assume that key doesn't already exist), there's a much faster way to do it:

var addSearchParam = function(url,keyEqualsValue) {

    var parts=url.split('#');
    parts[0]=parts[0]+(( parts[0].indexOf('?') !== -1) ? '&' : '?')+keyEqualsValue;
    return parts.join('#');

}

Example usage: addSearchParam('http://localhost?a=1#hash','b=5');

Maciej Krawczyk
  • 10,012
  • 5
  • 30
  • 38
  • I'm sure this will catch me out at some point in the future but it looks like it solves my need so I'm going to use it :P – rtpHarry Nov 13 '20 at 21:56
1

Here is an improved version of the answer by @skerit. This one supports # in URL path.

function addParameter(url, parameterName, parameterValue, atStart/*Add param before others*/) { 

    var replaceDuplicates = true;
    var cl, urlhash;

    parameterName = encodeURIComponent(parameterName);
    parameterValue = encodeURIComponent(parameterValue);

    if (url.lastIndexOf('#') > 0) {
        cl = url.lastIndexOf('#');
        urlhash = url.substring(cl, url.length);
    } else {
        urlhash = '';
        cl = url.length;
    } 

    var sourceUrl = url.substring(0, cl);
    var urlParts = sourceUrl.split("?");
    var newQueryString = "";

    if (urlParts.length > 1) {
        var parameters = urlParts[1].split("&");
        for (var i=0; (i < parameters.length); i++) {
            var parameterParts = parameters[i].split("=");
            if (!(replaceDuplicates && parameterParts[0] === parameterName)) {
                if (newQueryString === "") {
                    newQueryString = "?";
                } else {
                    newQueryString += "&";
                }
                newQueryString += parameterParts[0] + "=" + (parameterParts[1]?parameterParts[1]:'');
            }
        }
    } 

    if (newQueryString === "") {
        newQueryString = "?";
    }

    if (atStart) {
        newQueryString = '?'+ parameterName + "=" + parameterValue + (newQueryString.length>1?'&'+newQueryString.substring(1):'');
    } else {
        if (newQueryString !== "" && newQueryString != '?') {
            newQueryString += "&";
        }
        newQueryString += parameterName + "=" + (parameterValue?parameterValue:'');
    }
    return urlParts[0] + newQueryString + urlhash;
}

Examples:

addParameter('http://www.example.com?foo=bar#hashme', 'bla', 'valuebla', false);
// Returns: http://www.example.com?foo=bar&bla=valuebla#hashme
addParameter('http://www.example.com/#iAmNotUrlHash/?foo=bar#hashme', 'bla', 'valuebla', false);
// Returns: http://www.example.com/#iAmNotUrlHash/?foo=bar&bla=valuebla#hashme
rkb
  • 452
  • 2
  • 9
  • 18
1

Easy.

<script>
function addPar(URL,param,value){
var url = URL;
var hash = url.indexOf('#');
if(hash==-1)hash=url.length;
var partOne = url.substring(0,hash);
var partTwo = url.substring(hash,url.length);
var newURL = partOne+'&'+param+'='+value+partTwo
return newURL;
}
document.write(addPar('http://www.example.com?foo=bar','x','y')) // returns what you asked for
</script>

The code could be modified a bit, and made a little more efficient, but this should work fine.

@Sangol's solution's better. Didn't know a location.hash property existed.

Some Guy
  • 14,742
  • 10
  • 54
  • 67
0

I always use this code, and its working fine ...

var currenturl=location.href;
var url = location.href+"?ts="+true;
window.location.replace(url,"_self");
Dhaval dave
  • 172
  • 2
  • 9
0

Something like this ?

var param = "x=y";
var split = url.split('#');
url = split[0] + '&' + param + "#" + split[1];
Some Guy
  • 14,742
  • 10
  • 54
  • 67
slaphappy
  • 6,759
  • 3
  • 31
  • 58