Embed Discourse comments on another website via Javascript

Is there a way to find the associated topic ID or discourse URL for a given page with discourse embedding? I’d like to provide the discourse URL for our schema.org discussionUrl json-ld that we include in our pages with embedded comments. E.g.,




1 Like

Yes, we have a dedicated API endpoint just for that. Here is an example:

curl 'https://meta.discourse.org/embed/info?embed_url=https://blog.discourse.org/2021/04/discourse-team-grows-to-50' -H 'API-KEY: logapikeygoeshere' -H 'API-USERNAME: apiusernamehere' 

And the response is:

  "topic_id": 187794,
  "post_id": 925017,
  "topic_slug": "discourse-team-grows-to-50-blog",
  "comment_count": 2

Good question, added it to the OP.


Hey all - I’ve been following this topic and trying to get a feel for how the “Imported topics will be unlisted until there is a reply.” function works –

Essentially I have embedded a discourse topic on a webpage sucessfully ----- but want to have the embedded page show all posts in the topic – not just replies to the original post

shouldn’t the “Imported topics will be unlisted until there is a reply.” do this? I’ve tried enabling / disabling this and the “truncate posts” option and don’t seem to notice a difference for either

–any pointers? Thanks in advance


update: I found this topic along with a discourse plugin written by @arivanandan (thank you!) – will attempt to implement and post update for posterity

update 2: Plugin works! Huge thanks again to @arivanandan!!



Is it possible to embed a summary of a user stats? ilke:


  • 240 days visited

  • 6d read time

  • 4d recent read time

  • 1.5k topics viewed

  • 9.1k posts read

  • 539 given


  • 38 topics created

  • 1.2k posts created

  • 320 received

  • 61 solutions


This describes our current use case. Everything works as expected when users are logged into both sites.

The problem I have is that if the user is not logged into our discourse instance (which has no anonymous access) then they don’t see anything on the page where the embed has been places.

Is it possible to get the embed to display a “Login to Discourse to see the discussion” message when this occurs?


I had a similar situation in a instance, and what solved for me was having both sites under the same Identity Provider using DiscourseConnect - Official Single-Sign-On for Discourse (sso).


Thanks, but that’s not possible in this case.

The current behaviour seems odd though because if there is a problem with logins then the user sees nothing. Is there a reason not to show a login link which would redirect to the discourse site?


I’m experiencing the same issue. It would be nice to see the embedded comments even if the site is set to private mode. Overall, I am loving Discourse, and the ability to add the comments to Ghost is a plus!


Is there a way to pass a unique div id each time the script is called? I have asynchronous content loading under my main article and would like the comments to appear on those items as well. Of course the issue with the current set up is that they all get shown in the ‘discourse-comments’ div id.

Thanks. @eviltrout


There is no way to pass a dynamic id. I’d accept a PR to do that though!


@eviltrout Err… well I know what a PR is (now), but how do you initiate a pull request?

1 Like

Sorry can you be more clear on what you mean by that? I am not a Ruby dev so that code is not going to come from me sadly. I dabbled with it once but didn’t get that far.

I would actually pay for this functionality to be added. Do you think posting in the marketplace would be the way to go for that? Thanks.


Yes the marketplace is a great place to get started if you don’t have the ability to add the feature yourself.

1 Like

Great function guys.

We like to use it soon but we have more than 30.000 blogs on our website. We don’t want all of them in the forum without comments. As the blogs are inserted as topics OnLoad i was wondering if there is a way to insert them into the forum after a button click in the embed for example so not all blogs will be inserted when visited (via Google for example)?

Our new topics overview page will be flooded by blogs i think (for our admins because they start invisible for normal formal users)

1 Like

There is no such feature. The ability to create those as unlisted was added to address this specific use case, but I can see how even it may be too little in the face of 30k blogs.

Maybe you can write a script to go and import history manually with the original post dates?


I have another question. We are using it now but we have articles with links with nofollow. On the forum the links are dofollow (nofollow is gone).

Is this something we can fix? Or is the canonical enough to don’t follow the links on the topic article?

1 Like

I wonder if the data-attribute “nosnippet” might help? Robots meta tag, data-nosnippet, and X-Robots-Tag specifications

I’m not 100% sure if Google would ignore the content marked by nosnippet, or if it just tells them not to display it in the SERP preview?


How can you transfer pictures using this method?

1 Like

I wrote some scripts to migrate our blog comments from Disqus into the Discourse forum, and in doing so I created a bunch of topics using the Discourse API instead of letting this integration create them. For the old posts, I am using the topicId embedding method, and new posts going forward are using the discourseEmbedUrl method.

However, I’m having a strange issue where some new topics are getting created anyway. (I suspect this is from a bug on my end when I briefly had some topicIds missing from some posts and those are the ones getting created as dupes.) While I don’t think there’s any solution for me right now, I would like to propose a solution for the future.

Since the embed controller tries to look up an existing post by the embed_url database column, I would like to see an API property to set that field when creating a topic. This would let my import script set this property for the topic. Then the integration wouldn’t even need to worry about switching between the topicId and discourseEmbedUrl field in the JS.


I just tracked down the source of this issue with the embed plugin. When configuring the embedding, there is an “Allowed Hosts” setting, which then sets the CSP for the iframe and the iframe will only show up at that host. For example if I configure embeds with an allowed host of example.com then try to embed the JS on attacker.com the iframe refuses to load with the error

Refused to frame 'https://forum.example.com/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self' https://example.com".

However, the JS has already actually run at this point and created a topic on the forum with whatever URL was given to the embed code.

What’s happening in my case is we use Netlify to preview builds, so a copy of the blog is actually being served from netlify.app URLs, which is then loading that embed.js and creating the forum thread for the posts that I had previously incorrectly imported.

This isn’t necessarily a security issue since it can still only create topics for URLs at the configured website and that match the path allowlist. But it’s an issue in this migration strategy since I had no way to set the embed_url on the forum threads when migrating old posts into Discourse.

The fix is to add a CSP rule to prevent that embed.js from being allowed to run on domains that are not configured under the “allowed hosts” setting.

As a proof of concept, I copied the embed code to a completely unrelated domain and set the discourseEmbedUrl to one of the old posts that I imported. I loaded the page and the iframe was blocked, but the JS had already run and created the forum thread.

If you think this is more of a security issue than a bug, I’m happy to delete this post and report it through hackerone instead.