# How to add customer HTML after "post\_1"

**URL:** https://meta.discourse.org/t/how-to-add-customer-html-after-post-1/123068
**Category:** Support
**Created:** [July 16, 2019, 12:28pm UTC](https://meta.discourse.org/t/how-to-add-customer-html-after-post-1/123068 "2019-07-16T12:28:00Z")
**Posts on this page:** 1
**Showing post:** 2

<div class="post-metadata">

### Author: ![Johani](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/johani/32/176920_2.png) [@Johani](https://meta.discourse.org/u/Johani)
#### Post date: [July 16, 2019, 1:58pm UTC](https://meta.discourse.org/t/how-to-add-customer-html-after-post-1/123068/2 "2019-07-16T13:58:48Z")

</div>

Posts are [widgets](https://meta.discourse.org/t/a-tour-of-how-the-widget-virtual-dom-code-in-discourse-works/40347) which means what you’re trying to do will involve a bit more work that just adding html.

Discourse themes have the ability to [decorate widgets](https://meta.discourse.org/t/developer-s-guide-to-discourse-themes/93648#heading--4-c-6) so you can leverage on that.

Decorating a widget is explained in the link above so let’s focus on what you’re trying to do - add markup after the first post in every topic.

Start by adding the markup to all posts. So something like this

```plaintext
<script type="text/discourse-plugin" version="0.8">
api.decorateWidget("post:after", helper => {
  return helper.h("div", "test text");
});
</script>

```

to the header section of your theme. That should be enough to add “test text” below every post.

 ![widget001](https://global.discourse-cdn.com/meta/original/3X/2/7/271f86f6d7ebb76da642ca4bcbc9653dc8810b80.png)

Let’s breakdown the script above

`api.decorateWidget("post:after", helper => {`

calls the decorateWidget method, the target widget being `post` and the target location being `after`. So after a post widget.

`helper` is a built in helper that gives you access to a bunch of stuff that I will explain later

`return helper.h("div", "test text")`

This is the desired additional markup you want to add. You might notice that there’s no html in there and that’s because discourse widgets emit virtual nodes and not raw html.

Explaining what virtual nodes are or how the syntax works is outside of the scope for this topic, so I’ll skip that. I’ve added a note to write a howto for authoring virtual nodes but here are a couple of example for now

`helper.h("div", "test text")`

renders

```plaintext
<div>test text</div>

```

and

```plaintext
return helper.h("div#custom-ad", [
  helper.h(
    "a.custom-ad-link",
    { href: "example.com" },
    helper.h("img", { src: "https://picsum.photos/id/74/750/90" })
  )
]);

```

will render

```plaintext
<div id="custom-ad">
  <a href="example.com" class="custom-ad-link">
    <img src="https://picsum.photos/id/74/750/90">
  </a>
</div>

```

In a nutshell, a node looks like this

```plaintext
helper.h(selector, {properties}, children)

```

I’ll explain this more in the virtual node howto.

So, now you have the nodes ready, you would just need to add the whole script to the header section of your theme, so something like this

```plaintext
<script type="text/discourse-plugin" version="0.8">
  api.decorateWidget("post:after", helper => {
    return helper.h("div#custom-ad", [
      helper.h(
        "a.custom-ad-link",
        { href: "example.com" },
        helper.h("img", { src: "https://picsum.photos/id/74/750/90" })
      )
    ]);
  });
</script>

```

However, there’s still a problem here, the ad will be inserted below every post in the stream, which is not ideal.

 ![widget002](https://global.discourse-cdn.com/meta/original/3X/4/9/49e31312a80b2ebafea7193c86648cc968a789ff.jpeg)

This is where the helper comes in handy, the post attributes are passed to the helper, so you can do a quick

```plaintext
console.log(helper)

```

You’ll be able to see all the post attributes available for you to work with.

 ![widget003](https://global.discourse-cdn.com/meta/original/3X/9/b/9ba7293ea4e0c74c5b67d3f36416fce958bb78e3.png)

those are just examples, there’s more in there.

Luckily, the `firstPost` attribute is available for us here, so all you have left is to feed that into a conditional that will only render the ad markup if it’s indeed the first post, otherwise nothing happens. So something like this:

```plaintext
<script type="text/discourse-plugin" version="0.8">
api.decorateWidget("post:after", helper => {
  const firstPost = helper.attrs.firstPost;
  const h = helper.h;
  if (firstPost) {
    return h("div#custom-ad", [
      h(
        "a.custom-ad-link",
        { href: "example.com" },
        h("img", { src: "https://picsum.photos/id/74/750/90" })
      )
    ]);
  }
});
</script>

```

and that will insert your ad only after the first post. One additional thing to do here is to add a height to the image, otherwise it will cause jitter as it loads. So like I briefly touched on above, the `height` attribute for the image tag is a property, so you’re need to add it next to the `src`

With all of that put together, here’s the final code for what you’re trying to achieve

```plaintext
<script type="text/discourse-plugin" version="0.8">
api.decorateWidget("post:after", helper => {
  const firstPost = helper.attrs.firstPost;
  const h = helper.h;
  if (firstPost) {
    return h("div#custom-ad", [
      h(
        "a.custom-ad-link",
        { href: "example.com" },
        h("img", { src: "https://picsum.photos/id/74/750/90", height: "90" })
      )
    ]);
  }
});
</script>

```

One last note I want to highlight is that you can actually use raw html if virtual nodes prove to be to tricky, but it’s not recommended and it’s much better to use virtual nodes. So the same script with raw html would like like this

```plaintext
<script type="text/discourse-plugin" version="0.8">
  const RawHtml = require("discourse/widgets/raw-html").default;
  api.decorateWidget("post:after", helper => {
    const firstPost = helper.attrs.firstPost;
    if (firstPost) {
      return [
        new RawHtml({
          html: `<div id="custom-ad">
                   <a href="example.com">
                     <img src="https://picsum.photos/id/74/750/90" height="90">
                   </a>
                 </div>`
        })
      ];
    }
  });
</script>

```

but again, this is not recommended.

---

_[View the full topic](https://meta.discourse.org/t/how-to-add-customer-html-after-post-1/123068)._
