1.0.3 • Published 5 months ago
img-alt-text-webpack-plugin v1.0.3
img-alt-text-webpack-plugin
Overview
A Webpack plugin that automatically adds alt text to <img>
elements in HTML output and injects JavaScript to fetch alt text for dynamically loaded images, enhancing accessibility and SEO.
Features
- Automatically sets the
alt
attribute for static<img>
elements. - Supports dynamic images by fetching
alt
text when the image loads. - Easy integration with existing Webpack projects.
- Set up with Google Gemini API for generating alt text.
Usage
Installation
npm install img-alt-txt-webpack-plugin -D
Set up webpack config
const ImgAltTextWebpackPlugin = require("img-alt-txt-webpack-plugin");
plugins: [
new ImgAltTextPlugin({
key: process.env.GEMINI_API_KEY, // provide your gemini key
jsInject: {
observerJS: true, // inject script for dynamically loaded images
jsName: 'imageObserver', // set name for emitted JS file
}
})
],
Set up middleware function
Note: If client loads <img>
elements that are served by third-party then client side JS needs to be modified to either send image data for server to fetch alt-text or you can also modify the script to let client fetch alt-text directly but you will have to set up some token based mechanism to avoid exposing your API Key. The middleware shown below is strictly for providing alt-text for images, served by your web-server, that were not part of static build.
// server.js
require('dotenv').config();
const path = require('path');
const fs = require('fs');
const express = require('express');
const http = require('http');
const { GoogleGenerativeAI } = require("@google/generative-ai");
// load gemini model with API Key
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash"});
// middleware to provide alt-text
async function getAltText(req, res, next) {
try {
// resolve filepath from query parameter
const filepath = path.resolve(__dirname, `./fromServer/${req.query.file}`);
// generate alt text if image is found
if (fs.existsSync(filepath)) {
const file = fs.readFileSync(filepath);
const prompt = "Generate alt text for this image that can be inserted in img html element. Keep it concise."
const imageParts = {
inlineData: {
data: Buffer.from(file).toString("base64"),
mimeType: "image/png"
},
};
const result = await model.generateContent([prompt, imageParts]);
const response = await result.response;
res.altText = response.text();
} else {
// alt-text if image path not found
res.altText = "Cannot provide alt-text for this image";
}
} catch (error) {
console.error('Error generating alt text:', error);
// Gracefully refuse alt-text
res.altText = "Cannot provide alt-text for this image";
}
next();
}
// express server
const app = express();
const server = http.createServer(app);
// using middleware to intercept alt text generation
app.get('/alttext', getAltText, (req, res) => {
res.send(res.altText);
});
if (process.env.MODE === 'production') {
app.use(express.static(path.join(__dirname, 'prodBuild')));
} else {
app.use(express.static(path.join(__dirname, 'devBuild')));
}
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});