Встраивание списка тем Discourse на внешний сайт

:bookmark: Это руководство объясняет, как с помощью JavaScript встроить и отобразить список тем Discourse на внешних сайтах, что позволит вам демонстрировать контент форума (например, обсуждения или объявления) на блогах, веб-сайтах или внешних платформах.

:person_raising_hand: Требуемый уровень пользователя: Администратор

Краткое описание

Встраивание тем Discourse на внешние сайты позволяет отображать списки тем из вашего форума Discourse непосредственно на других ресурсах. Эта интеграция помогает привлекать трафик на ваш форум и удерживает аудиторию, вовлекая её в контент сообщества. Встроенные темы отображаются в виде виджета на JavaScript, который интегрируется в структуру DOM вашего сайта, что упрощает кастомизацию с помощью CSS.

Включение встраивания тем

Для настройки встраивания тем на вашем внешнем сайте:

  1. Перейдите в раздел Администрирование > Дополнительно > Встраивание и переключитесь на вкладку Настройки. Включите настройку сайта embed_topics_list.

  1. Добавьте скрипт встраивания в секцию <head> HTML-кода вашего внешнего сайта:
<script src="https://discourse.example.com/javascripts/embed-topics.js"></script>

Замените discourse.example.com на реальный URL вашего форума Discourse.

  1. Разместите элемент списка тем в том месте, где вы хотите отображать темы (например, в записи блога или на отдельной странице сайта):
<d-topics-list discourse-url="https://discourse.example.com" category="1234" per-page="5"></d-topics-list>
  1. Если вы встраиваете темы на домен, отличный от домена вашего сайта Discourse, добавьте домен вашего внешнего сайта в раздел Администрирование > Дополнительно > Встраивание > Хосты.

Например, если ваш сайт Discourse находится по адресу yourdiscourseforum.com, а вы хотите встроить темы на yourexternalsite.com, вам нужно добавить yourexternalsite.com в список разрешённых хостов.

:warning: Вы не можете встраивать темы с частного сайта Discourse, требующего входа в систему.

Параметры конфигурации

Элемент d-topics-list поддерживает следующие атрибуты для настройки отображения тем:

  • discourse-url — URL вашего сайта Discourse (обязательно)
  • template — Варианты стиля отображения:
    • basic (по умолчанию) — Отображает заголовки тем в виде ссылок
    • complete — Отображает заголовок, имя пользователя, аватар, дату создания, время последнего ответа, количество лайков, количество ответов и главное изображение/миниатюру
  • per-page — Количество тем для отображения (ограничено скрытой настройкой сайта embed_topic_limit_per_page, по умолчанию 200)
  • category — ID категории для фильтрации тем из конкретной категории
  • tags — Фильтрация тем по конкретным тегам
  • allow-create — При значении true отображается кнопка «Новая тема»
  • embed-class — Добавляет пользовательский CSS-класс к контейнеру встроенного списка тем (допустимы только буквы, цифры, дефисы и нижние подчёркивания)
  • top-period — Показывает лучшие темы за определённый период:
    • all
    • yearly
    • quarterly
    • monthly
    • weekly
    • daily

Вы можете комбинировать несколько параметров для уточнения отображения списка тем. Например:

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

Настройка внешнего вида

Вы можете стилизовать встроенные темы с помощью пользовательского SCSS в панели Администрирование > Внешний вид > Темы и компоненты. Нажмите на вашу текущую или стандартную тему и выберите Редактировать код. Затем выберите опцию Show_advanced и нажмите Встроенный CSS, чтобы добавить свой код:

Вот пример 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%;
      }
    }
  }
}

Рекомендации по использованию

  • Используйте осмысленные фильтры по категориям и тегам для отображения релевантного контента для вашей аудитории
  • Устанавливайте подходящее значение per-page, чтобы не перегружать посетителей
  • Тестируйте встроенные темы на экранах разных размеров, чтобы обеспечить адаптивный дизайн
  • Рассмотрите возможность использования шаблона complete для более привлекательного визуального оформления, если позволяет место
  • Регулярно проверяйте список разрешённых хостов, чтобы убедиться, что только авторизованные домены могут встраивать ваши темы

Распространённые проблемы и решения

Темы не отображаются на внешнем домене

Проблема: Встроенные темы отображаются как пустой или серый блок при просмотре с внешнего домена.

Решение: Добавьте внешний домен в раздел Администрирование > Дополнительно > Встраивание > Хосты вашего сайта Discourse. Убедитесь, что указан правильный поддомен (например, если ваш сайт использует www.example.com, добавьте www.example.com, а не только example.com).

Ошибки загрузки скрипта

Проблема: Скрипт встраивания не загружается или возвращает ошибки соединения.

Решение:

  • Проверьте правильность и доступность URL сайта Discourse в источнике скрипта
  • Убедитесь, что включена настройка сайта embed_topics_list
  • Проверьте, что ваш сайт Discourse не требует входа для доступа к публичным темам

Поведение в контексте SameSite

В контекстах SameSite, когда сайт встраивания и форум имеют общий родительский домен, Discourse учитывает статус входа в систему и отображает результаты соответствующим образом. Пользователи, вошедшие в систему, могут видеть контент из защищённых категорий, недоступный анонимным пользователям.

Часто задаваемые вопросы

В: Могу ли я встроить темы с частного сайта Discourse?
О: Нет, встраивание тем работает только с публичными сайтами Discourse. Частные сайты, требующие входа, встроить нельзя.

В: Могу ли я встроить несколько списков тем на одной странице?
О: Да, вы можете добавить несколько элементов <d-topics-list> на одной странице с разными параметрами для отображения различных коллекций тем.

В: Как встроить темы с главными изображениями?
О: Используйте параметр template="complete" в элементе <d-topics-list>, чтобы отображать темы с миниатюрами и главными изображениями.

В: Могу ли я изменить место, где открываются ссылки на темы?
О: По умолчанию ссылки на темы открываются в родительском окне. Вы можете изменить это поведение с помощью кастомизации CSS или JavaScript.

Дополнительные ресурсы

9 лайков

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

1 лайк

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.

4 лайка

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 лайка

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 лайков

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!

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

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

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?

1 лайк

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

just for reference YES, self hosted official install included the REST API

Got hints from api example thread 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

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

and I use API key and user per how to found here
hope it helps someone :+1:

1 лайк

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 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?

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?