Javascript Includes

Back in my day, inserting the menu on every page of your Freewebs site was as easy as adding a little SSI tag with the text you wanted inserted into your HTML file. However, Neocities does not allow for Server Side Includes. What is osmeone who wants to put their menu on every part of their page to do? You could use a Static Site Generator like Jekyll. You could make a template that inserts the menu into every page, and then upload the generated HTML files to Neocities. But what if you don't want to do that for some reason? Perhaps you like to update Neocities from 5 different computers and you don't want to have to have Jekyll installed on each one, or have to update your files on Github and then wait for Jekyll to deploy. What if you're a little insane? What if... we just used Javascript?

Indeed, using JavaScript to insert a menu into the page is one of the recommended options for someone wanting to keep their menu on every part of their Neocities site. Advantages are not needing to install anything and that it's pretty straightforward. Disadvantages are it won't work if your user has JS turned off and it's not clear how well it plays with accessibility. With this in mind, let's move forward, starting with the small idea of "let's make do Javascript includes" and build up to being able to do more customizable things with your site.

The basic idea is that you want some template that you can copy/paste on every HTML page you make. In this template, you will have your basic content where you write your lovely little articles. You'll also be able to change the title based on the name of the page. Other than that, we would prefer not to have to touch anything at all. We will include a link to CSS and a link to our script.

The script itself is pretty simple. Here is our first version of it:

   document.addEventListener("DOMContentLoaded", function () {
  const content = document.querySelector(".content");
  if (content) {
    const template = `
      
My Site
`; // Create a temporary element to modify the template const tempDiv = document.createElement("div"); tempDiv.innerHTML = template; // Insert the existing content inside the new structure const newContent = tempDiv.querySelector(".content"); if (newContent) { newContent.innerHTML = content.innerHTML; } // Replace the entire body with the new HTML structure document.body.innerHTML = tempDiv.innerHTML; } });

What we are doing here is we have a variable called 'template' which has the shape we want our final layout to have. I'm feeling nostalgic, so we will have a nice three-column website. The shape of the layout is, of course, entirely up to you. Then we create a div that will have our template as its inner HTML. At the start of the file, we looked for a div with the class "content." We then fetch the 'content' tag inside the NEW layout. If it was successfully created, we take the inner HTML of the source content div and dump it into the new content div. Now that the whole thing has been correctly formatted, we replace the whole body.

Your HTML pages can thus be very minimal:


      
      
        
          
          
          My Site
          
        
        
      
      
        
Welcome to my site. Please enjoy your stay.

Ugly Bounce Problem

But as you start creating new pages with this and navigating the site, you will notice something very annoying. For a split second, the content will load without the layout, and then snap into place. This is distracting! It goes away once the browser has cached the content, but it means you will see it for as long as the content isn't cached. How can we fix this?

Let's look at what's happening. There is basically a delay as the script waits for the content to load (DOMContentLoaded). However, when that content loads, since it's basically a plain HTML file without anything to force it into the correct position, the text appears at the upper left side of the screen instead of the center where we want it to be.

The solution is to mock aspects of the layout before the script has updated. Basically, instead of generating the left and right nav from scratch, we include dummy divs for the left and right nav in the HTML template. That way, those divs will be styled correctly when the site is first loaded. They will still be empty since we have to wait for the content to load to do anything, but your post will not suddenly bounce to a new location. This is much more pleasant.

This means our include script will become slightly more complicated. We now need to insert the menus into particular divs instead of just replacing the body wholesale.

Config Madness

Once you have internalized the idea that this little script can read and respond to things in the text, you slowly start to realize that there's a lot you can do with this. What if I wanted to add a table of contents to every page? Or what if I wanted to only add a table of contents to certain pages that had a particular text? All of this is, in fact, possible.

Limits

As mentioned above, you really are better off using an SSG for advanced configurations stuff like this. They are built for this purpose, they are more accessible, and they are arguably easier to use. The only reason to use this is if you are on a very limited platform like Neocities and you really want to go ham on your website's modifiability. However, if you have access to other tools or hosting sites, you should probably use those and save yourself the headache. Because we're only using one Javscript file, if you actually try to make all sorts of mad configs, you will end up with one very big file that will be hard to maintain and understand.