loading html from external files
so i want to break down my home page into smaller chunks of html while still displaying it all on the same page, and i'm going to use javascript to do it.
im sure lots or people have done this before and many will do it again, but this is my version. you know, make what you need and all that.
why?
- smaller files are more manageable and more easily-updatable
- i'll be able to use snippets of code (like my button wall and unsorted links feed) on multiple pages without duplicating the content
other ways to do it
- server-side scripting using a language like PHP or
PERLPython (not available on static hosting providers like Neocities.) - server-side includes, available on Nekoweb and other hosts, but sadly not on Neocities.
<iframe>. a pure-html solution, but not really because i'd still have to use javascript to control the size (if i want to avoid having loads of those scrolly boxes all over the place.)- static site generation (i.e. automating the build of your web site before you upload it.) i'm not using one, though, so probably won't do it this way.
- use JavaScript templates, as (excellently) described by petrapixel. yeah, i could do that but this is content not extra navigation and it seems weird to have it all wrapped up in code.
so what im going to do is:
- move the content to smaller, stand-alone html files.
- load the html files using javascript
fetch(im already using it for my updates feed which is XML, but the technique should work the same for HTML) - insert the loaded html code into a div on the page wherever i need it.
considerations
- simple configuration: try to keep it as easy as possible to add to new pages.
- non-javascript fallback: as with anything js-powered, there needs to be some sort of alternative if the visitor has javascript turned off or the code fails at runtime for some reason.
- it would be cool if the master snippet pages were actually visitable (if not necessarily pretty) by their direct url. because, you know, that can act as the no-js fallback.
setup
the container
the target is just a div containing a hyperlink:
<div class="loadexternal">
<a href="/clubs/kitty.html">kitties</a>
</div>
the link points to the page you want to load.
the external content
the content needs to be placed inside the <main></main> tags of a stand-alone html page. anything else on the page will be ignored. for an example of one of these files, see /clubs/kitty.html.
the javascript
loadexternalstuff.js
// runs asynchronously when page ready
document.addEventListener("DOMContentLoaded", (event) => {
async function loadExternalStuff()
{
try
{
// find all the divs with class="loadexternal"
const selector = ".loadexternal";
const divs = document.querySelectorAll(selector);
for(const div of divs)
{
// find a hyperlink inside the div
const a = div.querySelector("a");
if(a)
{
// load html from the url
const url = a.href.toString();
const response = await window.fetch(url);
if(!response.ok)
{
console.log(response.status);
// if the html failed to load, skip forward to the next div
continue;
}
// convert the html to a dom object
const raw = await response.text();
const dom = new DOMParser()
.parseFromString(raw, "text/html");
// grab the contents of <main> and ignore everything else
const mainHtm = dom.querySelector("main")
.innerHTML;
// replace everything in the div with the new code
div.innerHTML = mainHtm;
}
}
}
catch (error)
{
console.dir( "Error loading XML:" + error );
console.dir(error);
}
}
loadExternalStuff();
});
(you shouldn't need to change the js code to use it, but feel free to do so.)
how it works
the code:
- looks for any
<div>with classloadexternal, - grabs the url of the first hyperlink in the div,
- replaces the div contents with html loaded from the url.
demo
here are some cute kitty pixels loaded in from my master page at /clubs/kitty.html
if it worked you should see some pretty kitties. if it didn't work (eg. javascript is switched off) you should still see a plain link to the kitty master page!
notice the meta data, header, and footer were discarded after loading, i only capture the <main> element.
conclusion
well, it works on my machine, so i guess that's it! by the time i had finished writing these notes i'd already deployed the code in various places around the site. and it's already made things more maintainable!
what's it doing?
on the home page, unsorted links are loaded from unsorted.html and the button wall is loaded from neighbours.html
in the dog+house, kitty pixels are loaded from kitty.html
