I have widget app using boostrap and bootstrap icons
all this is bundled via Webpack js 5
I had huge difficulties to make bootstrap icons to be loaded correctly but now it’s working.
the only problem remaining is the conflict with boostrap framework which is overriding styles of the websites where I do put the widget js script.
I’m using shadow dom system but I think i’m missing something somewhere. I think the problem comes from bootstrap and bootstrap icons being loaded globally in index.js.
please find my files attached
thanks for helping me fix this
-
webpack config
const path = require(‘path’);
const MiniCssExtractPlugin = require(‘mini-css-extract-plugin’);
const HtmlWebpackPlugin = require(‘html-webpack-plugin’);
const webpack = require(‘webpack’);
module.exports = {
entry: ‘./src/index.js’,
output: {
filename: ‘widget-bundle.js’,
path: path.resolve(dirname, ‘dist’),
},
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: ‘babel-loader’,
options: {
presets: [‘@babel/preset-env’],
},
},
},
{
test: /.scss$/,
use: [
MiniCssExtractPlugin.loader,
‘css-loader’,
‘sass-loader’
]
},
{
test: /.css$/,
use: [‘style-loader’, ‘css-loader’, ‘postcss-loader’]
},
{
test: /.(woff|woff2|eot|ttf|otf)$/i,
type: “asset/inline”,
}
],
},
plugins: [
new MiniCssExtractPlugin({
filename: ‘widget.css’,
}),
new HtmlWebpackPlugin({
template: ‘./src/index.html’,
inject: ‘head’
}),
new webpack.ProvidePlugin({
$: ‘jquery’,
jQuery: ‘jquery’,
}),
],
resolve: {
alias: {
‘bootstrap-icons’: path.resolve(dirname, ‘node_modules/bootstrap-icons’),
‘bootstrap’: path.resolve(__dirname, ‘node_modules/bootstrap’),
},
},
}; -
index.js
import $ from ‘jquery’;
window.$ = window.jQuery = $; // Make jQuery available globally
import ‘bootstrap/dist/css/bootstrap.min.css’;
import ‘bootstrap-icons/font/bootstrap-icons.css’;
import ‘./css/widget.css’;
import { initWidget } from ‘./js/widget’;
const widgetId = document.currentScript.getAttribute(‘data-widgetid’);
if (widgetId) {
initWidget(widgetId);
} else {
console.error(‘Widget ID not provided’);
} -
widget.js
import { u } from ‘./config’;
//import ‘bootstrap/dist/css/bootstrap.min.css’;
//import ‘../css/widget.css’;
export function initWidget(widgetId) {
const shadowHost = document.createElement(‘div’);
document.body.appendChild(shadowHost);
const shadowRoot = shadowHost.attachShadow({ mode: ‘open’ });
const widgetContainer = document.createElement(‘div’);
widgetContainer.id = ‘widget-container’;
const buttonIcon = document.createElement(‘button’);
buttonIcon.className = ‘btn btn-primary widget-icon’;
buttonIcon.innerHTML = ”;
const form = document.createElement(‘div’);
form.className = ‘widget-form d-none’;
form.innerHTML =Name
Email
Submit
;
widgetContainer.appendChild(buttonIcon);
widgetContainer.appendChild(form);
const styles = document.createElement(‘style’);
styles.textContent = @import url(‘${u}/dist/widget.css’);;
shadowRoot.appendChild(styles);
shadowRoot.appendChild(widgetContainer);
buttonIcon.addEventListener(‘click’, () => {
form.classList.toggle(‘d-none’);
});
// Load settings via AJAX
$.ajax({
url: ${u}/proxy.php,
method: ‘GET’,
data: { widgetId },
success: function(response) {
// Apply settings to the widget
console.log(‘Widget settings:’, response);
},
error: function(xhr, status, error) {
console.error(‘Error loading widget settings:’, error);
}
});
} -
config.js
const protocol = ‘https://’;
const host = ‘domain.com’;
const dir = ‘/widget-v2’;
export const u = protocol + host + dir -
package.json
{
“name”: “widget-v2”,
“version”: “1.0.0”,
“description”: “”,
“main”: “index.js”,
“scripts”: {
“build”: “webpack –mode production”,
“dev”: “webpack –mode development –watch”
},
“keywords”: [],
“author”: “”,
“license”: “ISC”,
“devDependencies”: {
“@babel/core”: “^7.24.7”,
“@babel/preset-env”: “^7.24.7”,
“autoprefixer”: “^10.4.19”,
“babel-loader”: “^9.1.3”,
“css-loader”: “^7.1.2”,
“html-webpack-plugin”: “^5.6.0”,
“mini-css-extract-plugin”: “^2.9.0”,
“postcss-loader”: “^8.1.1”,
“sass”: “^1.77.6”,
“sass-loader”: “^14.2.1”,
“style-loader”: “^4.0.0”,
“to-string-loader”: “^1.2.0”,
“webpack”: “^5.92.1”,
“webpack-cli”: “^5.1.4”
},
“dependencies”: {
“bootstrap”: “^5.3.3”,
“bootstrap-icons”: “^1.11.3”,
“file-loader”: “^6.2.0”,
“jquery”: “^3.7.1”,
“raw-loader”: “^4.0.2”
}
}