skip to Main Content

I’m working on a project where I’m using webpack to bundle my assets and process my JavaScript files. The project uses Pug (formerly known as Jade) as the templating engine for generating HTML. However, I’m encountering an issue where the link and meta tags in the head section of my Pug templates are being misplaced in the rendered output.

I have checked my webpack configuration and couldn’t find any obvious issues that could directly cause this problem. The link and meta tags are defined correctly in the Pug templates, and the webpack configuration seems to be properly bundling the assets and JavaScript files.

I have also reviewed the structure of my Pug templates, ensuring that the head section is defined correctly and that there are no typos or misplaced tags. I’m using template inheritance in some cases, and I’ve confirmed that the block tags for the head section are placed correctly in both the base template and the child templates.

Additionally, I have verified that the variables I’m passing to the Pug templates contain the necessary data for rendering the link and meta tags. I’m not seeing any typos or missing data that could affect the rendering of these tags.

I suspect that the issue might be related to the interaction between webpack and Pug, but I’m unsure about how to proceed with troubleshooting and resolving this problem. I would appreciate any insights or suggestions on how to fix this issue and ensure that the link and meta tags are correctly placed in the head section of my Pug templates when using webpack.


Here are some relevant code snippets:

webpack.config.js:

import path from "path";
import webpack from "webpack";
import { fileURLToPath } from 'url'
const { DefinePlugin } = webpack;
import CopyWebpackPlugin from "copy-webpack-plugin";
import MiniCssExtractPlugin from "mini-css-extract-plugin";
import ImageMinimizerPlugin from "image-minimizer-webpack-plugin";
import TerserPlugin from "terser-webpack-plugin";
import WebpackAssetsManifest from "webpack-assets-manifest";

const IS_DEVELOPMENT = process.env.NODE_ENV === "dev";
const __dirname = path.dirname(fileURLToPath(import.meta.url))

console.log(path.join(__dirname, "views ========================================================="));

const dirApp = path.join(__dirname, "app");
const dirShared = path.join(__dirname, "shared");
const dirStyles = path.join(__dirname, "styles");
const dirNode = "node_modules";

export default {
  entry: {
    app: path.resolve(__dirname, "app/index.js"),
    styles: path.resolve(__dirname, "styles/index.scss"),
  },

  resolve: {
    modules: [dirApp, dirStyles, dirShared, dirNode],
  },

  plugins: [
    new DefinePlugin({
      IS_DEVELOPMENT,
    }),

    new CopyWebpackPlugin({
      patterns: [
        {
          from: "./shared",
          to: "",
        },
      ],
    }),

    new MiniCssExtractPlugin({
      filename: "[name].css",
      chunkFilename: "[id].css",
    }),

    new WebpackAssetsManifest({
      output: "manifest.json", // file name for the manifest file
      publicPath: "/", // public path to prefix filenames with
      writeToDisk: true, // write manifest file to disk
    }),
  ],

  module: {
    rules: [
      {
        test: /.js$/,
        use: {
          loader: "babel-loader",
        },
      },

      {
        test: /.scss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: "",
            },
          },
          {
            loader: "css-loader",
          },
          {
            loader: "postcss-loader",
          },
          {
            loader: "sass-loader",
          },
        ],
      },

      {
        test: /.(jpg|svg|png|gif|woff2?|fnt|webp)$/,
        loader: "file-loader",
        options: {
          name(file) {
            return "[hash].[ext]";
          },
        },
      },

      {
        test: /.(jpe?g|png|gif|svg)$/i,
        type: "asset",
      },

      {
        test: /.(glsl|frag|vert)$/,
        loader: "raw-loader",
        exclude: /node_modules/,
      },

      {
        test: /.(glsl|frag|vert)$/,
        loader: "glslify-loader",
        exclude: /node_modules/,
      },
    ],
  },
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin(),
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            plugins: [
              "imagemin-gifsicle",
              "imagemin-mozjpeg",
              "imagemin-pngquant",
              "imagemin-svgo",
            ],
          },
        },
        // Disable `loader`
        loader: false,
      }),
    ],
  },
  output: {
    path: path.resolve(__dirname, 'public'),
    filename: '[name].js'
},
};

