Skip to main content Accessibility Feedback

How to load HTML from another page with vanilla JavaScript

I recently had someone email me asking about how to load HTML from another page with vanilla JavaScript, so that’s what we’re going to look at today.

Let’s dig in!

Progressive enhancement

Using JavaScript to load HTML from another page is great progressive enhancement.

Let’s imagine you have a dialog modal that loads some HTML. You might keep all that HTML in a separate file, and by default display a link to it.

<a href="/terms">Read the Terms of Service</a>

When your JS loads, you can progressively enhance it into a modal toggle.

let toggle = document.querySelector('[href="/terms"]');
toggle.setAttribute('role', 'button');
toggle.addEventListener('click', handleModal);
<!-- After the JS loads -->
<a role="button" href="/terms">Read the Terms of Service</a>

One that button is clicked, you can asynchronously grab the HTML from the /terms page and inject it into a dialog element.

Alternatively, maybe you’re building your own “HTML over the wire” kind of library where you grab and update the body without doing a hard page reload.

Aside: please don’t do that! I have, and there are so many little gotchas and annoyances. Just build multi-page apps!

Fetching HTML

To get HTML, you can use the fetch() method, just like you would for JSON or API calls.

Instead of running the Response.json() method when you get a successful response back, you’ll use Response.text(). This converts the response into a text string with your HTML.

fetch('/about').then(function (response) {
	if (response.ok) {
		return response.text();
	}
	throw response;
}).then(function (text) {
	console.log(text);
});

Once you have the HTML string back, you can inject it into the DOM using something like Element.innerHTML.

fetch('/about').then(function (response) {
	if (response.ok) {
		return response.text();
	}
	throw response;
}).then(function (text) {
	let dialog = document.querySelector('dialog');
	dialog.innnerHTML = text;
});

Getting portions of a page

What about situations where you only need on section of a return HTML string?

The DOMParser() method converts an HTML string into real HTML without rendering it in the actual DOM. We can use it to convert our string into HTML elements, look for the one we need, and then inject just that.

function stringToHTML (text) {
	let parser = new DOMParser();
	let doc = parser.parseFromString(text, 'text/html');
	return doc.body;
}

In the fetch() callback function, we’ll convert our string to HTML, and use the document.querySelector() method to find the element we care about.

fetch('/about').then(function (response) {
	if (response.ok) {
		return response.text();
	}
	throw response;
}).then(function (text) {
	let html = stringToHTML(text);
	let content = html.querySelector('#agreement');
});

Once we have it, we can use our favorite DOM injection method to add it to our UI.

fetch('/about').then(function (response) {
	if (response.ok) {
		return response.text();
	}
	throw response;
}).then(function (text) {
	let html = stringToHTML(text);
	let content = html.querySelector('#agreement');
	let dialog = document.querySelector('dialog');
	dialog.append(content);
});