Search code examples
innerhtmlhtmx

secure way to emulate hx-swap without sending get requests?


I have a header that when user clicks it it sends a request to fetch some social media links

<h3 class='header1' hx-get="/social" hx-swap="outerHTML" hx-target="#content_div" >My Social</h3>

The request then replaces the current content_div with

<div id="content_div">
    <div class="Socials">
        <a href="https://stackoverflow.com/users/blah/blah"><font color="#007cc4"><i class="fab fa-stack-overflow"></i></font></a>
        <a href="https://github.com/blah"><font color="#007cc4"><i class="fab fa-github"></i></font></a>
        <a href="https://www.linkedin.com/in/blah-blah-blah/"><font color="#007cc4"><i class="fab fa-linkedin"></i></font></a>
    </div>
</div>

I like the functionality of this but I don't like the fact that I have to do a GET request to do this since the socials div is small and doesn't require any backend data. I can do this with some javascript by using the innerHTML attribute:

<h3 class='header1' hx-on:click="document.getElementById('content_div').innerHTML = document.getElementById('socials').innerHTML;">My Socials</h3>

<div id='socials' style="display:none">
    <div class="Social-media fade-in">
        <a href="https://stackoverflow.com/users/4231985/kkawabat" target="_blank"><i class="fab fa-stack-overflow"></i></a>
        <a href="https://github.com/kkawabat" target="_blank"><i class="fab fa-github"></i></a>
        <a href="https://www.linkedin.com/in/kan-kawabata-8b4106a2/" target="_blank"><i class="fab fa-linkedin"></i></a>
    </div>
</div>

However using innerHTML could be a security concern.

In summary, how do I get the same result as the first line of code but without unnecessary server request?


Solution

  • Try cloning the nodes directly. Perhaps:

    document.getElementById('content_div').replaceChildren(...document.getElementById('socials').cloneNode(true).childNodes);
    

    A slightly more concise version is possible if you use the HTML template element, which is designed for this type of scenario:

    document.getElementById('content_div').replaceChildren(document.getElementById('socials').content.cloneNode(true));
    
    <template id='socials'>
        <div class="Social-media fade-in">
            <a href="https://stackoverflow.com/users/4231985/kkawabat" target="_blank"><i class="fab fa-stack-overflow"></i></a>
            <a href="https://github.com/kkawabat" target="_blank"><i class="fab fa-github"></i></a>
            <a href="https://www.linkedin.com/in/kan-kawabata-8b4106a2/" target="_blank"><i class="fab fa-linkedin"></i></a>
        </div>
    </template>