Appending parameter to URL without refresh
Asked Answered
H

6

115

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.

Handsome answered 28/9, 2015 at 16:57 Comment(0)
L
187

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

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);
Lentha answered 28/9, 2015 at 17:0 Comment(4)
Thank you so much! that worked, but surprisingly the parameter didn't apply into the system. However, it take effect when I add it manually into the URL. I will take this as an accepted answer as it solves my main question but please if you have a suggestion on why the parameter won't be applied to system when added using the history.pushState please tell me :) Thank you again.Handsome
Thanks, I ending up using window.history.replaceState(null, null, "?mock"); To add a url param without reload.Diep
Browser compatibility is somewhat good, but note that it won't work for below IE10 or (potentially) some mobile browsers.Hackamore
This is not "appending" the URL. This removed a bunch of other parameters I had in my web browser's URL string. Those other parameters are important, so I'm not sure why this was the accepted answer.Martin
L
59

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
Lakshmi answered 25/12, 2020 at 12:26 Comment(1)
Much nicer than reconstructing the URL like window.location.protocol + "//" + window.location.host + window.location.pathname + '?arg=1'Acculturize
S
31

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!

Scuta answered 5/4, 2018 at 18:5 Comment(3)
here is the reference to this working code. eureka.ykyuen.info/2015/04/08/…Magna
I also add window.location.hash to the end of the new URL.Gheber
This removed a bunch of other parameters I had in my web browser's URL string. Those other parameters are important.Martin
Z
1

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);
    }
}
Zanazander answered 19/5, 2021 at 16:35 Comment(0)
E
1

If you want to append multiple parameters in the current url without reloading the page, try this:

window.history.replaceState(null, null, `?${$.param({
   item: 'brand',
   lang: 'en',
})}`);

$.param will convert your object to item=brand&lang=en then just add ? at the beginning.

The result would be: httpts://app.com/index?item=brand&lang=en

Elongate answered 7/3, 2023 at 9:40 Comment(0)
A
-1

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}`)
    : "";
}
Ascanius answered 5/10, 2020 at 18:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.