How can I inject a standard script into my HTML files using Node.js?

Asked

Viewed 186 times

1

I am creating a server with Express in Node.js where each HTML page is different but has the same Javascript code on <head> of the document.

What I want to do is write this Javascript code once to inject it into all my HTML files without needing to change anything on my server.

I’d like to do something like this:

app.get("/", (request, response) => {
    const filename = path.resolve("templates/index.html");
    const jsCode = getDefaultCode();

    const content inject(filename, jsCode);

    response.send(content);
});

Upshot:

<!doctype html>
<html>
    <head>
        <title>Meu arquivo HTML</title>
        <meta charset="UTF-8">
        <script>
            // Código injetado.
        </script>
    </head>
    <body>...</body>
</html>

I know there’s a package called handlebars, but it seems to be quite complex and I would like something very simple just to inject my Javascript code into the HTML files.

    1. You can use regex to seek a term <title>, for example, and add the code after the term; 2) You can use template engine as haml, ejs, vuexpress etc..

1 answer

1


As placed in comments, you can use regular expressions for this.

You can also, for example, edit your file and include some "special comment", which we will use to restore by the script to be injected. Something like that:

<!DOCTYPE html>
<html>
  <head>
    <title>Hello, world!</title>
    <meta charset="UTF-8" />
    <!-- inject::script -->
  </head>
  <body>
    Hello, world!
  </body>
</html>

You can then create a function to encapsulate this behavior:

function injectScript(file, script) {
  return file.replace('<!-- inject::script -->', `<script>${script}</script>`);
}

And just pass the contents of the file:

const { promises: fs } = require('fs');
const path = require('path');
const app = require('express')();

const filePath = path.join(__dirname, 'template.html');

const script = `
  window.addEventListener('load', () => {
    document.body.style.color = 'rgb(255, 0, 0)';
  });
`;

function injectScript(file, script) {
  return file.replace('<!-- inject::script -->', `<script>${script}</script>`);
}

app.get('/', async (req, res) => {
  try {
    // Obter o HTML:
    const file = await fs.readFile(filePath, 'utf8');

    // Injetar o script:
    const injected = injectScript(file, script);

    // Enviar o HTML com o script injetado:
    res.send(injected);
  } catch (error) {
    res.send(`Whoops. Erro: ${error.message}.`);
  }
});

const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Listening at port ${port}.`));

See working on Codesandbox.

Note that if you can’t edit the templates to add the comment, just use some tag who will always be in the <head> as a point of reference instead of a comment. In my opinion, </head> is the simplest to be used in this case.

Thus:

function injectScript(file, script) {
  return file.replace('</head>', `<script>${script}</script></head>`);
}

Note in the example above that we exchange </head> by a script tag and the closing of the </head> right away.

You can also use the calls template Engines, that help you do this more easily. Nunjucks is the simplest in my opinion, with an inspired syntax of template engine jinja2 by Python.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.