Multiple DISQUS threads on one page

Recently, I came around a problem with the Disqus comment system while fixing a random WordPress theme. The theme had individual blog posts where the Disqus module loaded as intended, but the top level blog listing (blog homepage so to say), which pulled 3 full posts per page, seemed to load only the default WordPress comments.

I took a nosedive at the issue (read: visited Stack Overflow and queried Google) and realized it’s a relatively known problem, but the prime solution on collaborable.com that everyone was pointing to was gone (no web archive, no google cache, thing just went poof). So I fired off some tribal hipsterstep and entered the DOM swamp.

First of all, let’s say why multiple modules on a page are a deal breaker. Disqus uses global variables for itself and it’s configuration (window.DISQUS, disqus_identifier, disqus_url, disqus_shortname,…) and plants itself into a unique id “disqus_thread” element. That’s not an entirely kosher situation in regard to the intention of loading multiple at the same time. The problem at hand is therefore loading the Disqus module with the unique page identifier and not loading more than one on a single page at a time as the DOM would implode. I realized a solution can be achieved in 2 ways with different results:

  • Load the Disqus threads in iframes under each post and somehow control the iframe height so it matches the Disqus height, including a height refresh on certain events (like new comment). This would practically enable multiple threads on one page visible at a time thanks to the iframes. I chose not to pursue this solution however as it feels problematic, but there are people who did. http://blog.devinterface.com/2012/01/how-to-insert-more-disqus-box-in-single-page/
  • Create some sort of “show comments” control under each post that would load the relevant module and display it. Once a different control was clicked, the HTML would move to the new location and DISQUS would be reloaded with new parameters. This article will further expand on this idea.
    Important: This is not possible to do in a clean way using the 2012 version of Disqus, as it misses the DISQUS.reset() method as of the time of writing this article. You must switch to the old version to use the reset() method or rewrite your script in a different way (cleaning the DOM/HTML of Disqus manually).

Let’s start with the control set for loading the Disqus module in a form of a “show comments” link below each individual post that would point to some function outside and pass all the necessary attributes for loading Disqus for the first time or resetting it with new parameters if it was already loaded. Mind me using jQuery for some simplified DOM manipulation and more importantly, mind the post id and guid used as the identifier (WordPress stored the original page url in case it changes for various reasons and Disqus uses it to identify the original content it belongs to) – the following code will therefore only work if you’re using the Disqus WordPress plugin as it will use the internal guid, not pretty permalinks. You can of course manually adjust the parameters if you’re using a different system or static pages. With regards to your specific blog template listing loop, something like this will do.

<div class="this-is-single-post-wrapper">

   <!-- this part will likely contain individual post data -->

   <a onclick="loadDisqus(jQuery(this), '<?= $id ?> <?= $post->guid ?>', '<? the_permalink() ?>');">
      Show comments
   </a>
</div>

Armed with the controls, let’s create a generic outside function that seals the deal. Put that in a file somewhere, in the page header or anywhere you like.

var disqus_shortname = 'yoursiteshortnameindisqus';
var disqus_identifier; //made of post id and guid
var disqus_url; //post permalink

function loadDisqus(source, identifier, url) {

if (window.DISQUS) {

   jQuery('#disqus_thread').insertAfter(source); //append the HTML after the link

   //if Disqus exists, call it's reset method with new parameters
   DISQUS.reset({
      reload: true,
      config: function () {
      this.page.identifier = identifier;
      this.page.url = url;
      }
   });

} else {

   //insert a wrapper in HTML after the relevant "show comments" link
   jQuery('<div id="disqus_thread"></div>').insertAfter(source);
   disqus_identifier = identifier; //set the identifier argument
   disqus_url = url; //set the permalink argument

   //append the Disqus embed script to HTML
   var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
   dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
   jQuery('head').append(dsq);

}
};

