43

How do you get and set URL hash parameters in pure JavaScript?

For example, I'd like to use parameters like this: myurl.com/#from=2012-01-05&to=2013-01-01

And I'd like to be able to get and set the from and to parameters in the above.

I'm happy to use the HTML5 history API if that's the best way of doing things.

10
  • Where's the URL? The location object and <a> elements give you this ability automatically. Commented May 16, 2014 at 15:59
  • liar! stackoverflow.com/questions/298503/… Commented May 16, 2014 at 16:01
  • 1
    For such, just use the code to parse the location.search query on location.hash Commented May 16, 2014 at 16:03
  • 1
    @Bergi thanks - that explains how to get parameters, but not how to set them. I'll see if I can adapt it to set them, and if I can then I'll post working code here. Commented May 16, 2014 at 16:06
  • 1
    > I assume that means you want to send them to the server Why assume that? We use this kind of thing purely front end to provide a navigable URL that can setup UI elements. Commented Oct 30, 2015 at 12:37

8 Answers 8

76

If you want to parse a hash URL:

var hash = window.location.hash.substr(1);

var result = hash.split('&').reduce(function (res, item) {
    var parts = item.split('=');
    res[parts[0]] = parts[1];
    return res;
}, {});

That way, if you have this: http://example.com/#from=2012-01-05&to=2013-01-01

It becomes: {'from': '2012-01-05', 'to':'2013-01-01'}

As @Dean Stamler notes in the comments, dont forget the empty starting object. }, {});

Now to set a hash URL:

window.location.hash = "from=2012-01-05&to=2013-01-01";

Sign up to request clarification or add additional context in comments.

3 Comments

@RickS, result is an array of all the params. Note that "from" and "to" are multiple params. Please test it out, it works just fine with multiple params.
@RickS if it's not working for multiple params it's very likely that you haven't included the empty object {} as a second argument to the reduce() call. This is the initial value of the accumulator.
A bit confusing to have the intermediate result and the final result share the same variable name IMO
14

As for getting parameters... how about this solution:

var myUrl = new URL(window.location.href.replace(/#/g,"?"));
var param_value = myUrl.searchParams.get("param_name");

Wish u luck!

3 Comments

It will work properly only if the url doesn't have any query parameters yet (and doesn't contain ? yet). So for example for this url it will not work: stackoverflow.com/?lala=kuku#bebe=nene
@Alexander You can solve that issue like this var myUrl = new URL('a://' + window.location.hash.replace(/^#/g,"?")) (a:// is just the shortest possible "valid" url)
@Lindsay-Needs-Sleep i dont think you need regex, in my code # works fine
13

You can set the hash with:

window.location.hash = "new value";

and (in newer browsers) listen to changes with:

window.addEventListener("hashchange", function () {
});

If you need to support browsers that don't support "hashchange" you'll want to use code that other people have written, such as jquery's history plugin.

4 Comments

Which older browsers do not support location.hash? (Btw, it's window. usually not document.)
location.hash is well supported, but not "hashchange". For older versions of IE you need a hack that involves an iframe. See: caniuse.com/#search=hashchange
Yeah, that's what I expected, but your phrasing "Newer versions of browsers support setting" is confusing.
I just want to make it abundantly clear that there compatibility issues.
6

The other answers don't address the problem

I got a way easier approach:

Copy over current hashparameters to a dummy URL as searchParameters. Now you can treat the hash parameters like search-parameters and copy them back afterwards:

Simple function

function setOrUpdateHashParameter( hashParameterName, hashParameterValue ) {
    let theURL              = new URL('https://dummy.com');             // create dummy url
    theURL.search           = window.location.hash.substring(1);        // copy current hash-parameters without the '#' AS search-parameters
    theURL.searchParams.set( hashParameterName, hashParameterValue );   // set or update value with the searchParams-API
    window.location.hash    = theURL.searchParams;                      // Write back as hashparameters
}

1 Comment

Be aware, that it is not working in Internet Explorer 11. developer.mozilla.org/en-US/docs/Web/API/URL/…
4

For Multiple Params:

const href = window.location.href;
const params = href.split('?')[1];

// Be sure url params exist
if (params && params !== '') {
    const result = params.split('&').reduce(function (res, item) {
        const parts = item.split('=');
        res[parts[0]] = parts[1];
        return res;
    }, {});
}

Therefore, when href=https://www.example.net/page.html#/page1?foo=bar&token=123abc the result will evaluate to {foo: "bar", token: "123abc"}.

This structure requires that the URL has the question mark ? before the params, an equal sign = between the variable key and value, and a & between each key/value pair.

3 Comments

Hey! I am trying to use your code snippet and it returns only the last hash value in object. Do you know why it can happen? I am using window.location.hash and before applying reduce, I do this: decodeURI(window.location.hash).substr(1).split('&').
The example of url I have: www.example.com#word=foo&word=bar. Can it be because I have same key (word) for parameters?
@OlgaB using this snippet, you need to use a ? to split the params from the rest. You can also replace the ? in const params with #.
4

For get only:

const startingUrl = 'https://stackoverflow.com/questions/23699666/javascript-get-and-set-url-hash-parameters#state=XXX&b=YYY'
const myUrl = new URL(startingUrl);
const hash = new URLSearchParams(myUrl.hash.substring(1))
hash.get('state'); // XXX
hash.get('b'); // YYY

enter image description here

Comments

2

This is my solution

arr = location.search.replace('?', '').split('&').map(x => x.split('=')).map(x => {
    let keyName = x[0];
    let val = x[1];
    let object = {};
    object[keyName] = val;
    return object;
});

obj = {}

arr.forEach(function(x) {
    let key = Object.keys(x)[0];
    obj[key] = x[key];
});

console.log(obj);

Basicaly with location.search we obtain the right part of a url, after the path (the query params with).

location.search also returns the '?' character, replace with white space, then split whit '&', map and split with '=', for obtain un array like

[['term', 'hello'], ['lang', 'es']]

Then, assemble the object as you wanted

arr = "?safe=active&source=hp&ei=c4Q8XcOPFd3F5OUP7e242Ag&q=hola&oq=hola&gs_l=psy-ab.3..0l5j0i131j0l2j0i131j0.1324.1667..1798...1.0..0.264.744.1j3j1......0....1..gws-wiz.....10..35i39.-_FkFlX_Muw&ved=0ahUKEwiDlaTgytXjAhXdIrkGHe02DosQ4dUDCAU&uact=5".replace('?', '').split('&').map(x => x.split('=')).map(x => {
    let keyName = x[0];
    let val = x[1];
    let object = {};
    object[keyName] = val;
    return object;
});

obj = {}

arr.forEach(function(x) {
    let key = Object.keys(x)[0];
    obj[key] = x[key];
});

console.log(obj);

2 Comments

You may want to provide more information as to what your solution does.
thanks @RobRose, i edit the response then. My english is bad, sorry
1

Based upon Maart's answer here is a version which returns the edited URL rather than applying the change to the current window.

function setHashParam(url, name, value) {

    // Create URL objects for the url we want to change and a dummy url (requires a polyfill for IE)
    var urlObj = new URL(url);
    var dummyObj = new URL('https://dummy.com');

    // Copy current hash-parameters without the '#' as search-parameters
    dummyObj.search = urlObj.hash.substring(1);

    // Set or update value with the searchParams-API (requires a polyfill for IE)
    dummyObj.searchParams.set(name, value);

    // Write back as hashparameters
    urlObj.hash = dummyObj.searchParams;

    return urlObj.href;
}

Note that for this answer (and Maart's) to work in IE they require polyfills for the URL constructor and the search params API.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.