I'm not here to say which is right or which is wrong. I think the progressive enhancement folks have made a very good case, and if your top concerns are accessibility or search engine indexability, you will have a rocky road ahead with a single page application. Meanwhile, single page applications exist, and HTML5 is starting to provide mechanisms to make these application sites more accessible, and browsers are beginning to implement them. Gmail has been a single-page application for years, and they completely changed the email landscape with their application-in-browser style. This style of website-application-crossover is also being used in Google Reader, Facebook, and Twitter, with varying levels of success and persistence.
Developers have embraced REST as a mechanism for getting content, while having a bit of a blind eye to the fact that REST is often used to create the single page applications that directly contradict their recommendations for progressive enhancements. (Certainly it's not the only thing to do with JSON, but it's just so darn fast to get up and running.) Even Github, the panacea of developer geekdom, has embedded this solution into their incredible source display. How lame would it be if you had to wait for the entire website page to load every time you wanted to change folders in your source repository?
I think it's high time to stop sticking up our collective noses at something that people clearly want, and start putting effort into understanding how to resolve some of the issues of single page applications, rather than just ignoring them.
So without further ado, (because there's been a lot of ado so far)
- How do we deal with indexability?
Fortunately these days the process of making a sitemap is standardized and straightforward. This (of course!) does mean that you need permalinks to access all these items in a SPA. Assuming you are using MVC, creating permalinks to your content should be straightforward. You will then probably want to have all those permalinks redirect to your index page and then deal with the permalink information as arguments to your application. Then you can use the "pushState" from HTML5 to push that permalink right back into the URL bar, so that any time your user looks at his URL bar, it represents the actual content that he is viewing. This way, if he copies the url to send it to his friend, the friend gets the content, not just your SPA home view.
It's easy to ship this sitemap to search engines these days. Just add a reference to your sitemap in your robots.txt. Done.
- How do we deal with accessibility?
From a user perspective, we have the capability now to push a URL to the URL bar. So in your OnClick function, you should also include a call that pushes the permalink URL to the URL bar for the user. Then, to get the visited class active, you should set the target of the link to that permalink URL. This way, if the user wants, they can right-click your link (which is also a JS function!) and open that item in a new tab. They can also see the visited link activate since the URL you've pushed to the history matches the URL in the href. You can see an example of this principle in action with this JSFiddle. (Thanks to Benson Kalahar for help getting this example working correctly.)