Insert content to DOM at script tag location

Reading Time: 3 minutes 🕑

Last updated: April 28, 2022.

Sometimes, it is useful to insert content to the DOM at the location of a script tag, placed somewhere within the document body.

For example, you may link to a script that loads a function in the head or bottom section of your page. You then want to place a script tag in the body of your page the runs the function and inserts some content at the location of the script function-invoking script.

This can be especially useful if you are creating some functionality for a non-developer, because you can give them the instruction to simply insert a function-invoking script tag on a page where they would like to append the content generated by the script.

So, how can you do it?

Table of contents

Getting current script tag location

All you have to do to get the location of the current script is call the following within the script:

document.currentScript; // returns script element in which code is embedded

Calling a function within the script

Calling a function inside <head></head>

If you want to call on a function that is loaded in the header of the document, you can simply call it from within the document-embedded script.

/* Calling a function loaded in header from document-embedded script */

const currentScript = document.currentScript;

insertSomething();

Calling a function loaded anywhere

If you want to call on a function that is loaded after the body of the HTML (or anywhere else), you can add an event listener to the global window object and run the callback function when the page content is loaded:

/* Calling a function loaded anywhere from document-embedded script */

const currentScript = document.currentScript;
window.addEventListener("load", () => {
    insertSomething();
})

Appending content at script location

There are two options here, depending upon whether you want to append a HTML element or string content (to be rendered as text or HTML).

You can run the following code inside the document-embedded script. But it is probably better to define the insertion code in its own function, so the body of the HTML does not become cluttered. We take this approach in the examples below.

For an element: insertBefore()

To insert an element to the DOM, use the insertBefore() method:

function insertSomething() {
    const newElement = document.createElement('p');
    newElement.textContent = "New element text";

    const parentElement = currentScript.parentElement;

    parentElement.insertBefore(newElement, currentScript);
}

For a string rendered as text: insertAdjacentText()

To insert content that you want to write to the DOM as text, use insertAdjacentText():

function insertSomething() {
    const content = "This is a sentence";
    currentScript.insertAdjacentText('beforebegin', content);
}

For a string rendered as HTML: insertAdjacentHTML()

To insert string or template literal content that you want to render to the DOM as HTML, use insertAdjacentHTML():

function insertSomething() {
    const content = `<p>This is some HTML<p>`;
    currentScript.insertAdjacentHTML('beforebegin', content);
}

Removing the script from the DOM

If the script located in the document runs and one-time process that appends content to the DOM, there is little value in leaving it in the DOM after it has worked its magic.

For this, you can use the remove() method after inserting the content:

/* In-document script */
const currentScript = document.currentScript;
window.addEventListener("load", () => {
    loadSomething();
    currentScript.remove();
})

/* Separate function */
function insertSomething() {
    const content = `<p>This is some HTML<p>`;
    currentScript.insertAdjacentHTML('beforebegin', content);
}

Minimal global scope ‘pollution’ with self-executing function

It is best practice to place the contents of the in-document script inside a self-executing function. This minimizes the possibility of a naming conflict with other scripts that are running on the page.

Using this solution, the current script element can be passed to a separate function as an argument when calling it:

/* In-document script */
(function() {
const currentScript = document.currentScript;
    window.addEventListener("load", () => {
        insertSomething(currentScript);
        currentScript.remove();
    })
})()

/* Separate function */
function insertSomething(script) {
    const content = "This is a sentence";
    script.insertAdjacentText('beforebegin', content)
}