Embedding Discourse Comments via Javascript


(Carlo) #231

Hi everyone, and thanks for this amazing feature.

I’m already using the javascript embed on my website, and it works great so far…
…Yet, I believe I have noticed a bug on the mobile/smartphone version.

It seems that because of height issues, the button “continue discussion on the forum” is not display.

Anyone else having the same issue here ?

Desktop version:

Mobile version:

(Carlo) #232

A quick ( and dirty fix ) would be to add

<iframe style="padding-bottom:20px:"....

But I believe I don’t have access to that through customisation ?

(Christoph Holtermann) #233

Hello @hellekin, thanks for the rescue from the 90s !

I checked your suggestion and found that it does not completely satisfy my question.
I didn’t think of the problem of the iframe not having been initialized in the DOM. With your code I can check if this has happened. But my question arises after the iframe has been 1) put into the DOM and 2) initially loaded. In that state it shows “Loading comments…” (I guess because mine speaks german). This is the time I want to entertain the people in because if it is a new page on my website discourse needs to create a new thread and that may take some seconds. At last (3) the iframe will show “start discussion”.

Looking at the source of embed.js (discourse/embed.js at master · discourse/discourse · GitHub) I found that messages are being sent.

Logging the events I could capture I find that state 2 and state 3 both go with a signal “loaded” of the iframe and a message of type “discourse-resize”. Actually the load signal and the resize message get repeatedly being resent every 30 seconds until “start discussion” appears. [So if I don’t get that signals for one minute I could assume things are finally loaded]

So from the outside I can’t tell which state the iframe is in. I may even miss the first onLoad because I can’t put it into embed.js where the handler should be initialized in.

It seems that it would be helpful if the embedded code would not only sent a message about resizing but also ones about the state of the iframe. Just two messages “discussion-loading” and “discussion-loaded” would be nice. That could quite easily be done in discourse/embed.html.erb at 10f2db67baba9850d69d736b181837e19651a3f6 · discourse/discourse · GitHub. This is where the other messages originate.

Maybe there’s another way and someone can tell me ?

