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
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
Install the required dependencies:
Update your webpack configuration file (webpack.config.js) to include the html-webpack-plugin and configure it to work with Pug templates:
Create or update your Pug template file (src/index.pug in this example):
Run webpack to build your project:
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.