title: What is the right way to do client-side routing on a single-page-app?
body: <p>I am creating a single-page-app (SPA) on my local machine, but a few levels down from the document root. So, for example, my index page would be at <code>http://localhost/projects/foo/index.html</code>.</p>
  
  <p>I'm using <a href="http://davisjs.com/" rel="nofollow">Davis.js</a> to do client-side routing with the history API, and it recommends using absolute URLs for its routes. E.g. <code>&lt;a href="/hello/world"&gt;</code> triggers the <code>/hello/world</code> route.</p>
  
  <p>This is a problem, because when you click that link residing on <code>http://localhost/projects/foo/index.html</code>, it changes the URL to <code>http://localhost/hello/world</code>, which is obviously not right, even though the app continues on like normal (because you never actually left the page). Refresh the page, though, and you'll get a 404 error, because the file <code>http://localhost/hello/world</code> doesn't exist.</p>
  
  <p>Using relative links, like <code>&lt;a href="hello/world"&gt;</code> gets closer to the mark. Clicking that link changes the URL to <code>http://localhost/projects/foo/hello/world</code>, but does <em>not</em> trigger the <code>/hello/world</code> route. Click that same link again, and you'll find yourself at <code>http://localhost/projects/foo/hello/hello/world</code> (double hello). Again, not desired behavior.</p>
  
  <p>Now, what's going on is that Davis is matching routes from the root of the domain, so <code>/hello/world</code> will only trigger when the url is <code>http://somewhere.tld/hello/world</code>. But even if I was serving directly out of the document root, there's still the problem that <code>/hello/world</code> <em>doesn't actually exist</em>.</p>
  
  <p>At the moment, my current solution is forcing Davis to use hash-based routing instead of path-based: <code>http://localhost/projects/foo/index.html#/hello/world</code>. This works 100% as expected, because the browser will always load <code>index.html</code> and Davis will always see the <code>/hello/world</code>. Additionally, links containing that hash fragment will always work, provided the user has Javascript turned on. (I'm not worried about that case)</p>
  
  <p>One solution I can see is to have a base URL of <code>http://localhost/projects/foo/</code>, have a server rewrite all requests in that directory to <code>index.html</code>, and have all links and routes point to and match the base url + fragment (like <code>http://localhost/projects/foo/hello/world</code>). So technically, all those URLs <em>do</em> exist, they just all point to the same file. This, however, requires that <strong>(a)</strong> a server capable of URL-rewriting serves the SPA (the url-hash solution doesn't even require a server, just a browser) and <strong>(b)</strong> the SPA keep track of "where" it is relative to the document root (which to me is a <em>very</em> bad thing).</p>
  
  <p>So my question is, what is the <strong>right</strong> way to do client-side routing, agnostic to the app's location on the server, and preferably without requiring server-side technology other than static hosting.</p>