Embedding Discourse Comments via Javascript


(r3d_f0x) #213

Where do I go to check the header?

I already found it in Discourse. It’s unchecked so it should be disabled.

(Raphaël Jadot) #214

Thanks for this awesome plugin :thumbsup: working perfectly

Is it possible to replace the logo with a custom one (not necessarily logo_url)?

edit: in fact I’d like to use digest_logo_url instead…

edit2: I think I have found a way with this

(Raphaël Jadot) #215

Hello, sorry for this silly question:
What is the best way to troubleshoot this feature? Images are not imported in my case and I try to understand why, however I don’t see how to debug the process…

Thank you.

(Robin Ward) #216

What do you mean images weren’t imported? Do you mean when viewing the post in Discourse it is missing the images altogether, or that they are broken, or perhaps that Discourse is showing them but did not download them locally?

(Raphaël Jadot) #217

In fact it’s not showing them at all (after clicking “view full post” inside Discourse) but there is no visible “broken link image”, simply nothing; I think it’s because the rss feed import fails at some point, and then my instance is trying to parse html instead. Because of a serie of scripts modifying html on the fly for rendering adaptive images in the imported posts, I guess it may be quite hard for the parser. However, as I’m a free Discourse user I don’t want to take too much time from you, it’s why I’d like to troubleshoot as much as possible on my side (from logs or another way) but I’m not sure how to do it.

(Kevin) #218

I’m not shure if I’m doing something wrong, but creating a topic in Discourse from a new article seems to be a bit…buggy for me. I’ve filled out the Embedding Settings and Feed Settings correctly, but Discourse seems to ignore the Feed and the key and just crawls the whole article. Sometimes it then posts a second topic a few minutes later, using the Feed correctly, sometimes it doesn’t. With the latest article, it even seemed to first post the crawled version, before trying to edit the post with the content from the feed, masking itself as the user specified in the feed key? With…unsatisfactory results. And IF it uses the feed to create a topic, German Umlauts also seem to cause a small problem and are being replaced with a Numb (ö as ö), which doesn’t happen if it crawls the site.
Any help to fix these problems would be greatly appreciated, thank you in advance.

Edit: Most of these problems were related to SSL-issues or the feed generator of the CMS. However, Discourse still doesn’t assign the correct author sometimes.

(Michael Downey) #219

Hi, embedding newbie here. Can anyone explain to me how Class Name and Path Whitelist are used? The other stuff seems pretty self-explanatory, but I think maybe these fields are newer than the stuff written here in this topic.

Thanks in advance!

(Robin Ward) #220

Class Name is a class name that will be attached every time your iframe is rendered. You can use it for styling purposes.

Path Whitelist allows you to specify the paths on the remote host that would accept your embed.

(Michael Downey) #221

Makes sense. Thanks for the explanation!

(Sam Bryfczynski) #222

Has anyone had any luck embedding this into an Angular app? I can only get it to work for the root of my application (http://www.mydomain.com/MyAngularApp). But I can get it to work on any of the pages (http://www.mydomain.com/MyAngularApp/#/ExamplePage). Anyone have issues like this? Any suggestions? Thanks :slight_smile:

(Christoph Holtermann) #223

I’m embedding discourse and it loads new discussions for quite a while. I’d like to be able to know from the perspective of the embedding website when the discourse frame finished loading. It seems as if the onload event doesn’t work for showing when the discussion can be started. Is there a way to know if loading has finished ?
The background is putting some animation on top of the frame so that people don’t loose patience and know somethings happening.

(Kane York) #224

Have you tried listening to the iframe’s onload event?

It’ll be tricky since the iframe is inserted by the script, of course.

(Christoph Holtermann) #225

yes, that didn’t work.

jQuery("#discourse-embed-frame").on('load', function() { alert("X");});

I also tried readystatechange.

jQuery("#discourse-embed-frame").on('readystatechange', function() { alert("X");});

(Michael Downey) #226

Throwing this tip out there for folks that might be dynamically populating the value of discourseEmbedUrl, and getting random extra topics created when folks pass query strings to your pages.

If your documents to get the embedding are all .html files, for example, you’ll want to use something for the value of Path Whitelist along the lines of:


(Side note: No, this was not related to my earlier embedding problems just something else we ran across.)


Hi @Christoph_Holtermann, you should use console.log('X') instead. Alert is so 90s :slight_smile:

I guess your code is trying to get jQuery("#discourse-embed-frame") before it became available in the DOM. One way around it is to use its parent, e.g., if you have <div id="discourse-comments"></div>, then:

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
        clearInterval(watch)       // remove this interval!
        console.log("iframe is ready")
    } else {                        // the XHR is still running
        console.log("comments are not loaded yet")
        // Add stuff to distract your impatient readers :P 
}, 10);

I put a very short interval (10 ms) because in my case the iframe loads within 30 ms.


Nobody ever answered this question, but I’m at this crossroad here with my WordPress blog (WP-Discourse vs. Embedded) and would love any feedback.

Some pros of using this embedded iframe:

  1. No “duplicate content” in the search engine’s terms – It’s pretty clear that the Discourse side “owns” the content
  2. Ability to see who has replied to whom. The WP-Discourse plugin doesn’t show that (which is why I asked here and got sent into this thread.
  3. Less moving parts / reliance on PHP/WordPress…
  4. I can also use this on our non-WordPress pages
  5. Seems to be solid support in this thread.

Am I right in thinking this JS embed method is probably the way to go??


I have this exact same problem.

Setting discourseEmbedUrl hangs at “Loading Discussion...” but setting topicId works just fine.

I’ve set my X-Frame-Options’ => ‘ALLOW-FROM …’ options and restarted everything, but that didn’t help.

Nothing in my console log either.

I don’t see why one would work and the other wouldn’t. Is there a difference if I have access to both the Topic URL and the Topic ID? If not, I’ll just stick to the topicId method.

(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);