window.addEventListener('message', function(e) { console.log("window message", e); }, false); 
lastload = Date.now();
var dc = document.getElementById('discourse-comments')
var watch = window.setInterval(function() {
    var iframe = dc.firstChild     // this is your 'jQuery("#discourse-embed-frame")'
    if (iframe !== null) {         // iframe has loaded
        iframe.addEventListener('load', function() { lastload = Date.now(); console.log("iframe loaded", lastload); }, false);
        clearInterval(watch)       // remove this interval!
        console.log("iframe is ready")
    } else {                        // the XHR is still running
        console.log("comments are not loaded yet - iframe not yet initialised") // waiting for state 1 and 2
}, 10);

var watch2 = window.setInterval(function() {
    var iframe = dc.firstChild     // this is your 'jQuery("#discourse-embed-frame")'
    if (iframe !== null) {         // iframe has loaded
        time_passed = Date.now() - lastload;
        console.log("lastload", time_passed);
        if (time_passed > 30000) { 
            console.log("discourse loaded");
           // STOP ENTERTAINING HERE, state 3 reached
        }  else {                        
            console.log("comments are not loaded yet - discussion loading") // waiting for state 3
}, 30000);

This works, but there is a delay up to 30 seconds.

Edit: I applied the idea of sending state information in this pull request: Include information about iframe state in message by c-holtermann · Pull Request #5276 · discourse/discourse · GitHub.

Having established such a signal the code on the embedding page could be as simple as

function check_discourse_message_loaded(message) {
        if (message.data.state != null) {
                if (message.data.state == "loaded") {
                        console.log("discourse loaded");
                        discourse_loaded = true;
                        // STOP ENTERTAINMENT
window.addEventListener('message', function(message) { check_discourse_message_loaded(message); }, false);

(Paul Solt) #234

I can’t seem to get this to work . . .

  1. Problem: I got it working for a static URL, but the content is all squished on Ghost. Any ideas why it’s squished?
<script type="text/javascript">
  DiscourseEmbed = { discourseUrl: 'http://community.supereasyapps.com/',
                     discourseEmbedUrl: 'http://blog.supereasyapps.com/test-comments/' };

  (function() {
    var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
    d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);

  1. Problem: I can’t figure out how to get the page number auto generated. Is my page url code wrong? How do I see the real value it generates?

I’m using the page format discourseEmbedUrl = "http://blog.supereasyapps.com/{{url}}"; (but I don’t really know what I’m doing here … )

Post: http://blog.supereasyapps.com/discourse-comments/

<div id='discourse-comments'></div>

<script type="text/javascript">
    var discourseUrl = "http://commmunity.supereasyapps.com/",
        discourseEmbedUrl = "http://blog.supereasyapps.com/{{url}}";
(function() {
    var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
    d.src = discourseUrl + 'javascripts/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);

Super Easy Apps Discourse: http://community.supereasyapps.com

Ghost Blog: http://blog.supereasyapps.com/

I just see in Safari debugger (but I don’t understand what to do to fix it).

Failed to load resource: A server with the specified hostname could not be found.

Note: Originally I was stuck on the “Loading Discussion…” issue. The solution was to set the user to my account (i.e.: PaulSolt) Otherwise it never loaded anything.

(Allan Stromfeldt Christensen) #235

I’ve successfully integrated Discourse into a Ghost blog (was surprisingly easy!) and am curious if it’s possible to grab the comment count of topics/posts for the homepage.

I’m using the Eston theme whose default was set up for Disqus but which was easy enough to substitute in Discourse instead. One Disqus feature that Eston comes with is the ability to display comment count numbers on the front page (where only excerpts of blog posts are shown, and Discourse/Disqus isn’t even loaded). You can see how it looks via the Eston link above or on the PNG below:

Screenshot-2017-11-4 Eston

Is there some kind of functionality I can use to grab those comment count numbers from Discourse for their respective blog posts on the front page of the blog?


Using this script, it’s pulling down Google Analytics a second time (my blog already pulls it down once).

Any way to prevent this and lower the number of requests to the bare minimum possible?


Embed Request: Option to NOT Load Google Analytics or Other Unnecessary Scripts in the Embedded iFrame JS

Here’s what I’m doing. Many will disagree for huge sites, but it works:

I wrote a script to query the Discourse side for all posts and count the total number of comments. I then save that number in a custom field for the post. And then my child theme uses that number instead of the default comment count to display the number of comments.

And then I run the script every 2 hours in cron. It hammers the API with n*12 hits every day, but it doesn’t slow site load times and is relatively accurate.

(Allan Stromfeldt Christensen) #239

Interesting! I certainly don’t have a huge site, just a blog on the smaller side of the spectrum. Any chance you have a copy of that script up on GitHub or something where I could take a look at it and possibly use it for my blog?


Sure thing:

Going through this just made me realize that I have a few custom post types that aren’t getting updated here, it’s only updating post type. Will have to update this later today.

This is a hybrid solution between WP-Discourse plugin and this JS script everyone’s using in this thread here. I like WP-Discourse’s ability to post INTO discourse, I just don’t want it to pull the actual comments into WP’s commenting system (as this script displays them better with replies and stuff).


Regarding this, I’ve simply disabled Google Analytics for this site in the official Admin area, and pasted my Analytics code in the header of the site (common area for both mobile/desktop).

Now Google Analytics is not called in embedded situations and my overall stats aren’t doubled between the two subdomains/sites.

I’ll be putting in a feature request to disable Google Analytics for the embed script.

Disabling Google Analytics while embedding discourse as comments
(Allan Stromfeldt Christensen) #242

Awesome, thanks for that. I don’t actually know JavaScript, but once I find somebody who can adapt that script for my Ghost blog (rather than WordPress blog) I’ll throw a link to the coding up here as well for anybody who might have a need for it.

(Carlo) #243

For the people having the same issue, it is actually ( and again ) a Cloudflare bug…

(Carlo) #244

Hi everyone.

I am having trouble integrating embedded comments when the subfolder has latin characters.

I manage a website in Portuguese, and this is what I get:

For a domain like: domain.com/definição/url.html


The referer did not match any of the following hosts:

I have tried both:

www. domain.com.br/definição/*
www. domain.com.br/defini%C3%A7%C3%A3o/.*

But with no luck so far. Has anyone encounter the same issue ?


(Jeff Atwood) #245

Hmm that seems like it might be a bug, perhaps @gerhard could have a look next week?

(Carlo) #246

I’ve managed to do it with the referer set to /defini.*.
It works, but it is not ideal :thinking:

(Quintin Par) #247

Please please add this to the topic post. For the longest time,I didn’t understand what the Class Name meant until I bumped into this serendipitously.

(Robin Ward) #248

Sure, good suggestion. I’ve updated the OP.

(Quim Gil) #249

Hi, this is a great feature and I am trying to deploy it in our Discourse instance. Thank you very much!

There is something that I am trying to understand: different hosts can be allowed but apparently only one RSS feed and one username for topic creation can be defined?

I would expect that each allowed host has their own settings, but I cannot find the way to define this. The use case is to have different blogs (with their own username and RSS feed each) sharing a discussion space in a Discourse instance.

Let’s say that having a popular blog post about niche_Topic is very hard and many posts get almost zero comments, but if a dozen blogs about that niche topic agree on sharing their discussion space in a Discourse instance about that very same niche_Topic then the chances to increase participation are higher. This is exactly what we are aiming to do in our site right now.

Embedding: one RSS feed for each host
(Quim Gil) #250

If the feature described above is missing but it would be welcomed, a new topic could be created to discuss it. I would even consider funding the development of this feature because, as said, our project partially relies on something like this.

(Arpit Jalan) #251

Done via: