# Embed a list of Discourse topics onto an external site

**URL:** https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709
**Category:** Integrations
**Tags:** embedding, how-to
**Created:** [January 31, 2024, 11:59pm UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709 "2024-01-31T23:59:08Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [January 31, 2024, 11:59pm UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/1 "2024-01-31T23:59:08Z")

</div>

> 🔖 This guide explains how to embed and display a list of Discourse topics on external websites using JavaScript, allowing you to showcase forum content such as discussions or announcements on blogs, websites, or external content platforms.
> 
> 🙋 Required user level: Administrator

## Summary

Embedding Discourse topics on external websites enables you to display topic lists from your Discourse forum directly on other sites. This integration helps drive traffic to your forum and keeps your audience engaged with your community content. The embedded topics appear as a JavaScript widget that integrates with your site’s DOM structure, making it easier to customize through CSS.

## Enable topic embedding

To set up topic embedding on your external site:

1. Navigate to **Admin \> Advanced \> Embedding** and switch to the **Settings** tab. Enable the `embed_topics_list` site setting

 ![Enabling embed](https://global.discourse-cdn.com/meta/original/4X/a/2/3/a2391e75a14edae0085bbc868f53ab9199cbb85b.png)

1. Add the embedding script to your external site’s HTML head section:

```html
<script src="https://discourse.example.com/javascripts/embed-topics.js"></script>

```

Replace `discourse.example.com` with your actual Discourse forum’s URL.

1. Place the topics list element where you want to display topics (such as in a blog post or on an individual site page):

```html
<d-topics-list discourse-url="https://discourse.example.com" category="1234" per-page="5"></d-topics-list>

```

1. If you’re embedding topics on a different domain than your Discourse site, add your external site’s domain to **Admin \> Advanced \> Embedding \> Hosts**

 ![Adding Hosts](https://global.discourse-cdn.com/meta/original/4X/4/e/a/4ea706a8b795433af585804538480e36155afe12.png)

For example, if your Discourse site is located at `yourdiscourseforum.com` and you want to embed topics on `yourexternalsite.com`, you need to add `yourexternalsite.com` to your Allowed Hosts list.

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

## Configuration parameters

The `d-topics-list` element supports the following attributes to customize your topic display:

- `discourse-url` - The URL of your Discourse site (required)
- `template` - Display style options:
  - `basic` (default) - Shows topic titles as links
  - `complete` - Shows title, username, avatar, creation date, last reply time, like count, reply count, and featured image/thumbnail

- `per-page` - Number of topics to display (capped by the hidden `embed_topic_limit_per_page` site setting, default 200)
- `category` - Category ID to filter topics from a specific category
- `tags` - Filter topics by specific tags
- `allow-create` - When set to true, shows a “New Topic” button
- `embed-class` - Adds a custom CSS class to the embedded topics list container (alphanumeric, hyphens, and underscores only)
- `top-period` - Show top topics from a specific time period:
  - `all`
  - `yearly`
  - `quarterly`
  - `monthly`
  - `weekly`
  - `daily`

You can combine multiple parameters to refine your topic list display. For example:

```html
<d-topics-list 
  discourse-url="https://discourse.example.com" 
  category="5" 
  tags="announcements" 
  per-page="10"
  template="complete">
</d-topics-list>

```

## Customizing the appearance

You can style the embedded topics using custom SCSS in your **Admin \> Appearance \> Themes and Components** panel. Click on your current or default theme and click **Edit Code**. You can then select `Show_advanced` and choose **Embedded CSS** to add your custom code:

 ![Embedded CSS tab](https://global.discourse-cdn.com/meta/original/4X/d/3/6/d36084b5669f9d655b3d7c7572886fcc76f14a04.png)

Here’s an example SCSS for creating a grid layout:

```scss
.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%;
      }
    }
  }
}

```

## Best practices

- Use meaningful category and tag filters to display relevant content for your audience
- Set an appropriate `per-page` value to avoid overwhelming visitors
- Test your embedded topics on different screen sizes to ensure responsive design
- Consider using the `complete` template for better visual appeal when space permits
- Regularly review your Allowed Hosts list to ensure only authorized domains can embed your topics

## Common issues and solutions

### Topics not displaying on external domain

**Issue** : The embedded topics appear as a blank or grey box when viewed on an external domain.

**Solution** : Add the external domain to your Discourse site’s **Admin \> Advanced \> Embedding \> Hosts**. Make sure to include the correct subdomain (e.g., if your site uses `www.example.com`, add `www.example.com` rather than just `example.com`).

### Script loading errors

**Issue** : The embed script fails to load or returns connection errors.

**Solution** :

- Verify that the Discourse URL in your script source is correct and accessible
- Check that the `embed_topics_list` site setting is enabled
- Ensure your Discourse site is not login-required for public topics

### SameSite context behavior

In SameSite contexts where the embedding site and forum share a parent domain, Discourse respects login status and displays results accordingly. Logged-in users may see content from secure categories that anonymous users cannot access.

## FAQs

**Q: Can I embed topics from a private Discourse site?**  
A: No, topic embedding only works with public Discourse sites. Private login-required sites cannot be embedded.

**Q: Can I embed multiple topic lists on the same page?**  
A: Yes, you can include multiple `<d-topics-list>` elements on the same page with different parameters to display various topic collections.

**Q: How do I embed topics with featured images?**  
A: Use the `template="complete"` parameter in your `<d-topics-list>` element to display topics with thumbnails and featured images.

**Q: Can I change where topic links open?**  
A: By default, topic links open in the parent window. You can modify this behavior through CSS or JavaScript customization.

## Additional resources

- [Embed Discourse comments on another website via Javascript](https://meta.discourse.org/t/embed-discourse-comments-on-another-website-via-javascript/31963)

> Last edited by @jessii 2025-08-28T21:48:18Z
> 
> > **Check document**
> >
> > Perform check on document:

---

<div class="post-metadata">

### Author: ![Michael\_Baker](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/michael_baker/32/361055_2.png) [@Michael\_Baker](https://meta.discourse.org/u/Michael_Baker)
#### Post date: [February 11, 2024, 7:19pm UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/2 "2024-02-11T19:19:28Z")

</div>

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

---

<div class="post-metadata">

### Author: ![SaraDev](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/saradev/32/335139_2.png) [@SaraDev](https://meta.discourse.org/u/SaraDev)
#### Post date: [February 15, 2024, 9:04pm UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/3 "2024-02-15T21:04:55Z")

</div>

Yes, this should work alongside the [Discourse Subscriptions](https://meta.discourse.org/t/discourse-subscriptions/140818) 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.

---

<div class="post-metadata">

### Author: ![yoke\_snowwolf](https://avatars.discourse-cdn.com/v4/letter/y/ac91a4/32.png) [@yoke\_snowwolf](https://meta.discourse.org/u/yoke_snowwolf)
#### Post date: [February 19, 2024, 10:23am UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/4 "2024-02-19T10:23:45Z")

</div>

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?

---

<div class="post-metadata">

### Author: ![Michael\_Baker](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/michael_baker/32/361055_2.png) [@Michael\_Baker](https://meta.discourse.org/u/Michael_Baker)
#### Post date: [February 27, 2024, 7:51pm UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/5 "2024-02-27T19:51:06Z")

</div>

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

My discourse URL is [https://learn.getupearlier.com](https://learn.getupearlier.com)

I have this script embedded here and it’s working:

> **[Personal Training & Marathon Coaching for Adults 40+ | Get Up Earlier...](https://getupearlier.com/)**
>
> Personal strength training, marathon coaching, and nutrition coaching for adults 40+ in Orange & Milford, CT or virtual nationwide.

 ![image](https://global.discourse-cdn.com/meta/original/4X/8/d/5/8d50da3024f19f3ec5a5518fc2039a37c9162f64.png)

I have the same script embedded here and it’s not working:

> **[Michael Baker Digital | 25+ Years Website Creation | Local Search | AI and...](https://michaelbakerdigital.com)**
>
> Hands-on digital marketing expert consulting and customization for Replit, AI, WordPress Repair, WordPress to AI Migration, Shopify Plus, content creation, strategy.

 ![image](https://global.discourse-cdn.com/meta/original/4X/f/5/4/f54364b13de7c14ea446906929bbe417e3ca6353.png)

This is in the header:

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

```

This is in the page:

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

```

Any help is appreciated!

---

<div class="post-metadata">

### Author: ![SaraDev](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/saradev/32/335139_2.png) [@SaraDev](https://meta.discourse.org/u/SaraDev)
#### Post date: [March 7, 2024, 8:29pm UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/8 "2024-03-07T20:29:49Z")

</div>

Hi Michael,

> [@Michael\_Baker](#):
>
> Hello, I am trying to get these to display on 2 different sites.
> 
> My discourse URL is [https://learn.getupearlier.com](https://learn.getupearlier.com)
> 
> I have this script embedded here and it’s working: `https://getupearlier.com/`
> 
> I have the same script embedded here and it’s not working: `https://www.michaelbakerdigital.com/`

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.

> [@SaraDev](#):
>
> 1. If the domain you are embedding topics on is different from the domain of the Discourse site hosting the topics, you will need to add the domain you want to embed the topics on to the list of “Embeddings” → “Allowed Hosts” (`.../admin/customize/embedding`) on the Discourse site hosting the topics.
> 
> For example, if your Discourse site located on `yourdiscourseforum.com`, and you want to embed topics on `yourexternalsite.com`, you would need to add a record similar to the following to your Discourse forum’s “Embeddings” page:
> 
> ![image](https://global.discourse-cdn.com/meta/original/4X/5/6/a/56a0fa8c2f38b68fa4ab7ae1c3352454aa0f5e35.png)
> 
> If you are embedding topics on the same domain as the Discourse site hosting the topics, this step is not necessary.

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.

---

<div class="post-metadata">

### Author: ![Michael\_Baker](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/michael_baker/32/361055_2.png) [@Michael\_Baker](https://meta.discourse.org/u/Michael_Baker)
#### Post date: [May 26, 2024, 10:54pm UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/23 "2024-05-26T22:54:21Z")

</div>

Hello I allowed this URL as you can see below:

 ![image](https://global.discourse-cdn.com/meta/original/4X/3/0/c/30cdad30b907d1c7cd563634fd85ae9690e3422c.png)

Here is the test URL:

> **[Michael Baker Digital | 25+ Years Website Creation | Local Search | AI and...](https://michaelbakerdigital.com/)**
>
> Hands-on digital marketing expert consulting and customization for Replit, AI, WordPress Repair, WordPress to AI Migration, Shopify Plus, content creation, strategy.

I just get a blank grey error box

 ![image](https://global.discourse-cdn.com/meta/original/4X/6/7/0/670a75f5539165aea74b3c06ce0fe4a217eaca94.jpeg)

And this is the code inside [michaelbakerdigital.com](http://michaelbakerdigital.com)

```plaintext
<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:

```plaintext
<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

---

<div class="post-metadata">

### Author: ![Michael\_Baker](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/michael_baker/32/361055_2.png) [@Michael\_Baker](https://meta.discourse.org/u/Michael_Baker)
#### Post date: [May 30, 2024, 4:18pm UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/24 "2024-05-30T16:18:20Z")

</div>

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

 ![image](https://global.discourse-cdn.com/meta/original/4X/c/3/9/c39c47eb097077271a76af7361b129e4ee9939d2.png)

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

---

<div class="post-metadata">

### Author: ![Michael\_Baker](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/michael_baker/32/361055_2.png) [@Michael\_Baker](https://meta.discourse.org/u/Michael_Baker)
#### Post date: [May 30, 2024, 5:13pm UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/25 "2024-05-30T17:13:18Z")

</div>

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

Thanks so much

---

<div class="post-metadata">

### Author: ![pinder99](https://avatars.discourse-cdn.com/v4/letter/p/dfb087/32.png) [@pinder99](https://meta.discourse.org/u/pinder99)
#### Post date: [June 26, 2024, 6:37pm UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/26 "2024-06-26T18:37:35Z")

</div>

**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](http://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:**

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

```

**In the body section:**

```html
<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!

---

<div class="post-metadata">

### Author: ![Andrew\_Rowe](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/andrew_rowe/32/445877_2.png) [@Andrew\_Rowe](https://meta.discourse.org/u/Andrew_Rowe)
#### Post date: [January 26, 2025, 9:53pm UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/27 "2025-01-26T21:53:56Z")

</div>

I have a Discourse instance running on a VPS  
I have another website running on a different VPS  
Both have the same root domain for example

```plaintext
community.mydomain.com
mydomain.com

```

I have successfully used this method to embed a topic list from the forum server (Discourse) into the other website. It is really great for generating traffic from my website to the forum.

I use the right sidebar blocks component to list ‘upcoming events’ from a calendar using the discourse-calendar plugin

I would like to replicate the ‘upcoming events’ on my other website. I can use the method described in this topic to get all the topics in my calendar category but they are ordered by most recently posted

The right sidebar blocks component orders them by the date of the event  
example

 ![image](https://global.discourse-cdn.com/meta/original/4X/d/7/3/d73fbc9824d3457df390f54673c58e71a89e0052.png)

Is there a way to do this? I have administrative control over both websites.  
Is there another way to extract data from my Discourse server such as the API? Is the API installed on all Discourse instances by default or do I have to install it?

---

<div class="post-metadata">

### Author: ![Andrew\_Rowe](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/andrew_rowe/32/445877_2.png) [@Andrew\_Rowe](https://meta.discourse.org/u/Andrew_Rowe)
#### Post date: [February 6, 2025, 12:09am UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/28 "2025-02-06T00:09:50Z")

</div>

Since I didn’t get any hints I figured I’d answer a few of my own questions for anyone who looks

> [@Andrew\_Rowe](#):
>
> Is the API installed on all Discourse instances by default or do I have to install it?

just for reference YES, self hosted [official install](https://meta.discourse.org/t/install-discourse-in-production-with-the-official-supported-instructions/142537?silent=true) included the REST API

Got hints from [api example thread](https://meta.discourse.org/t/discourse-rest-api-comprehensive-examples/274354) how to make cURL calls from the terminal. Once the cURL commands worked I used this website to convert the command line version to PHP

> **[cURL to PHP code Converter | HasData](https://hasdata.com/curl-to-php-converter)**
>
> Convert cURL commands to PHP code instantly and easily with our free online tool.

My other server runs PHP as backend and I make ajax calls from web page to function on the server. The Discourse spits out json and javascript it built for decoding that. Style as needed… soup  
note this may only work because

> [@Andrew\_Rowe](#):
>
> Both have the same root domain for example
> 
> ```plaintext
> community.mydomain.com
> mydomain.com
> 
> ```

and I use API key and user per [how to found here](https://meta.discourse.org/t/create-and-configure-an-api-key/230124)  
hope it helps someone 👍

---

<div class="post-metadata">

### Author: ![bitmage](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/bitmage/32/389881_2.png) [@bitmage](https://meta.discourse.org/u/bitmage)
#### Post date: [April 20, 2025, 6:02pm UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/29 "2025-04-20T18:02:46Z")

</div>

It seems we can also use the embed link within a forum post, like this:

`<iframe width="500" height="400" src="https://meta.discourse.org/embed/topics?tags=release-notes" frameborder=0 scrolling="no"></iframe>`

(it won’t work here because they haven’t enabled their own site within iframe admin settings)

However, scrolling=“no” does not work… Apparently the standards body [deprecated scrolling within HTML5](https://stackoverflow.com/questions/217776/how-to-apply-css-to-iframe) and replaced it with… nothing. Iframes just get better every year, huh?

In my testing if I change the `<body>` within the iframe to `overflow: hidden` the horizontal scrollbar goes away. I haven’t found a way to get the vertical one to go away. From my plugin is there a way I can modify the embed page to set `overflow: hidden`?

---

<div class="post-metadata">

### Author: ![jrgong](https://avatars.discourse-cdn.com/v4/letter/j/c57346/32.png) [@jrgong](https://meta.discourse.org/u/jrgong)
#### Post date: [September 17, 2025, 1:34pm UTC](https://meta.discourse.org/t/embed-a-list-of-discourse-topics-onto-an-external-site/293709/30 "2025-09-17T13:34:50Z")

</div>

When embedding a list of topics, what would be the “best” way if I want to create a carousel from all embedded topics with horizontal scrolling?

Is there any way to change each topic link to be opened in a new tab/window?
