How do add consistent HTML to the body

Let’s start simple:

  var tag = document.createElement("div");
  var text = document.createTextNode('Hello World!'); 

This is good for adding a couple tags, but what would be the correct approach to inject complex/nested HTML tags and maybe also forms/controls etc? Is it possible for example to load from a file and then bind events programmatically?

You can use content templates to inject blocks of HTML and then populate in relevant data with DOM methods. This example has very amateurish code and needs refactoring, but for what it’s worth:

the cloneNode is already of great help, I really need to load some text/html from some form of data storage, I read reading local files shipped with the extension is not simple, maybe there are other methods? Download it from the cloud?

Remote content is unlikely to be allowed. See

Reading files shipped with the extension should be as simple as using fetch with browser.runtime.getURL.

1 Like

I eventually resolved with parametric modules put inside various const so for example I have a const that contains a wrapper, and at some point I added a {%xxxx-content} what I do inside my cycle is building inner content. Like a set of boxes I also have content variable with {%xxxx-rows} consider my const as templates. Following this I also have row variable and so on.

When everything is complete I create a <div> add my content and inject into the page:


Using prepend (and append) is forbidden for addons because it accepts also strings.
To append / prepend nodes one should use insertAdjacentElement:

As you can see, work with HTML is pretty bad in addons. It may be better to use Vue, React or Angular for building complex HTML pages.

See also:

these new bots asking for help just to post a spam link afterwards are starting to piss me off, can someone make registration harder?

I’m not sure I do this and prepend it to the <body> the add-on is working on both firefox and chrome and was approved.

I was using prepend in my code for a long time and then one day I’ve got a message from a reviewer that I can’t use it :slight_smile:.

The problem is same as with innerHTML, the ability to build HTML from a string:

The point is to build HTML, imagine all the plug-ins that have an interface inside the page, they must at some point build or inject HTML, be it raw HTML or a JS that prints the HTML. How would you do otherwise? Using insertAdjacentElement gets the same result of adding/injecting HTML so why they would allow this but not prepend it doesn’t make sense.

To note, that I build from a string this way:

var $final_overlay = document.createElement("div"); $final_overlay.innerHTML= DOMPurify.sanitize($temp_overlay); document.body.prepend($final_overlay);

Probably the presence of sanitize was what made my add-on pass the check.

You can build DOM in a safe way using document.createElement which returns a Element which can be appended to body using insertAdjacentElement.

The issue with prepend (unlike insertAdjacentElement) is that it also accepts string as input.
It’s all explained here:

Note that for a reviewer it can be very hard (or impossible) to tell whether you are calling it with Element or a string and whether the string has been sanitized. That’s why they forbid to use the API that allows HTML string as input (there is only handful of those).

I think the misunderstanding is about the source of the code you are injecting. I’m not injecting external code. The HTML I’m adding has no <script> or other “suspicious” tags such as <iframe> or others, just nested <div> elements to build the itnerface.

Fact is it was approved in both platorms with prepend I don’t think it is forbidden, but probably it must check some requisites. For more informations about this you should ask a reviewer I suppose.

And example message from reviewer:

  1. This add-on is creating DOM nodes from HTML strings containing potentially unsanitized data, by assigning to innerHTML, jQuery.html, or through similar means. Aside from being inefficient, this is a major security risk. For more information, see .

Again, the reviewer may not see that you are injecting safe code. That’s why it’s better to avoid it.
Then you won’t see warnings when submitting new version.
You can also use web-ext lint command to check your source code for potential issues.

It is telling you that you have potentially unsanitized data. Without looking at the code it is hard to tell if you have paths that lead to insecure use. I usually do the sanitize just before passing the string to the innerHTML of the node (usually a <div>) and it gets approved. Maybe your add-on is a lot more complex than mine and the reviewer is not looking at it in detail.

1 Like