Appending parameter to URL without refresh

JavascriptJqueryHtmlPushstateHtml5 History

Javascript Problem Overview


I know this has been asked many times before but answers were not descriptive enough to solve my problem. I don't want to change the whole URL of page. I want to append a parameter &item=brand on button click without refresh.

Using document.location.search += '&item=brand'; makes the page refresh.

Using window.location.hash = "&item=brand"; append without refresh but with a hash # which eliminates the usage/effect of the parameter. I tried to remove the hash after appending but that didn't work.


This answer and many others suggest the use of HTML5 History API, specifically the history.pushState method, and for old browsers is to set a fragment identifier to prevent page from reloading. But how?


Assuming the URL is: http://example.com/search.php?lang=en

How can I append &item=brand using HTML5 pushState method or a fragment identifier so the output would be like this: http://example.com/search.php?lang=en&item=brand without a page refresh?


I hope someone can throw some light on how to use the HTML5 pushState to append a parameter to an existing/current URL. Or alternatively how to set a fragment identifier for the same purpose. A good tutorial, demo or piece of code with a little explanation would be great.

Demo of what I've done so far. Your answers would be greatly appreciated.

Javascript Solutions


Solution 1 - Javascript

You can use the pushState or replaceState methods, i.e. :

window.history.pushState("object or string", "Title", "new url");

OR

window.history.replaceState(null, null, "?arg=123");

Example with argument:

var refresh = window.location.protocol + "//" + window.location.host + window.location.pathname + '?arg=1';    
window.history.pushState({ path: refresh }, '', refresh);

Solution 2 - Javascript

If anyone wants to add a parameter to a more complex url (I mean, https://stackoverflow.com/questions/edit?newParameter=1), the following code worked for me:

var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?newParameter=1';
window.history.pushState({ path: newurl }, '', newurl);

Hope this helps!

Solution 3 - Javascript

You can also use URL API if you want to add and remove params at the same time:

const url = new URL(window.location.href);
url.searchParams.set('param1', 'val1');
url.searchParams.delete('param2');
window.history.replaceState(null, null, url); // or pushState

Solution 4 - Javascript

Modified Medhi answer and this did the trick

const insertParam = (key: string, value: string) => {
    key = encodeURIComponent(key);
    value = encodeURIComponent(value);

    let kvp = window.location.search.substr(1).split('&');
    if (kvp[0] === '') {
        const path = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' + key + '=' + value;
        window.history.pushState({ path: path }, '', path);

    } else {
        let i = kvp.length; let 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('=');
        }

        const refresh = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' + kvp.join('&');  
        window.history.pushState({ path: refresh }, '', refresh);
    }
}

Solution 5 - Javascript

export function getHash(hash: string, key: string): string | undefined {
  return hash
    .split("#")
    .find((h) => h.startsWith(key))
    ?.replace(`${key}=`, "");
}
export function setHash(hash: string, key: string, value: string): string {
  let hashArray = hash.split("#").filter((h) => !h.startsWith(key));
  hashArray.push(`${key}=${value}`);
  return hashArray.length > 0
    ? hashArray.reduce((s1, s2) => `${s1}#${s2}`)
    : "";
}
export function deleteHash(hash: string, key: string): string {
  let hashArray = hash.split("#").filter((h) => !h.startsWith(key));
  return hashArray.length > 0
    ? hashArray.reduce((s1, s2) => `${s1}#${s2}`)
    : "";
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMina HafzallaView Question on Stackoverflow
Solution 1 - JavascriptPedro LobitoView Answer on Stackoverflow
Solution 2 - JavascriptpablobasconesView Answer on Stackoverflow
Solution 3 - JavascriptYarrowView Answer on Stackoverflow
Solution 4 - JavascriptBanobe PascalView Answer on Stackoverflow
Solution 5 - Javascriptuser12535483View Answer on Stackoverflow