logo elektroda
logo elektroda
X
logo elektroda

Procedural creation of project pages on Github - free GH Pages hosting and node.js script

p.kaczmarek2  9 318 Cool? (+4)
📢 Listen (AI):
GitHub Pages deployments panel showing recent commits and deployed link .
GitHub Pages is a free hosting service that allows you to publish static HTML pages. However, it does not support running server-side scripts, which means no support for backend languages such as PHP, Python or Ruby. In this tutorial, I will show a potential way around this limitation - procedural HTML generation using Node.js via GitHub Actions.

Node.js is a server-side JavaScript runtime environment that allows us to create web applications, generate files and automate various processes. With Node.js, for example, we can write a script that dynamically creates static HTML files, which can then be published on GitHub Pages. In this way, we can, to a certain extent, 'simulate' a backend on a static host and, more precisely, generate all the expected pages 'for the future'.

GitHub Actions is a tool for automating processes in the GitHub repository. It allows the creation of so-called workflows that can run automatically, e.g. with each push to the repository.

The aim of the project is to automatically create device pages for my list of programmable IoT hardware . I already have one aggregate page-search engine that takes data from a JSON file and runs in the browser, but in addition I want each device to have a separate link with its own page.

This is where the first doubt arises - but how can Node.js if you can't run server-side scripts? Indeed, you can't run server-side scripts, but during changes to the repository you can run a one-time GitHub Workflow which will generate static HTML and save it to the gh-pages branch.

So the organisation of the repository will look as follows:
- branch main contains the main information we provide, the source data, in my example it will be a JSON file with device information
- branch gh-pages will be empty by default
- in addition, in branch main there will be a GitHub workflow which, at the time of each change in main, parses the JSON file and generates static HTML files and writes them to gh pages, which then publishes them on GitHub

Generate HTML locally (on your own computer) .
Let's consider the contents of the main branch. The most important file there is devices.json, here is an example of the contents:
Code: JSON
Log in, to see the code
.
It describes the devices for which we want to generate pages.
Now you can add the JS script that will do this.
We need in turn:
- clear the old GH Pages content
- load the devices.json file
- spell out each device object and generate HTML for it into a separate file to the gh-pages branch
Minimal example, deletion section:
Screenshot of JavaScript code clearing and recreating the gh-pages directory .
Loading JSON, creating a folder for the devices and iterating:

Node.js code snippet loading devices.json and processing devices .
Device processing function:
JavaScript code snippet generating HTML files for IoT devices
pageNameForDevice converts the name of the manufacturer and model of the device into a page name, and sanitizeFilename makes sure it is file system friendly. Not all characters can be in file names. We are left with createDeviceHTML. Here is an example implementation:
Code: Javascript
Log in, to see the code
.
. For clarity I have removed the HTML file - the latest version of the script can be seen here: https://github.com/OpenBekenIOT/webapp/blob/main/generate-devices.js .
The code above has a few features added from me, such as displaying the GPIO of the device, but this is not relevant to this example.

Now it's time to test how the system works - we run the script via node.js:

node generate-devices.js
.
The whole thing should execute correctly and generate files for our JSON database:
Screenshot of devices folder with HTML files generated for individual devices .


Generate HTML on GitHub (automatically with each change to the main branch) .
We have already developed the generation of HTML files for each device from a JSON file and tested this locally with Node.js. Now it's time to go one step further. GitHub allows us to automatically perform operations with every change on a branch, we can use this to automatically run our script and save the results to gh pages. This way every, even the smallest, change to the data in devices.json will update our documentation.
We create a file .github/workflows/gh-pages.yml :
Code: text
Log in, to see the code
.
Let's consider the operation of this script. The script is called after a push to the main branch. Then, on a machine with the latest version of ubuntu, first Node.js is installed and then the script developed earlier is executed. The results are then saved to gh-pages, i.e. published on GitHub.

