Embed a list of Discourse topics onto an external site

:bookmark: This guide explains how to embed and display a list of Discourse topics on external websites using JavaScript.

:person_raising_hand: Required user level: Administrator

Summary

Embedding Discourse topics on external websites allows you to showcase forum content such as discussions or announcements. This integration enables you to display topic lists from your Discourse forum directly on your blog, website, or external content platform.

Enable topic embedding

  1. Add the embedding script to your external site:
<script src="https://discourse.example.com/javascripts/embed-topics.js"></script>

Replace discourse.example.com with your Discourse forumā€™s URL.

  1. Place the topics list element where you want to display topics (a blog post, an individual site page, etc.):
<d-topics-list discourse-url="https://discourse.example.com" category="1234" per-page="5"></d-topics-list>
  1. Navigate to your siteā€™s admin settings and enable the embed topics list site setting panel

  2. Add your external siteā€™s domain to Admin > Customize > Embedding > Allowed Hosts

:warning: You cannot embed topics from a private login-required Discourse site.

Configuration parameters

The d-topics-list element supports these attributes:

  • template - Display style options:
    • basic (default) - Shows minimal topic information
    • complete - Shows title, username, avatar, creation date, and thumbnail
  • per-page - Number of topics to display
  • category - Category ID to filter topics
  • allow-create - When true, shows a ā€œNew Topicā€ button
  • tags - Filter topics by specific tags
  • top_period - Show top topics from a time period:
    • all
    • yearly
    • quarterly
    • monthly
    • weekly
    • daily

You can combine multiple parameters to refine your topic list.

Customizing the appearance

You can style the embedded topics using custom SCSS in your Admin > Customize > Themes > Embedded CSS settings:

Example SCSS for a grid layout:

.topics-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  
  .topic-list-item {
    .main-link {
      border: 1px dotted gray;
      padding: 0;
    }
    
    .topic-column-wrapper {
      flex-direction: column-reverse;
      
      .topic-column.details-column {
        width: 100%;
      }
      
      .topic-column.featured-image-column .topic-featured-image img {
        max-width: initial;
        max-height: initial;
        width: 100%;
      }
    }
  }
}

Additional information

SameSite behavior

In SameSite contexts (where the embedding site and forum share a parent domain), Discourse will respect login status and display results accordingly. This means logged-in users may see content from secure categories that anonymous users cannot access.

Working with iframes

The embedded topics list does not use an iframe - it uses a JavaScript widget included via a <script> tag. This allows for better integration with your siteā€™s DOM structure and easier customization through CSS.

:information_source: If youā€™re looking to embed comments rather than topic lists, see our guide on embedding Discourse comments.

Example implementation

You can view a live example of embedded topics and examine the source code:

Last edited by @jessii 2024-11-21T19:01:02Z

Check documentPerform check on document:
8 Likes

Does this work with Discourse subscriptions? I tried to implement it and it was framing in my whole forum rather than topics?

1 Like

Yes, this should work alongside the Discourse Subscriptions plugin without any issues.

The embedding relies on configuring specific parameters to control what topics are displayed, such as category, tags, or per-page, through the d-topics-list tag in your websiteā€™s HTML. If your embedding ended up framing your whole forum, you might want to make sure that the Discourse URL and any parameters in the <d-topics-list> tag are properly set to reflect the topics you intend to display.

3 Likes

Hiļ¼Œitā€™s very niceļ¼Thanks!

I want to change the topic-list-item a element target value to ā€œ_blankā€ļ¼ˆdefault is _parentļ¼Œhas across domain problem and and itā€™s not what I wantļ¼‰ļ¼Œ

what should I do?

Hello, I am trying to get these to display on 2 different sites.

My discourse URL is https://learn.getupearlier.com

I have this script embedded here and itā€™s working:

I have the same script embedded here and itā€™s not working:

This is in the header:

<script src="https://learn.getupearlier.com/javascripts/embed-topics.js"></script>

This is in the page:

<d-topics-list discourse-url="https://learn.getupearlier.com" category="5" per-page="10"></d-topics-list>

Any help is appreciated!

2 Likes

Hi Michael,

The issue youā€™re encountering here is likely related to using a domain different from your Discourse domain to embed the topics on.

Your script is working on getupearlier.com because this is on the same domain as your Discourse site learn.getupearlier.com, whereas michaelbakerdigital.com is on a different domain.

Iā€™ve added this section to the guide, which explains how to resolve this situation.

So for your situation, adding michaelbakerdigital.com to your Discourse siteā€™s ā€œEmbeddingā€ ā†’ ā€œAllowed Hostsā€ should allow you to correctly embed topics on that domain.

6 Likes

Hello I allowed this URL as you can see below:

Here is the test URL:

I just get a blank grey error box

And this is the code inside michaelbakerdigital.com

<div id='discourse-comments'></div>
<meta name='discourse-username' content='MikeB'>

<script type="text/javascript">
  DiscourseEmbed = {
    discourseUrl: 'https://learn.getupearlier.com/',
    discourseEmbedUrl: 'michaelbakerdigital.com',
    // className: 'CLASS_NAME',
  };

  (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);
  })();
</script>

Or this:

<d-topics-list discourse-url="https://learn.getupearlier.com" category="5" per-page="5"></d-topics-list>

Any help appreciated Iā€™ve been stuck here forever and keep meaning to get this solved

Hello the solution here was my domain name that was added to the embed section needed www.

Thatā€™s it! So much time for 4 characters but solved it with help of Discourse and WP Engine support

Is there an example code to use for outputting a featured image as well to the external site?

Thanks so much

Help Needed: Embedding Discourse Topic List on Next.js Site

Hi everyone,

Iā€™m trying to embed a Discourse topic list on my website (example.io) which is built with the Next.js framework and Node.js, deployed through Vercel. Iā€™ve created a test replica of the website on test-discourse.app for this purpose.

Hereā€™s what Iā€™ve done so far:

  1. Added the host to the Discourse embedding settings.
  2. Enabled CORS in the environment and added the host to the CORS origin.
  3. Turned off CSP (Content Security Policy).

Despite following these steps and adding the necessary scripts, Iā€™m still unable to see the topic list on my website.

Hereā€™s the code Iā€™m using:

In the head section:

<script src="my-website/javascripts/embed-topics.js"></script>

In the body section:

<d-topics-list discourse-url="my-website" tags="example"></d-topics-list>

Also tried the categories embed as shown in post

Could anyone point out what I might be missing or doing wrong? Any suggestions to get the topic list to appear on my website would be greatly appreciated.

Thank you in advance for your help!