GitHub provides us an easy way of embedding gists on a web page. When we navigate to a gist on GitHub, there is a drop-down list element with the default option named "Embed". The value of this is an HTML <script>
tag. The src
attribute of this <script>
tag is nothing but simply the GitHub Gists URL of this gist, with .js
appended to it. When we navigate to this URL (the one that ends with .js
), we observe that this is a JavaScript source file with two document.write
statements. The first document.write
statement adds an HTML <link>
element for the CSS of the embedded gist. The second document.write
is the gist itself.
Embedding gists this way is acceptable for one or two gists (although still being a bad approach) but for more gists, it simply results in a polluted HTML and needless HTTP GET requests for each gist embed link (the HTTP GET requests to the relevant JavaScript files). In other words, every visit to your web page will result in multiple (as many as the number of gists you have) HTTP GET requests to be made to the gist embed scripts (the JavaScript files). This is a waste of network and hardware resources because in order to obtain the exact same output, every visitor will make the exact same HTTP requests and their browsers will process (execute) the script and add (write) the elements to the document.
A much more reasonable way of doing this is to simply make the HTTP requests to the embed scripts on the back-end, process (execute) the scripts on the back-end and generate a static web page as the output and serve this web page whenever a visitor would like to access that web page. This way, instead of making network requests and processing (executing) embed scripts numberOfVisitors * numberOfYourGists
times, you will make them only once, which is numberOfYourGists
times and serve the visitors a static web page which has already been populated with your embedded gists.
The benefit of "embedding gists on the back-end" this way are:
- Huge savings on network and hardware resources.
- A much faster (quicker) render of the web page.
- Users that have their JavaScript disabled can view your gists.
- Much cleaner (neat, tidy) HTML output.
- Much more control on the HTML output since instead of relying on
document.write
statements, we pick where exactly to place the gists.
Without further ado, the following is the code to embed gists to a web page on the back-end, generating a static web-page:
const GITHUB_USERNAME = 'ugultopu';
// Helper function to perform an easier GET request.
function get(link, options, callback) {
if (!callback) {
callback = options;
options = {};
}
require('https').get(link, options, response => {
let data = '';
response.setEncoding('utf8');
response.on('data', chunk => data += chunk);
response.on('end', () => callback(data));
}
);
}
get(
`https://api.github.com/users/${GITHUB_USERNAME}/gists`,
{headers: {'User-Agent': ''}},
data => {
const gistEmbedLinks = getGistEmbedLinks(data);
let stylesheetLink;
const gistElements = new Array(gistEmbedLinks.length);
for (let i = 0; i < gistEmbedLinks.length; i++) {
get(gistEmbedLinks[i], embedScript => {
const scriptData = [
...embedScript.matchAll(/document\.write\((.*)\)/g)
];
stylesheetLink = eval(scriptData[0][1]);
gistElements[i] = eval(scriptData[1][1]);
/**
* Alternatives to the lines above:
*
* Alternative 1
* =============
* stylesheetLink = new Function(`return ${scriptData[0][1]}`)();
* gistElements[i] = new Function(`return ${scriptData[1][1]}`)();
*
* Alternative 2
* =============
* eval(`
* stylesheetLink = ${scriptData[0][1]};
* gistElements[i] = ${scriptData[1][1]};
* `);
*
* etc.
*/
// After all gists have been obtained
if (!gistElements.includes(undefined)) {
require('fs').writeFile(
'myGists.html',
`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
${stylesheetLink}
<style>
.gists {
max-width: 80ch;
margin: auto;
}
</style>
<title>All my GitHub Gists</title>
</head>
<body>
<div class="gists">
${gistElements.join('\n')}
</div>
</body>
</html>
`,
() => console.log('Write complete!')
);
}
});
}
}
);
function getGistEmbedLinks(data) {
return JSON.parse(data).map(
gist => `https://gist.github.com/${GITHUB_USERNAME}/${gist.id}.js`
);
}