26

Possible Duplicate:
What’s the shebang/hashbang (#!) in Facebook and new Twitter URLs for?

I was wondering how Twitter works its links.

If you look in the source code, you use the links are done like /#!/i/connect or /#!/i/discover, but they don't have a JavaScript function attached to them like load('connect') or something, and that it doesn't require a page reload. It just changes out the page content.

I saw this page, but then all of those files would have to exist, and you couldn't just go straight to one of them. I imagine that on Twitter each of those files don't exist, and that it is handled in some other method. Please correct me if I'm wrong, though.

Is there a way I could replicate this effect? If so, is there a tutorial on how to go about doing this?

Community
  • 1
  • 1
ixchi
  • 2,349
  • 2
  • 26
  • 23
  • When you mark a question as duplicate, it would be useful with a reference to the duplicate itself. Is this the one you mean? http://stackoverflow.com/questions/3009380/whats-the-shebang-hashbang-in-facebook-and-new-twitter-urls-for?lq=1 – Per Quested Aronsson Jul 27 '13 at 04:52
  • You should now seriously re-consider your accepted answer as @BillBad explained it exceptionally good! – Subliminal Hash Sep 02 '14 at 17:54
  • @Emin okay, I did so! Haven't looked back on this question in a while – ixchi Sep 05 '14 at 01:09

2 Answers2

124

"Hash-Bang" navigation, as it's sometimes called, ...

http://example.com/path/to/#!/some-ajax-state

...is a temporary solution for a temporary problem that is quickly becoming a non-issue thanks to modern browser standards. In all likelihood, Twitter will phase it out, as Facebook is already doing.

It is the combination of several concepts...

In the past, a link served two purposes: It loaded a new document and/or scrolled down to an embedded anchor as indicated with the hash (#).

http://example.com/script.php#fourth-paragraph

Anything in a URL after the hash was not requested from the server, but was searched for in the page by the browser. This all still works just fine.

With the adoption of AJAX, new content could be loaded into the current (already loaded) page. With this dynamic loading, several problems arose: 1) there was no unique URL for bookmarking or linking to this new content, 2) search would never see it.

Some smart people solved the first problem by using the hash as a sort of "state" reference to be included in links & bookmarks. After the document loads, the browser reads the hash and runs the AJAX requests, displaying the page plus its dynamic AJAX changes.

http://example.com/script.php#some-ajax-state

This solved the AJAX problem, but the search engine problem still existed. Search engines don't load pages and execute Javascript like a browser.

Google to the rescue. Google proposed a scheme where any URL with a hash-bang (#!) in lieu of just a hash (#) would suggest to the search bot that there was an alternate URL for indexing, which involved an "_escaped_fragment_" variable, among other things. Read about it here: Ajax Crawling: Getting Started.

Today, with the adoption of Javascript's pushstate in most major browsers, all of this is becoming obsolete. With pushstate, as content is dynamically loaded or changed, the current page URL can be altered without causing a page load. When desired, this provides a real working URL for bookmarks & history. Links can then be made as they always were, without hashes & hash-bangs.

As of today, if you load Facebook in an older browser, you'll see the hash-bangs, but a current browser will demonstrate the use of pushstate.

TRiG
  • 10,148
  • 7
  • 57
  • 107
Billbad
  • 17,651
  • 2
  • 21
  • 17
  • 3
    awesome answer ! i have been browsing internet for the last 1 hr to understand the whole concept and you explained it so well. – Rishul Matta Jun 06 '14 at 06:37
  • 4
    It's not obsolete. Notably if you have a (literal) single page app changing a url won't work. You have to setup your web server to wildcard all requests to a single page behind the scenes. – Caleb Oct 11 '14 at 17:17
  • @Caleb This is very, very important, and I always read things like "hashbangs are dead", but often everyone overlooks that little detail. – user4052054 May 02 '17 at 04:47
2

You might wanna check out more on Unique URLs.

It's loading the page via AJAX, and parsing the "hash" (the values that come after the "#") to determine which page it's going to load. Also, this method is used due to the nature that AJAX requests don't count to the browser's history thus the "back button breaks". But the browser does however store into history the hash changes.

Using hashes plus the fact that you can use hashes to determine pages, you can say that you can keep AJAX requested pages "in history". Added to that, hashed URLs are just URLs, and they are bookmarkable including the hash, so you can also bookmark AJAX requested pages.

Joseph
  • 117,725
  • 30
  • 181
  • 234
  • What about how Twitter has the /#!/ URL path? That only adds the #. Also, is there a live example of that? – ixchi Mar 31 '12 at 01:32
  • 1
    If you want a live example, just use Twitter. `window.location.hash` returns anything after "#" (including the hash) like `#!/i/connect` or `#!/i/discover`. Then you can use that string to determine what location you want loaded via AJAX. It depends on the site how they use the hash to determine where they go. There is no standard practice how to parse the data after the hash. In twitter's case, it starts parsing after the first `/`. only typing `/#!/` or `/#` just loads the home page. – Joseph Mar 31 '12 at 01:37
  • I'm looking at the code relating to window.location.has and have no idea what any of it means. `(function(){var a=document.getElementsByTagName("html")[0],b=window.location.hash.split("?")[0],c=b.match(/#/)&&b.replace(/#[!]?[\/]?/,"")!=="";c?a.className+=" remove-prerendered-content":(a.className+=" use-prerendered-content",a.getAttribute("data-nav-highlight-class-name")&&(a.className+=" "+a.getAttribute("data-nav-highlight-class-name")))})();` – ixchi Mar 31 '12 at 01:48
  • what it does is remove parameters (ones after a `?`), then removes the `/#!` or `/#`. then determines if it's to add a className of `pre-rendered content` , or `remove the pre-rendered content` to `html`, and gets a few classNames. that's about it. – Joseph Mar 31 '12 at 01:59