How do I add certain script tags inside <head> and <body> tags when using HtmlWebackPlugin

how to include external javascript in html
html-webpack-plugin add script tag
where to place script> tag in html
script tag not working in html
script tag at the end
inside which html element do we put the javascript
script tag at end of html
script tag before body

I'm using HtmlWebpackPlugin to generate HTML files with javascript.

Now I would like to add custom script at different parts of <head> and <body> tags

Example:

How do I,

  1. Add <script> alert('in head tag') </script> inside the <head> tag as the first child
  2. Add <script> alert('in body tag') </script> inside the <body> tag as the first child

Here is the snippet in my Webpack config

        new HtmlWebpackPlugin({
        hash: true,
        chunks: ["app"],
        filename: path.resolve(__dirname, "./public/pages/app.html"),
        title: "Title of webpage",
        template: path.resolve(__dirname, "./src/pages/app.page.html"),
        minify: {
            collapseWhitespace: true
        }
    })

Your question is a bit confusing. It implies you want to add static script tags to your template. If that's the case you just need to go into your src/pages/app.page.html file and add those two script tags in the head and body.

What I'm guessing that you're asking is "How do I insert generated bundles in two different areas of my template?". If that's the case there's a section in the docs that mentions what data is passed to the template file:

"htmlWebpackPlugin": {
  "files": {
    "css": [ "main.css" ],
    "js": [ "assets/head_bundle.js", "assets/main_bundle.js"],
    "chunks": {
      "head": {
        "entry": "assets/head_bundle.js",
        "css": [ "main.css" ]
      },
      "main": {
        "entry": "assets/main_bundle.js",
        "css": []
      },
    }
  }
}

So if your entry looked like

entry: {
  head: './src/file1.js',
  body: './src/file2.js',
}

and your plugin was set to

new HtmlWebpackPlugin({
  template: './src/pages/app.page.ejs' // note the .ejs extension
})

then app.page.ejs should be able to access the data from the plugin and you can place those entries where ever you'd like. There's a large ejs example file in their repo. A simpler example, and one more specific to your use case would be:

<!DOCTYPE html>
<head>
  <% if(htmlWebpackPlugin.files.chunks.head) { %>
  <script src="<%= htmlWebpackPlugin.files.chunks.head.entry %>"></script>
  <% } %>
</head>
<body>
  <% if(htmlWebpackPlugin.files.chunks.body) { %>
  <script src="<%= htmlWebpackPlugin.files.chunks.body.entry %>"></script>
  <% } %>
</body>
</html>

Note that I'm not using files.js but rather files.chunks since you can access single files by entry name instead.


Multi-Page Set-Up

For a multi-page set-up your WP config could look like

const pages = [
  'home',
  'about',
];

const conf = {
  entry: {
    // other entries here
  }
  output: {
    path: `${ __dirname }/dist`,
    filename: 'scripts/[name].js'
  },
  plugins: [
    // other plugins here
  ]
};

// dynamically add entries and `HtmlWebpackPlugin`'s for every page
pages.forEach((page) => {
  conf.entry[page] = `./src/pages/${ page }.js`;
  conf.plugins.push(new HtmlWebpackPlugin({
    chunks: [page],
    // named per-page output
    filename: `${ __dirname }/dist/pages/${ page }.html`,
    googleAnalytics: { /* your props */ },
    // shared head scripts
    headScripts: [
      {
        src: 'scripts/jQuery.js'
      },
      {
        content: `
          console.log('hello world');
          alert('huzah!');
        `
      }
    ],
    // per-page html content
    pageContent: fs.readFileSync(`./src/pages/${ page }.html`, 'utf8'),
    // one template for all pages
    template: './src/pages/shell.ejs',
  }));
});

module.exports = conf;

The template would look something like

<!DOCTYPE html>
<head>
  <%
    for (var i=0; i<htmlWebpackPlugin.options.headScripts.length; i++) {
      var script = htmlWebpackPlugin.options.headScripts[i];
  %>
  <script
    <% if(script.src){ %>src="<%= script.src %>"<% } %>
  >
    <% if(script.content){ %><%= script.content %><% } %>
  </script>
  <% } %>
</head>
<body>
  <% if(htmlWebpackPlugin.options.pageContent) { %>
  <%= htmlWebpackPlugin.options.pageContent %>
  <% } %>

  <% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
  <script src="<%= htmlWebpackPlugin.files.chunks[chunk].entry %>"></script>
  <% } %>

  <% if (htmlWebpackPlugin.options.googleAnalytics) { %>
  <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    <% if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
      ga('create', '<%= htmlWebpackPlugin.options.googleAnalytics.trackingId%>', 'auto');
      <% } else { throw new Error("html-webpack-template requires googleAnalytics.trackingId config"); }%>
    <% if (htmlWebpackPlugin.options.googleAnalytics.pageViewOnLoad) { %>
      ga('send', 'pageview');
    <% } %>
  </script>
  <% } %>
</body>
</html>

Where to put your script tags in Javascript, Some advocate putting the SCRIPT tags in the BODY section, right at the end. Like this: Javascript tags in the BODY section of a HTML page. The reason to do it  It is possible to execute JavaScript via innerHTML without using <script> tags as illustrated on MDN's innerHTML page. Solution: Dynamically adding scripts. To dynamically add a script tag, you need to create a new script element and append it to the target element. You can do this for external scripts:

