444

I have URL like: http://example.com#something, how do I remove #something, without causing the page to refresh?

I attempted the following solution:

window.location.hash = '';

However, this doesn't remove the hash symbol # from the URL.

6
  • 4
    Do you really want to do this? It'll cause a page refresh. Commented Sep 9, 2009 at 3:08
  • 17
    Is it possible to do without a page refresh? Commented Sep 9, 2009 at 3:11
  • 2
    It is possible. AJAX history libraries deal with it. But it's not easy, and it has to be done differently for almost every browser. Not something you wanna get into. Commented Sep 9, 2009 at 3:14
  • Is there any conciderations with leaving a "#" behind other than a visual one? Commented Aug 16, 2016 at 10:55
  • Possible duplicate of Modify the URL without reloading the page Commented Sep 10, 2017 at 12:53

18 Answers 18

700

Solving this problem is much more within reach nowadays. The HTML5 History API allows us to manipulate the location bar to display any URL within the current domain.

function removeHash () { 
    history.pushState("", document.title, window.location.pathname
                                                       + window.location.search);
}

Working demo: http://jsfiddle.net/AndyE/ycmPt/show/

This works in Chrome 9, Firefox 4, Safari 5, Opera 11.50 and in IE 10. For unsupported browsers, you could always write a gracefully degrading script that makes use of it where available:

function removeHash () { 
    var scrollV, scrollH, loc = window.location;
    if ("pushState" in history)
        history.pushState("", document.title, loc.pathname + loc.search);
    else {
        // Prevent scrolling by storing the page's current scroll offset
        scrollV = document.body.scrollTop;
        scrollH = document.body.scrollLeft;

        loc.hash = "";

        // Restore the scroll offset, should be flicker free
        document.body.scrollTop = scrollV;
        document.body.scrollLeft = scrollH;
    }
}

So you can get rid of the hash symbol, just not in all browsers — yet.

Note: if you want to replace the current page in the browser history, use replaceState() instead of pushState().

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

13 Comments

Use this line to make sure you don't lose the query string: history.pushState("", document.title, window.location.pathname + window.location.search);
@Phil: thanks for pointing that out, I've updated the answer accordingly. I'm too used to using pretty URLs.
For older versions of IE, it seems you need to use document.documentElement instead of document.body. See this answer stackoverflow.com/a/2717272/359048
I suggest using replaceState instead of pushState, to not create an extra entry in the browser history.
I think history.pushState will not trigger hashshange whereas window.location.hash will. To me this event is very important, so just be careful
|
247

Initial question:

window.location.href.substr(0, window.location.href.indexOf('#'))

or

window.location.href.split('#')[0]

both will return the URL without the hash or anything after it.

With regards to your edit:

Any change to window.location will trigger a page refresh. You can change window.location.hash without triggering the refresh (though the window will jump if your hash matches an id on the page), but you can't get rid of the hash sign. Take your pick for which is worse...

MOST UP-TO-DATE ANSWER

The right answer on how to do it without sacrificing (either full reload or leaving the hash sign there) is up here. Leaving this answer here though with respect to being the original one in 2009 whereas the correct one which leverages new browser APIs was given 1.5 years later.

14 Comments

This is just plain wrong, you can change window.location.hash and it will not trigger a refresh.
@Evgeny -- That's what my answer says. I explicitly say that changing window.location.hash won't trigger a refresh. "You can change window.location.hash without triggering the refresh (though the window will jump if your hash matches an id on the page)".
No page reload - that is in the question. This is not the answer as it requires/forces a page reload!
also think it should not be the ✓answer
This is not an answer to the OP question.
|
172

(Too many answers are redundant and outdated.) The best solution now is this:

history.replaceState(null, null, ' ');

9 Comments

use history.pushState(null, null, ' ') instead if you want to preserve history.
It might be useful to explain what passing null for the state and title parameters ultimately does.
A problem with this, and the rest, is that it doesn't trigger onhashchange, even though the hash is now empty when it wasn't before.
In TypeScript, null is not allowed for the second parameter because the command takes a string. Mozilla recommends empty string.
is this behavior documented somewhere? is it supported by all browsers/versions?
|
52

Simple and elegant:

history.replaceState({}, document.title, ".");  // replace / with . to keep url

6 Comments

use a dot instead of a slash if you want to stay in the same directory
Please update answer as regards @vahanpwns note, to use . instead of /. Using / changes the url to the root path.
Thanks for this answer, I modified to history.replaceState({}, document.title, location.href.substr(0, location.href.length-location.hash.length)); for my use case.
This does not preserve url query.
My use-case was also to replace instead of push, but this makes more sense to me: history.replaceState(null, document.title, location.pathname + location.search);
|
33

You can do it as below:

