I’m currently developing a conversational AI web application. I’ve been building it completely from scratch, following a structured SDLC approach.
Right now, I’m in Phase 3: Frontend Interactivity, where I'm working on dynamically rendering chat messages.
Initially, I took a common approach: use insertAdjacentHTML()
to append user and AI message bubbles directly into the DOM. It worked, but my JavaScript file became messy with chunks of repetitive HTML.
Here’s what that looked like.
⛔ The Problem: Too Much HTML in JavaScript
<div id="messages-container"></div>
const messagesContainer = document.getElementById('messages-container');
const messageHTML = `
<div class="flex justify-start mb-4 animate-slide-in">
<div class="bg-gray-100 dark:bg-gray-800 rounded-lg px-4 py-2 max-w-[70%]">
<p class="text-gray-800 dark:text-gray-200">${text}</p>
</div>
</div>
`;
messagesContainer.insertAdjacentHTML('beforeend', messageHTML);
This worked fine for a single message type, but once I needed to handle AI messages (with a different layout), I realized I was duplicating the same structure in multiple places.
It lacked simplicity. It was not scalable.
I required a method to differentiate between logic (JS) and structure (HTML) that was easier to maintain.
At that point, I discovered the <template>
tag, a native feature.
✅ The Solution: <template>
Tag
It allows you to define reusable HTML sections that remain inactive until you purposefully use JavaScript to render them.
In simpler terms:
The browser parses the HTML inside , but doesn’t display it.
You can clone its content with JS using
template.content.cloneNode(true)
whenever you need to render it dynamically.
By doing this, you can create clear, declarative HTML and then use it in your scripts without messing up your JS files with raw HTML strings.
Here’s the structure.
<template id="user-message-template">
<div class="flex justify-start mb-4 animate-slide-in">
<div class="bg-gray-100 dark:bg-gray-800 rounded-lg px-4 py-2 max-w-[70%]">
<p class="text-gray-800 dark:text-gray-200 message-text"></p>
</div>
</div>
</template>
<div id="messages-container"></div>
🛠️ How It Works
When the browser encounters a , it parses the markup but doesn’t render it.
This means:
The content inside doesn’t appear in the DOM.
Scripts or images inside it won’t execute or load.
It quietly waits to be cloned when its turn comes.
To use it, clone the content of the template by capturing it via JavaScript:
const messagesContainer = document.getElementById('messages-container');
const userTemplate = document.getElementById('user-message-template');
function addUserMessage(text) {
// Clone the content of the template
const messageClone = userTemplate.content.cloneNode(true);
// Modify the cloned node
messageClone.querySelector('.message-text').textContent = text;
// Append it to the container
messagesContainer.appendChild(messageClone);
}
// Example usage
const btn = document.getElementById('sendBtn');
btn.addEventListener('click', function () {
addUserMessage('This is test user message');
});
Your HTML is now scalable, readable, and modular.
There won't be any messy HTML duplication in my JavaScript if I decide to add an AI message later. I can just define a different template with a slightly different style.
🧐 Why is this important?
Cleaner: JS doesn't contain any HTML strings.
More maintainable: Structure can be easily changed without affecting logic.
Safer: Less likely to have injection problems or malformed HTML
Scalable: Easily adjusts to more complex message formats.
These small improvements add up in a real-world chat application, especially one that goes through several stages of development.
This structure maintains consistency and helps with debugging as the UI grows.
🔚 Conclusion
The <template>
tag quietly addresses a practical issue: keeping markup and logic separate in dynamic UI.
It transformed a messy part of JavaScript into a clear, reusable system for my project.
What's the best part? There is no need for additional dependencies because it is pure JavaScript.
Sometimes, the cleanest solutions are already built into the browser. You just need to look closely.
Top comments (38)
⛔ The Problem: Too Much HTML in JavaScript
I'd say the problem is using the wrong HTML
Every
<div>
can be replaced with a Custom Elementdashed-html.github.io
Thanks for sharing. I will check it out
Sure, the issue you brought in and how you solved it, is great and I learned from it.
But when I read 'JavaScript file became messy ', then I guess you use a single js file?
Just as an advice.
With a module approach and a proper file structure your js flles hardly becoming messy at all and are better maintainable too.
Thanks for the advice! I’m currently in the early stage of development, focusing on frontend interactivity, so I’m using a single JS file for now. I do plan to refactor it into modules soon for better structure and maintainability.
It's funny, there is so much hate for PHP because of the mixed code/markup, but sure, do it in JS and suddenly it's a good thing 🤣
A little late but for sure I do like PHP very much and I used to do a lot with it.
At present not at all but that's for another reason.
Then, Yes the reason that I like to use JS in a modular way has all to do with my PHP experiences because with that, having a proper file structure is a standard.
Fantastic article, Richa!! I love how you showcased the power of the tag — it’s such an underrated gem in HTML. Your example perfectly demonstrates how it streamlines JavaScript, keeps code cleaner, and boosts scalability. It’s refreshing to see elegant, native solutions that reduce complexity without extra libraries. Definitely inspired to refactor some code now!
Glad you find this useful. And yeah, it's amazing how simple native features can make such a big difference.
If you think this is good, you should check out JSRender. Basically offers the ability to separate HTML from JS creating reusable templates, but also lets you push a JS array or object into it and handles all of the content placement.
jsviews.com/#jsr-quickstart
Thanks for sharing. I will look into that.
When a person code in spring boot for almost 2 years no front end touched, then even basic html tag looks too much scary :(
Haha, switching back to the frontend after backend work feels like entering a different world. 😄
that's huge! in 3 years using HTML, never heard of this tag one single time. i wonder how long it was hidden from me 😂
Haha, same here! I hadn’t come across this tag until recently. When I needed to create a dynamic UI and my HTML started getting too lengthy to manage in JS, I looked for alternative approaches online, and I’m glad I discovered this underrated HTML feature!
If you are amazed by template, React will blow your mind
Yeah. React indeed is best. But it is about how a built-in feature can have the capability to solve issues or implement features without any library or framework.
If you are amazed by React, Custom Elements will blow your mind!
In vue js the template tag is heavily used .but does it does not work in the same way.
So if I want to use template tag in vue how do I do it.
This might cause conflicts. ( although this template tag is really not needed in frontend framework. Just curious 🤔)
I’m not very familiar with Vue.js, but you’re right, tag works differently there and might conflict with the native one.
Great post, Richa! This is truly useful when optimizing web applications!
Glad you find this useful!
I hate writing JS (in any form), but found myself having to do so for work lately. This was actually a pretty useful post. Thanks!
Thanks for appreciating! Glad you find this useful.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.