You can use template parameters like shown in the official example

var path = require('path');
var HtmlWebpackPlugin = require('../..');
var webpackMajorVersion = require('webpack/package.json').version.split('.')[0];
module.exports = {
  context: __dirname,
  entry: './example.js',
  output: {
    path: path.join(__dirname, 'dist/webpack-' + webpackMajorVersion),
    publicPath: '',
    filename: 'bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      templateParameters: {
        'foo': 'bar'
      },
      template: 'index.ejs'
    })
  ]
};

How To Add JavaScript to HTML, In order to achieve this, we will add a <script> tag along with some JavaScript code into the HTML file. To begin with, we'll add the JavaScript  Adding JavaScript to a page. You can add a script anywhere inside the head or body sections of your document. However, to keep your document well structured there are some basic guidelines: Most scripts can go inside the document head. This keeps them out of the way of the main document content.

Best Practice: Where to include your <script> tags, I have read in some places that for best performance we should include <script> elements at the end of our body tags, also, I have read that it's  You can add JavaScript code in an HTML document by employing the dedicated HTML tag <script> that wraps around JavaScript code. The <script> tag can be placed in the <head> section of your HTML, in the <body> section, or after the </body> close tag, depending on when you want the JavaScript to load.

Gotchas with dynamically adding script tags to HTML, Prev Post Next Post. Sometimes you need to dynamically add a script tag to HTML. But there are some gotchas that might get you if you don't know to look out for them. Gotcha #1: No script tags in innerHTML. It turns out that  The <script> tag is used to define a client-side script (JavaScript). The <script> element either contains scripting statements, or it points to an external script file through the src attribute. Common uses for JavaScript are image manipulation, form validation, and dynamic changes of content.

Script tag, Any type of client side script can be written inside <script> tag in html. also write JavaScript code in a separate file with .js extension and include it in a web page using <script> tag and reference the file via src attribute. Some HTML here. External scripts are practical when the same code is used in many different web pages. JavaScript files have the file extension .js. To use an external script, put the name of the script file in the src (source) attribute of a <script> tag:

Where should JS <script> tags be linked in HTML documents , It is a best practice to put JavaScript <script> tags just before the closing </body> tag rather than in the <head> section of your HTML. Click to expand You have to set a tag in the tag manager beforehand and then, in the script, you can assign it (for example, if you take a key you can change the tag of doors from "Closed" to "Open", as long as the "Open" tag exists in the tag manager).

Everything I Know About The Script Tag - Eager Blog, A script tag can either include the JavaScript directly, or it can point to a URL Those tags will load whenever the browser sees fit, and in no particular order. A Detailed Breakdown of the <script> Tag When the <script> tag was originally introduced, it was used to add only the most basic level of interactivity to web pages. But the web has changed a lot

Comments
  • Just like any other element
  • Thanks for the comment Adelin . Can you be a little more specific on how I can achieve this.
  • I came across the same issue. You can use this - npmjs.com/package/html-webpack-injector
  • I sincerely thank and appreciate the effor you have put in asnwering my question. I'm already been doing this, my usese case is how do I inject snippets of <script> tags with embedded js code in it into my html files. My use case: I have a multi page site and I would like to insert same, <script> snippet say it Google Analyitics into multiple pages at the <head> and <body> tags with js code embedded in it.
  • @sujeetb Perhaps I'm missing something. Your Code snippet implied that you have only one page that's being generated. I and the other replier mentioned how to add a static script entry - just open your template and inline it. It sounds like you want something like Handlebar's partial mechanism which would allow for sharing the same content in multiple files.
  • @sujeetb I've amended my original answer and added a Multi-Page Set-Up section. See if that'll do the trick for you.
  • That's a super cool answer and this absolutely works for me. Apologies for the question, but is there a way by which I could inject GoogleAnalyitics script into portions of the page without actually changing the templates. I'm sorry if it doesn't make any sense at call, I just didn't want to change templates all the time and rather change the config file for such purposes. Here is my webpack config jsbin.com/ruleqekake/2/edit?js
  • @sujeetb sure. In the example I posted you'll see a block for htmlWebpackPlugin.options.googleAnalytics you can put whatever you want in that Object and then key off of that in the template. For example, in the template you could just have if( htmlWebpackPlugin.options.googleAnalytics.headScript) and then in the WP config you can have a template literal with whatever you want, or use fs.readFileSync to read a file in. You can also create a <script> entry in the template that just points to a JS file that you can alter when ever.
  • I sincerely thank and appreciate the effor you have put in asnwering my question. I'm already been doing this, my usese case is how do I inject snippets of <script> tags with embedded js code in it into my html files. My use case: I have a multi page site and I would like to insert same, <script> snippet say it Google Analyitics into multiple pages at the <head> and <body> tags with js code embedded in it.
  • If you need Google analytics - open the src/pages/app.page.html in your favorite editor and put the desired script tag and its js code embedded in it just before the closing </head> tag or before the </body> tag. If you do not have such tags in your template - then simply add them.
  • This did not work for me. All scripts were added to body, even the "_head" one
  • I tried it too, and it didn't seem to do anything.
  • @Gordon Did you add new HtmlWebpackInjector() in your plugins array?
  • @ArchitGarg I did, but I didn't seem to recongize the _head file. I've taken a different approach.