# Is this the correct way to create a theme component?

**URL:** https://meta.discourse.org/t/is-this-the-correct-way-to-create-a-theme-component/334468
**Category:** Development
**Created:** [November 4, 2024, 7:11pm UTC](https://meta.discourse.org/t/is-this-the-correct-way-to-create-a-theme-component/334468 "2024-11-04T19:11:40Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![noahl](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/noahl/32/552343_2.png) [@noahl](https://meta.discourse.org/u/noahl)
#### Post date: [November 4, 2024, 7:11pm UTC](https://meta.discourse.org/t/is-this-the-correct-way-to-create-a-theme-component/334468/1 "2024-11-04T19:11:40Z")

</div>

I’ve experience building custom solutions with other platforms/frameworks, and want to understand if this is the correct way to create a theme component in Discourse.

It seems to be working, but doesn’t necessarily mean it’s the correct way.

In short, this should hide reaction depending on the category a topic is within. Is this the right way to do it?

```js
<script type="text/discourse-plugin" version="0.1">
$(document).ready(function() {
    try {
      const isTopicPage = /^\/t\//.test(window.location.pathname);
      
      if (!isTopicPage) return;

      const allowedCategories = ['ask-a-question'];

      const topic = Discourse. __container__.lookup("controller:topic");
      const categorySlug = topic && topic.get("model.category.slug");
      const isAllowedCategory = categorySlug && allowedCategories.includes(categorySlug);

      const toggleReactionEmoji = () => {
        const emoji = document.querySelector("[data-reaction='frog']");
        
        if (emoji) {
          emoji.style.display = isAllowedCategory ? '' : 'none';
          console.log(`Emoji with data-reaction='frog' ${isAllowedCategory ? 'shown' : 'hidden'}.`);
        }
      };

      toggleReactionEmoji();

      const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
          mutation.addedNodes.forEach(node => {
            if (node.nodeType === 1) {
              const emoji = node.querySelector("[data-reaction='frog']");
              if (emoji) {
                emoji.style.display = isAllowedCategory ? '' : 'none';
                console.log(`Emoji with data-reaction='frog' found in mutation and ${isAllowedCategory ? 'shown' : 'hidden'}.`);
              }
            }
          });
        });
      });

      observer.observe(document.body, { childList: true, subtree: true });

      api.cleanupStream(() => observer.disconnect());

    } catch (error) {
      console.error("An error occurred in the emoji toggle script:", error);
    }
  });
</script>

```

---

<div class="post-metadata">

### Author: ![keegan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/keegan/32/383395_2.png) [@keegan](https://meta.discourse.org/u/keegan)
#### Post date: [November 4, 2024, 7:45pm UTC](https://meta.discourse.org/t/is-this-the-correct-way-to-create-a-theme-component/334468/2 "2024-11-04T19:45:39Z")

</div>

Although this way of doing things is technically possible, it’s not the _ideal_ approach.

Instead of using script tags and jQuery `$(document).ready` it would be better to work with Ember’s rendering system correctly.

To start, it would be good to create a theme component repository with a proper folder structure for your theme-component. Have a look at the [`discourse_theme` CLI](https://meta.discourse.org/t/install-the-discourse-theme-cli-console-app-to-help-you-build-themes/82950/1) as this will scaffold out that structure for you, and make it easy for you to develop the component. (Alternatively, there’s also the [theme skeleton](https://github.com/discourse/discourse-theme-skeleton) if you only need the structure and not any of the other goodies of the theme CLI).

From here, I would use tools Discourse has in place for extensibility such as `apiInitializers`, the [`pluginAPI`](https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/lib/plugin-api.gjs), plugin outlets, etc. to achieve what you’re trying to do.

The best way to learn about these things is to peruse the [Developer Guides here on Meta](https://meta.discourse.org/c/documentation/developer-guides/56) (specifically the theme/theme-component) sections. Additionally, I would go through the #Customization > Theme component category and find their GitHub repositories. Looking through their code and how they achieve things will help you as well.

I hope this helps!

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [November 5, 2024, 12:57pm UTC](https://meta.discourse.org/t/is-this-the-correct-way-to-create-a-theme-component/334468/3 "2024-11-05T12:57:12Z")

</div>

> [@noahl](#):
>
> this should hide reaction depending on the category a topic is within.

If this is your goal, you can do it with simple CSS:

```css
body.category-ask-a-question .discourse-reactions-picker.frog {
  display: none;
}

```