history.replaceState({}, document.title, window.location.href.split('#')[0]);

1 Comment

The starred answer didn't work for me in either case, but this one did. Thanks!
16

To remove the hash, you may try using this function

function remove_hash_from_url()
{
    var uri = window.location.toString();
    if (uri.indexOf("#") > 0) {
        var clean_uri = uri.substring(0, uri.indexOf("#"));
        window.history.replaceState({}, document.title, clean_uri);
    }
}

Comments

15

This will remove the trailing hash as well. eg: http://test.com/123#abc -> http://test.com/123

if(window.history.pushState) {
    window.history.pushState('', '/', window.location.pathname)
} else {
    window.location.hash = '';
}

2 Comments

This removes any query params present in the URL :(
@kevgathuku you can add them back with location.search, eg: ` window.history.pushState('', '/', window.location.pathname + window.location.search)`
7
function removeLocationHash(){
    var noHashURL = window.location.href.replace(/#.*$/, '');
    window.history.replaceState('', document.title, noHashURL) 
}

window.addEventListener("load", function(){
    removeLocationHash();
});

Comments

6

How about the following?

window.location.hash=' '

Please note that am setting the hash to a single space and not an empty string.


Setting the hash to an invalid anchor does not cause a refresh either. Such as,

window.location.hash='invalidtag'

But, I find above solution to be misleading. This seems to indicate that there is an anchor on the given position with the given name although there isn't one. At the same time, using an empty string causes page to move to the top which can be unacceptable at times. Using a space also ensures that whenever the URL is copied and bookmarked and visited again, the page will usually be at the top and the space will be ignored.

And, hey, this is my first answer on StackOverflow. Hope someone finds it useful and it matches the community standards.

4 Comments

Setting hash to whitespace still keeps the # at the end of the URL, I think the goal is to remove it altogether.
It trails a hash at the end of the URL. The question is how to remove that.
Yes how can we can remove # as well with hash string.
Even with something like document.location.hash = "avalidtagthatdoesntconfusejavascriptanditsanexampleafterall" it still makes it #avalidtagthatdoesntconfusejavascriptanditsanexampleafterall
6
const url = new URL(window.location);
url.hash = '';
history.replaceState(null, document.title, url);

1 Comment

While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value.
3
<script type="text/javascript">
var uri = window.location.toString();
if (uri.indexOf("?") > 0) {
    var clean_uri = uri.substring(0, uri.indexOf("?"));
    window.history.replaceState({}, document.title, clean_uri);
}
</script>

put this code on head section

Comments

3

I think, it would be more safe

if (window.history) {
    window.history.pushState('', document.title, window.location.href.replace(window.location.hash, ''));
} else {
    window.location.hash = '';
}

Comments

1
if (window.location.href.includes('#')) {
    const cleanedUrl = window.location.href.split('#')[0];
    window.history.replaceState(null, null, cleanedUrl);
}

Comments

0

Here is another solution to change the location using href and clear the hash without scrolling.

The magic solution is explained here. Specs here.

const hash = window.location.hash;
history.scrollRestoration = 'manual';
window.location.href = hash;    
history.pushState('', document.title, window.location.pathname);

NOTE: The proposed API is now part of WhatWG HTML Living Standard

Comments

0
$(window).on('hashchange', function (e) {
    history.replaceState('', document.title, e.oldURL);
});

Comments

0

Building off one of the answers given above, use this:

var scrollV, scrollH
var loc = window.location;
scrollV = document.body.scrollTop;
scrollH = document.body.scrollLeft;
if ("pushState" in history) {
    history.pushState("", document.title, loc.pathname + loc.search);

    // Restore the scroll offset
    document.body.scrollTop = scrollV;
    document.body.scrollLeft = scrollH;

} else {
    loc.hash = "";

    // Restore the scroll offset
    document.body.scrollTop = scrollV;
    document.body.scrollLeft = scrollH;
}

Comments

-1

Try the following:

window.history.back(1);

4 Comments

This doesn't answer the question if the user has come directly to the URL including the hash.
This trick is very useful when you just want create a link to previous page, but the link is hidden in bunch of js files.
Exactly what I was looking for. This works perfectly to remove a hashtag just created by my web app in order to consume a value returned by a javasript function.
Well what if <a href="#"></a>?
-6

You can replace hash with null

var urlWithoutHash = document.location.href.replace(location.hash , "" );

3 Comments

The question asks "without causing the page to refresh", but this method does refresh the page. You should note this fact in your answer, so we don't all have to waste our time finding out firsthand that you're answering a different question than the one we're actually trying to get answered here.
It does not refresh the page.
It does not refresh the page because it isn't updating the URL. replace returns a fresh new string and location.href remains the same. As soon as you do location.href = urlWithouthHash you will get the refresh.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.