Deep Linking + Browser History Navigation in Silverlight
Deep linking is a strange term and the first time I heard it was while I was giving a talk. Someone asked me if Silverlight supported deep linking and I sort stumbled around until I found my way to a big “I don’t know.” Well, now I do and the answer is, um, kind of. Technically, it’s a no, but, as with most things, there is always a way. Last week I spent a couple of evenings trying to track one down.
What do you mean by deep linking?
Before we jump into solutions, here’s the skinny on deep linking for newbies (like me): on a traditional web site, the URL in the browser is pretty closely correlated to the content you’re viewing. If you click on the about link on somepage.com, for example, you would likely go to http://www.somepage.com/about. That link directly identifies that content. In a Silverlight (or Flash, or AJAX) application, on the other hand, the content is often being loaded by some other container so the URL never changes. Deep linking is the idea that you somehow embed navigation directives into the URL to the application so that the content in the application is tied to the browser URL. This is handy for letting people copy or bookmark links, keep track of where they are, etc.
Usually this is done with a bookmark, the part of a URL that comes after a pound (#) sign to indicate some content area within the page. So if our about example were using this technique, we would get http://www.somepage.com/#about.
The companion to deep linking (and the more difficult technical challenge) is getting deep links to work with the browser’s navigation history. In other words, every time the URL changes in the browser you would ideally generate a new entry into the browser history. That way, when someone hits back and forth in the browser, they navigate within the app.
So how do you do it in Silverlight?
Great question and exactly the one on my mind last week. Turns out that there are already a handful of solutions out there. For starters, there is a commercial solution included in Telerik’s Silverlight control suite and in a very cool example of openness, someone at Telerik also blogged about a solution (using the ASP.NET script manager). I found another intriguing example from Asual, the guys who created SWFAddress (which appears to be a favorite Flash/AJAX solution) called .NETAddress. They have a great sample but it seems to have gone a little stale.
No, how do you do it in Silverlight?
Those are just a couple of at least half a dozen different solutions to this. As I moved through them, I kept hitting issues: browser compatibility, an unwanted ASP.NET dependency, etc. In spite of a lot of interest, I couldn’t find a solution that would fit the bill. I even tried writing my own (based on this helpful sample from Mark Rideout) but quickly found myself sinking in a swamp of browser compatibility issues.
Like I mentioned before, it turns out that lots of people are solving the same problem for AJAX and Flash and so, in the end, I decided to take a jQuery dependency. I’m really pleased with this solution. I wrapped a jQuery plugin (jQuery.history) that handles deep linking and the navigation history like a dream. The jQuery dependency is a much smaller price to pay than an ASP.NET dependency. Moreover, the library is fast, reliable, and someone else has already done the browser compat work. Nice!
Using the jQuery.History Wrapper
The wrapper is really straightforward. The only friction you may feel is inherent in the deeplinking problem itself: your navigation logic will need to be centralized and much less deterministic (i.e. you can be asked to navigate from anywhere to anywhere at any time). Here’s how to get up and running.
First, include jQuery and jQuery.history in the page that hosts your Silverlight:
<script type="text/javascript" src="scripts/jquery-1.2.6.js" /> <script type="text/javascript" src="scripts/jquery.history.js" />
Next, include jQueryHistoryHelper.cs somewhere in your Silverlight project and then establish an event handler for the static NavigationRequested event on the jQueryHistoryHelper object.
jQueryHistoryHelper.NavigationRequested +=
new NavigationRequestedEventHandler(jQueryHistoryHelper_NavigationRequested);
In the handler for this event, you’ll write the code to handle all of the navigation for the app. You have access to the new and the old bookmarks and you can write whatever ninja code you care to for handling that change.
void jQueryHistoryHelper_NavigationRequested(object sender, NavigationRequestedEventArgs fe) { // handle the navigation here switch (fe.NewBookMark) { case "Awesome": // do something awesome break; // etc. } }
Finally, to request a navigation yourself just call the static method called Navigate on the jQueryHistoryHelper object. You pass in a string, the new boorkmark to which you want to navigate. This will update the URL, generate a NavigationRequested event and add an entry to the browser’s history.
jQueryHistoryHelper.Navigate(r.Content.ToString())
Example
Hopefully this is helpful. You can see an example of this here. The code for the example is available from the labs page. If you just want the C# file for the wrapper, you can get that there too.
Finally, this example showcases a bunch of photos that were shot using a technique called tilt shifting in which you simulate a focus depth which would normally only be available at really short distances. The result is that normal scenes begin to look like models. It’s like the inverse of 1970’s special effects (don’t believe me? check out Superman II). The images have a fake depth to them, just like the links… get it?

Kurt Brockett
21 jan 2009
Was hoping this would come to your blog. As part of the work I want to do on identitymine.com some of it revolves around sales purposes, meaning being able to route things from an arbitrary link, say identitymine.com/surface or identitymine.com/ and I wasn’t sure how that would work with a SL project portfolio. Now I know. Thanks for sharing.
AussieInSeattle
21 jan 2009
Great article – jQuery to the rescue again! I’ll be using the concepts ona project I’m currently working on.
I’ve been fascinated by TiltShift too – check out http://www.tiltshiftmaker.com which I’ve used to create a few of my own without having to purchase the super pricey camera lenses that you usually need.
Regards,
Matt
Karim Hernandez
21 jan 2009
I had once built a sample in Silverlight 2b1 using one of the popular solutions for flash, a javascript project called HistoryKeeper. It’s likely no better or worse than the JQuery solution, but at the time I wanted something that was self contained without the extraneous javascript functionality.
http://www.unfocus.com/projects/historykeeper/
Bryant Likes
22 jan 2009
Thanks for the example! Once I saw how easy this was I decided to add it to the project I’m working on. I tried to implement the callback instead of the timer and found it was a real pain so I ended up just using a timer. Works great!
Silverlight Deep Linking & Browser History with jQuery | WPF Dev
30 jan 2009
[...] Ingebretsen of NerdPlusArt has a well written piece on deep linking and browser history in Silverlight using [...]
Ida Smith
05 feb 2009
Cool! Important, too.
But your code doesn’t “work on my box” perfectly:
The history is double-entered on my IE8 Release Candidate 1 browser:
Starting on #Bench, I visit #Bus, #Hockey, #Joes, #Train in order.
Then I repeatedly hit back and here is my path back:
Starting from #Train, #Joes, #Train, #Joes, #Hockey, #Joes, #Hockey, #Bus, #Hockey, #Bus, #Bench, #Bus, #Bench.
Also, the forward button never lights up during this backward crawl.
ckaut
12 mar 2009
Try refresh (F5) the page in IE7. The back button will be disabled.
TCSWeekly Episode 003 - Silverlight, Moonlight, Kaxaml, Facebook, Multi-touch - AdamKinney.com
27 aug 2009
[...] Deep Linking + Browser History Navigation in Silverlight [...]