I am building a single page application (SPA) using Durandal JS (with ServiceStack powered API layer). In one of the sections I wanted to have DISQUS discussion integrated. This blog post outlines problems I faced and solution to the problem I found.
In a normal web site, integration of DISQUS to your pages is easy, you sign up for DISQUS, get the JavaScript Universal Code for web sites, add it where you want your discussion thread to show up in your page. When web page loads, DISQUS loads the required Javascript and adds it to the section of your page. By default DISQUS will use the page url as the key to the discussion and manages unique thread ids for your posts and replies within that.
Now with this model we have a problem, in a SPA, there is no “pages” its all one “single” page with routes (by some convention) managing the loading of various views. So if you simply paste DISQUS code where you want the discussion to show up in your SPA view html page, result will be disappointing! At least it was for me the first time. Again to my defense, it was late in the night and I was not thinking clearly. When the page ran, it did not load anything…blank! Problem is that if you add a JS snippet to your view code, its not going to work in a SPA architecture.
Solution
We need to load the required JavaScript file just like you load any other piece of code that is required by your application. Here is how you do it…
function initDisqus() {
window.disqus_shortname = 'your-app-name';
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + window.disqus_shortname + '.disqus.com/embed.js';
$.getScript(dsq.src)
.done(function () {
//
});
}
This works, well mostly…If you run your page now, you will see your discussion initialized on the page. And you can start adding comments, I was happy to get to this point, and soon realized that all the comments were getting added to the root of the site, and if you reload the page, DISQUS failed to attach the comments back to this discussion. All those comments were kinda orphaned. Soon I realized that the presence of ‘#’ (hash) in my url is also messing up with how DISQUS works!! If you have a URL like http://www.mysite.com/#/blog/my-first-blog, DISQUS does not treat anything after the ‘#” as part of your Url and attaches the thread id after the ‘#’.
So what do you do? One way (at least what I think) is to change ‘#’ to ‘#!’, for example, the URL given before will change to http://www.mysite.com/#!/blog/my-first-blog. Durandal did not complain and loads the page, and DISQUS seems to like it too. One another thing you will need to do is to reload DISQUS every time your new view loads with new unique identifier for the page and the link. This way all the discussions that happens will be tracked under your unique view (urls).
More complete solution:
function initDisqus() {
window.disqus_shortname = 'your-app-name';
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + window.disqus_shortname + '.disqus.com/embed.js';
$.getScript(dsq.src)
.done(function () {
DISQUS.reset({
reload: true,
config: function () {
this.page.identifier = window.location.href;
this.page.url = window.location.href;
}
});
});
}
Note: Make sure to call this function from your “viewAttached” within your view model code.
That’s all for now folks, Happy programming!
Cheers!
Binu







Recent Comments