That’s pretty much it.

  • Chelsea Medley

    Can any one please tell that why did not I get line id for every identifier. I a while get this mistake Code=2 “Invalid discussion, ‘thread’: Not able to discover thread

    HCG Rezepte

  • Great post. But lately my disqus started creating new threads for every blog post I visit. Not showing previous comments :(

  • nzt123

    Can any one please tell that why did not I get thread id for every identifier. I some time get this error Code=2 “Invalid argument, ‘thread’: Unable to find thread

  • bkash

    only problem tho is that it loads the same comments on every thread. can someone here figure out how will that work? im really new in this.

  • elexes

    im making an application and this was very helpful so thanks so much! my only problem tho is that it loads the same comments on every thread. can someone here figure out how will that work? im really new in this.

  • www.kuhnishkaf.ru

    very thanks

  • Alpha0007

    how to make it open in an external window/popup window ?

  • chirisdex

    I took a nosedive at the issue (read: frequented Collection Flood and queried Google) and noticed it’s a relatively known issue, but the primary remedy on collaborable.com that everyone was directing to was gone (no web database, no search engines storage cache, factor just went poof). So I shot off some tribe hipsterstep and joined the DOM swamp.

    Spybubble gratuit

  • Phillius Thomas

    You can do this on windows? That is amazing.

  • This works great!

    …accept, it doesn’t work when using Disqus Single Sign-On. Any clue how to get that rolling?

    • mystrdat

      From the documentation, it seems like SSO requires a bit deeper integration than just a js file (seems like you communicate directly with their API instead of a premade front-end widget). If that’s correct, you can customize the implementation in any way you want, so the code here becomes rather meaningless.

  • Anthony Wallace

    So I’ve got the script to work correctly. Everything toggles, but the same comment form appears for each post. The links in the guid within the source is displayed correctly so I’m not sure exactly what the problem is. Here is the link to the page where you can see it happening. Any help is very much appreciated!

    http://howheasked.com/proposal-ideas

    • Anthony Wallace

      Ok I’ve figured it out after messing around a bit. I’m not sure if anything has changed with Disqus but in the onClick we need to change the guid ?> to . Once I figured that out the correct comments was displayed. Thanks so much for this script as its save me sooooo much time!!

      • Anthony Wallace

        Sorry I just realized that I can’t put code in here lol. But pretty much we need to remove the post->guid and replace that with the_permalink. Thats how I was able to make this work correctly. Thanks!

  • Kat

    Awesome! Thanks so much, was about to begin banging my head repeatedly on the monitor!

  • Guest

    Hi, I’ve tried your snippet, but i when i click to open the thread it starts do load ferever and asks to reolead. Do you have any ideas of what could be happening?

    • Chip

      Probably your disqus_identifier is incorrect

    • mystrdat

      Not from such a vague description, a link would help.

  • webspot

    Thanks very nice article yes I used it with reset it is working prefect. ;)

  • I faced an issue and e-mailed to Disqus about this. They confirmed
    that by default they only support one Disqus module per page.

    • mystrdat

      Well, yes. That’s why I wrote this in the first place.

  • tinytouchtales

    hey great thing! was sitting the whole evening to get this to work! was super puzzled why its not working until i found out that jquery 2.0.0 has an error somewhere, when i used version 1.9.1 everything worked …

  • reallycreepykids

    damn sexy, thanks!

  • I need to use this technique on another CMS that doesn’t have a plug-in. I think I can figure out the script part, but the “onclick” part that loads the parameters is confusing me since I’m not familiar with PHP. Does anyone have ideas on how to change this to work outside of WordPress?

    • mystrdat

      Onclick is a JavaScript event on the front-end, no PHP involved there.

  • I was trying to get Disqus on my index.php for hours now. THANK YOU for those code snippets. Did the job in less than 2 Minutes.
    So – thanks for sharing :-)

  • heshiyou

    Nice solution!!!

  • Thanks for this walk-thru. I was able to get Disqus 2012 working on my single-page app. I’m still getting an error of:

    Uncaught TypeError: Cannot call method ‘postMessage’ of null

    Again, everything seems to work just fine, I’m just seeing this error in the console log. Any idea on why this is happening?

    Thanks!

    • mystrdat

      I could take a look if you give me the URL, sounds like some inter-frame call messing up, could be Disqus as it’s iframe loaded.

  • I actually get this one finished to use for other pages.
    AMS1117

  • jrefano

    great info here on the undocumented DISQUS.reset() method. i was re-adding the script to the page but that was causing problems (most noticably, the iframe wasnt aware of my logged in user anymore). thanks much

  • Please, It didnt work for me, Help pls. I pasted the code on my page and inserted the name of my app on disqus but it didnt load it.

    • mystrdat

      Some parts of the code depend on your specific template and the theme you’re using. Exactly which part doesn’t work? Post some details please.

  • I applied on my blog, but the same code can be applied on all pages…

    • mystrdat

      I don’t understand your point, please try to specify the issue (if there is any).

  • animalnots

    did someone got that working easily? Can someone explain what does  $id, $post->guid and the_permalink() look like? Why you need 2 ids , id and guid.
    I just have a page that loads posts with jquery and trying to add comments after that post. No page reload is available.
    PS: Clicking on show comments is working and its toogling but comments are the same for all posts.
    PS2: Anchors look like :
    loadDisqus(jQuery(this), ‘cont_desc1851’, ‘h tt p //example. org/somepage.php?#tooglepost_1851’)
    cont_desc_number is changing, as well as #tooglepost_number

    • mystrdat

      The id, guid and permalink strings shown here are what the Disqus WordPress plugin generates for each post/page. If you didn’t use the same structure, comments on individual articles would use a different Disqus instance (eg. displaying different comments). If you used this outside WordPress on your own, the structure would be different.

      PS: That’s good, means the JS is working.
      PS2: I would blame your template for generating a different structure (looks broken), try debugging if the vars are available in your loop.
      PS3: Could you be using some “SEO” plugin that would overwrite the permalink in db? Try to go to an individual post page and checking what the disqus_identifier and disqus_url variables show in JS console. Those need to be the same as those that are output from your listing loop.
      PS4: I would argue that’s because the element is not displayed at the time when Disqus is trying to load inside of it, could be solved by correct timing. Console should show that as an error, check for it.

      • animalnots

        Crap, everything seems to be working smoothly now, even in ff. I don’t understand ), hope that was a reload pages bug ).
        About permalinks structure same, no actual structure is required. So about templates (ps2) what’s wrong with that? Why don’t you like it? Moreover i just tried a few experiments and found out that only first and second arguments matter. So 
        loadDisqus(jQuery(this), ‘cont_desc1851’, ‘somesite/somepage.php?#tooglepost_1851’) 
        and
        loadDisqus(jQuery(this), ‘cont_desc1851’, ”) 
        are identical for me (same result in both cases and everything works. As far as I learnt – Only a unique id is required to tell one “page” from the other and that key is the second argument.

        • mystrdat

          I haven’t really dug as much into Disqus to know that eventually only the id matters, which is nice. If it works now, I have no objections, just that my initial impression seemed to be that the ids are not generated properly.

          • animalnots

            Ids are unique, they seem fine and ok.  Disqus stats? They may use those ids for stats as well. I just noticed the disqus admin records url pretty well (I think it’s getting them from click on anchors (therefore from a.hrefs))
            What stats do u mean?

          • mystrdat

            What I mean is that it’s likely the url isn’t passed to Disqus for just shits n’ giggles, there must be a reason for it to be there. I don’t intend to dig for that knowledge though, not very interested in it.

  • wired420

    So I’m trying to use this on my page. I’m pretty sure it’s just something dumb I have done. So I’ll outline what I’ve done here and maybe you can point me in the right direction. I’m kind of new and doing this as a learning tool for one of my classes.

    So here’s what I have done.

    <script type="text/javascript" src="/js/disqus.js” >

    is loaded in my header between the head tags with the other js scripts. In this file is the second piece of code from up top.

    Here is the template file. I’m trying to add it in the loop so it shows up under each post. 

    http://pastie.org/5352857

    My first template for wordpress ever. Still learning about word press. I know its kind of messy, haven’t bothered lining it up as every time I do I screw it all up again. Will bother with that when I actually get this one finished to use for other pages.

    • mystrdat

      When you open the generated HTML code (just go to the page) and check the “show comments” link in web inspector/firebug or whatever you’re using, does it render the correct arguements for the onclick function call? Can you paste the code inside of it?

      • wired420

        appears to,

        ’45 website/?p=45′, ‘permalink in correct structure’

        each has the correct id and perma link
        assuming from the code that is what it supposed to look like? I’ve tried it with 2012 on and 2012 off. Doesn’t appear to load the jQuery function either way though I do have the latest jQuery in for other things.

      • wired420

         http://pastie.org/private/lmypqfo82famfhbryegq

        This is how it shows up each time. Each time it has the correct id’s and links.

        This
        is where the second piece of code you have up there loads in the header
        as I’ll be using this on different pages if I can get it to work.

        • mystrdat

          Check the console, you have a syntax error in the script and the loadDisqus function is therefore unavailable in the global scope when called.

          • wired420

            Not exactly sure what you mean here by console. I’ve copy pasted the code exactly minus taking out the div that was supposed to represent my post content. Only thing I changed in the second piece of code was the short name. For good measure I’ve copied both exactly again, and even copy pasted another line I know is working and just modified the file name to match the file I stored the script in. See no errors in the web server logs anymore either.

            All other scripts work. It now validates as 100% XHTML/CSS. Firebug doesn’t bring any errors to light. I’ve tried with 2012 on and off again. I’m at a complete loss. I even changed it from disqus.js to multithread.js in case it was causing an error by the file name. If you have no other suggestions, guess I’ll give up on it for a day or two and come back with fresh eyes and hopefully able to resolve it then.

          • mystrdat

            It seems to be gone now, the function is registered. There shouldn’t be a problem anymore, but I can’t see you using the link in the listing. If you want, I’m on GTalk now as mystrdat@gmail.com, so I can help you real-time, it should be just a quickie.

  • play ninja hattori games free

    The New York Stock Exchange
    said it will be shut down Monday, including electronic trading. Nasdaq
    is shutting the Nasdaq Stock Market and other U.S. exchanges and markets
    it owns, although its exchanges outside the U.S. will operate as
    scheduled.

  • labmassiv

     Does the second part of your code need to be adding inside some other code? beacuse when I add it as it shows above to index.php it shows up as text and doesn’t execute.

    • mystrdat

      It’s JavaScript, wrap it in tags if you want to use it straight on the page or put it in a .js file and use somewhere on the page.

  • vmrhudson

    Supposedly as of 17 July 2012, Disqus 2012 now supports “reset” again.

    • mystrdat

      Nice, appreciate the info.