Verified working on GitHub .
Let's see how this works in practice. I've added some changes via the GitHub GUI:
GitHub editor view showing changes in generate-devices.js file .
A commit with a "bird" appears on GitHub:
Screenshot of GitHub repository “webapp” with active “main” branch shown .
In the preview we have information about the success of the deploy operation:
GitHub Actions notification: Deploy Device Pages completed successfully .
In the details we have the entire log of the operation:
View of completed GitHub Actions job showing step list and execution times .
Now we can look at the gh-pages branch:
Dropdown menu showing main and gh-pages branches in a GitHub repository .
There is a devices folder generated on it:
GitHub repo view showing “devices” folder in the gh-pages branch .
Our HTML files are also in it:
List of device HTML files in the devices folder on the gh-pages branch on GitHub .


Final result .
The HTML itself is beyond the scope of this presentation, so I'll just write that I also modified the search engine to link to the generated device pages. The result is available here:
https://openbekeniot.github.io/webapp/devicesList.html
Example device page:
https://openbekeniot.github.io/webapp/devices/Tuya_ATLO_SW1_TUYA.html
From now on, each device has its own page where I can additionally display configuration tips and links to related topics on Elektroda.

Direct link to the repository (for reference):
https://github.com/OpenBekenIOT/webapp

Summary .
GitHub only offers hosting of static HTML code, but clever use of GitHub Actions allows you to automatically pregenerate any kind of page which then mimics a site with a dynamic backend. For finer work, on the other hand, you can harness JavaScript, on which my main search engine is based - fully client-side. I think this is a convenient and practical solution and will probably use it more than once.
PS: In a separate topic I will show how the same mechanism can be used to automatically generate project documentation.
PS2: Anticipating the question - I put the code snippets as images due to the limitations of our forum. Javascript was turning on spam protection and I couldn't save the topic....

About Author
p.kaczmarek2
p.kaczmarek2 wrote 12696 posts with rating 10496 , helped 593 times. Been with us since 2014 year.

Comments

gulson 04 Sep 2025 15:42

Very interesting. Github Pages is often just used as free hosting for static pages. I would add that Cloudflare Pages is also often considered together with Cloudflare Workers (for executing simple JS... [Read more]

p.kaczmarek2 04 Sep 2025 16:28

And let's not forget GitHub Actions - it's an equally powerful tool. GitHub Actions essentially provides us with a clean virtual machine with a repository where we can perform any operation, including... [Read more]

divadiow 04 Sep 2025 18:50

cool. I notice though that the new pages do not contain the wiki links, relying on the user to check the link on the main device list to get to the topic for that device. On a related note, TuyaMCU... [Read more]

p.kaczmarek2 04 Sep 2025 19:07

What do you mean? The wiki links are at the end of new page: https://openbekeniot.github.io/webapp/devices/Generic_ZN268131.html I can also make device name clickable. Regarding TuyaMCU - you are... [Read more]

divadiow 04 Sep 2025 19:25

apologies, yes, that's quite obvious. Added after 15 [minutes]: I've been vibe coding with overrides. Here's a summary of changes seen in here https://github.com/divadiow/OpenBekenIOT-webapp/blob/main/devicesList.html ... [Read more]

p.kaczmarek2 05 Sep 2025 09:23

not bad... would it work if I type "BK7231" in search box? Show only BK7231 T and N devices? And U... if present. [Read more]

divadiow 05 Sep 2025 18:09

seems so https://obrazki.elektroda.pl/5612536500_1757088549_bigthumb.jpg [Read more]

p.kaczmarek2 05 Sep 2025 20:41

Ok, now, what happened to keywords? Why they look like JSON array? They are okay in currently live version. https://openbekeniot.github.io/webapp/devicesList.html [Read more]

divadiow 05 Sep 2025 22:53

oh yeh! didn't spot that. hmm ok Added after 2 [hours] 11 [minutes]: i've been playing a bit more. [Read more]

%}