Pug base template:

block variable
block content

doctype html
html(lang="en")
    head
        meta(charset="UTF-8")
        meta(name="viewport" content="width=device-width, initial-scale=1.0")
        base(href="/")
        title Floema
        meta(name="description" content="placeholder text for base html")
        link(href="main.css" rel="stylesheet")
    body
        include ./partials/preloader
        include ./partials/navigation
        .content#content(data-template=template)
            block content

detail pug template

extends ../base.pug 

block variable
  - var template = 'detail'

block content
  .detail
    .detail__wrapper
      figure.detail__media 
        img.detail__media__image(alt=product.data.image.uid src=product.data.image.url)

rendered webpage on firefox

<body>
   <div class="detail">
      <div class="detail__wrapper">
         <figure class="detail__media"> <img class="detail__media__image" src="https://images.prismic.io/floemasa/6265cead-447f-413f-9375-bdf830118a3a_Collanina+Vita+Piccola+%28lato%29-1.png?auto=compress,format"></figure>
      </div>
   </div>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <base href="/">
   <title>Floema</title>
   <meta name="description" content="placeholder text for base html">
   <link href="main.css" rel="stylesheet">
   <style class="darkreader darkreader--sync" media="screen"></style>
   <div class="preloader">
      <p class="preload__text">
         <title>surprise of what is possible to make with a simple and thin thread.</title>
      </p>
      <div class="preload__number">0%</div>
   </div>
   <nav class="navigation">
      <div class="navigation__wrapper">
         <a class="navigation__lionk" href="/">
            <title>Floema </title>
            <svg class="navigation__link__icon"> </svg>
         </a>
         <ul class="navigation__list">
            <li class="navigation__list__item"> <a class="navigation__list__link" href="/about">About </a></li>
            <li class="navigation__list__item"><a class="navigation__list__link" href="/Collections">Collections</a></li>
         </ul>
      </div>
   </nav>
   <div class="content" id="content" data-template="detail">
      <div class="detail">
         <div class="detail__wrapper">
            <figure class="detail__media"> <img class="detail__media__image" src="https://images.prismic.io/floemasa/6265cead-447f-413f-9375-bdf830118a3a_Collanina+Vita+Piccola+%28lato%29-1.png?auto=compress,format"></figure>
         </div>
      </div>
   </div>
</body>


Why is the div with class "detail" being rendered twice?

2

Answers


  1. Chosen as BEST ANSWER

    Following the answer submitted by ronak, I encountered errors specific to the loader configuration. After a lot of trial and error, I wasn't able to resolve those errors. So I changed the approach, I removed the loaders, and refactored the base pug template (base.pug) such that the block variable and block content are placed at the end of the file. It resolved the issue.


    Although working, i am still unsure about who is loading pug.

    In app.js file

    app.set("view engine", "pug");
    

  2. Install the required dependencies:

    npm install html-webpack-plugin pug-html-loader --save-dev
    

    Update your webpack configuration file (webpack.config.js) to include the html-webpack-plugin and configure it to work with Pug templates:

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
      // ...other webpack config settings...
    
      module: {
        rules: [
          // ...other webpack rules...
          {
            test: /.pug$/,
            use: ['pug-html-loader']
          }
        ]
      },
    
      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.pug' // Path to your Pug template
        })
      ]
    };
    

    Create or update your Pug template file (src/index.pug in this example):

    doctype html
    html(lang='en')
      head
        meta(charset='UTF-8')
        meta(http-equiv='X-UA-Compatible', content='IE=edge')
        meta(name='viewport', content='width=device-width, initial-scale=1.0')
        title My Website
        link(rel='stylesheet', href='./path/to/your/styles.css')
      body
        // Your page content here
    enter code here
    

    Run webpack to build your project:

    npx webpack
    

    The html-webpack-plugin will generate an HTML file based on your Pug template and place the link and meta tags in the correct location within the resulting HTML file. The pug-html-loader is responsible for compiling the Pug templates to HTML.

    Make sure to adjust the paths and file names in the webpack configuration and Pug template according to your project structure and needs.

    By following these steps, you should be able to retain the correct placement of link and meta tags in your Pug templates when using webpack with Prismic CMS.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search