UNPKG

img-alt-text-webpack-plugin

Version:

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.

152 lines (111 loc) 9.39 kB
# Img Alt Text Webpack Plugin A Webpack plugin that automatically adds alt text to `<img>` elements in your HTML output and injects a JavaScript runtime to fetch alt text for dynamically loaded images. This improves web accessibility and SEO by ensuring all images have descriptive `alt` attributes, while saving developers the effort of writing alt text manually. ## Features - **Automatic Alt Text:** Finds any `<img>` tags in the build output that lack an `alt` attribute and automatically generates and inserts appropriate alt text. - **Dynamic Image Support:** Injects an optional runtime script to handle images loaded dynamically (after initial page load) by fetching alt text when those images appear. - **Easy Integration:** Designed to integrate with existing Webpack setups with minimal configuration. - **Powered by Google Gemini API:** Utilizes Google’s Generative AI (Gemini) to generate meaningful descriptions for images. ## Installation Install the plugin via npm (as a development dependency): ```bash npm install img-alt-text-webpack-plugin --save-dev ``` *(Alternatively, use Yarn: `yarn add --dev img-alt-text-webpack-plugin`.)* You will need a Google Gemini API key to use this plugin. Sign up for Google’s Generative AI API to obtain an API key, and store it securely (for example, in an environment variable). ## Usage: Webpack Configuration After installing, configure Webpack to use the plugin. In your Webpack config (e.g. **webpack.config.js**), require the plugin and add it to the `plugins` array. For example: ```js // webpack.config.js const ImgAltTextPlugin = require('img-alt-text-webpack-plugin'); module.exports = { // ... other config ... plugins: [ new ImgAltTextPlugin({ key: process.env.GEMINI_API_KEY, // your Google Gemini API key jsInject: { observerJS: true, // inject runtime script for dynamic images jsName: 'imageObserver' // name of the emitted JS file (for the runtime script) } }) ] }; ``` In the above example, the plugin will automatically process your output HTML to add alt attributes to any images missing them. It will also emit a small JS file (named **imageObserver.js** in this case) and include it in your HTML. This runtime script uses an **Intersection Observer** (or similar mechanism) to detect when new images appear on the page and requests alt text for them. Make sure to provide your Gemini API key (here via `process.env.GEMINI_API_KEY`). It’s recommended to **not** hard-code the key in your config; instead, load it from environment variables or a `.env` file for security. ## Configuration Options The plugin accepts a configuration object when instantiated. The available options are: - **`key`** (string, **required**): Your Google Gemini API key used to generate image descriptions. This key is required for the plugin to contact the Generative AI service. Make sure to keep this value secure (do not commit it to source control). - **`jsInject`** (object, optional): Settings for the optional runtime script injection. This object can contain: - **`observerJS`** (boolean): Set to `true` to inject the JavaScript observer for dynamic images (default is `false`, meaning no runtime script is added unless enabled). When enabled, the plugin will generate and include a script that watches for images loaded after initial render and fetches alt text for them. - **`jsName`** (string): The base name for the emitted JS file that contains the dynamic image handler (default is `"imageObserver"`). The plugin will output a file with this name (e.g. **imageObserver.js**) in the build folder and ensure it’s included in the HTML. You can change this if you need a different filename. *(All other configuration is handled internally; typically you only need to provide the above options.)* ## Express Middleware Setup for Dynamic Images If your application loads images dynamically (e.g. via client-side scripts or AJAX after page load), you should set up a backend endpoint to provide alt text on the fly. The plugin’s injected script will call this endpoint for any new images it detects. Below is an example **Express** server setup with a middleware function to generate alt text using the Google Generative AI API: ```js // server.js (Express server example) 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'); // Initialize the Google Generative AI client with your API key const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY); const model = genAI.getGenerativeModel({ model: 'gemini-1.5-flash' }); // Middleware to generate alt text for an image file async function getAltText(req, res, next) { try { // Resolve the image filepath based on request query const filepath = path.resolve(__dirname, './fromServer/' + req.query.file); if (fs.existsSync(filepath)) { // Read the image file and prepare it for the API request const fileData = fs.readFileSync(filepath); const prompt = 'Generate alt text for this image that can be inserted in an <img> tag. Keep it concise.'; const imageParts = { inlineData: { data: Buffer.from(fileData).toString('base64'), mimeType: 'image/png' // adjust if not PNG } }; // Call the generative model to get alt text const result = await model.generateContent([prompt, imageParts]); const response = await result.response; res.altText = response.text(); } else { // Image file not found res.altText = 'Cannot provide alt-text for this image'; } } catch (error) { console.error('Error generating alt text:', error); // In case of any error, provide a fallback alt text res.altText = 'Cannot provide alt-text for this image'; } next(); } // Set up Express app and route const app = express(); const server = http.createServer(app); // Endpoint to get alt text for an image (uses the getAltText middleware) app.get('/alttext', getAltText, (req, res) => { // Send back the generated alt text res.send(res.altText); }); // Serve static files (your built front-end) app.use(express.static(path.join(__dirname, 'build'))); // Start the server const PORT = process.env.PORT || 3000; server.listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}`); }); ``` In this setup, the client-side script (injected by the plugin) will make a GET request to `/alttext?file=<imagePath>` whenever it encounters a new image without alt text. The `getAltText` middleware reads the image file (here assumed to be under a known directory like `fromServer/` relative to the server) and uses the Google Generative AI Model to produce a description. The generated text is then returned to the client, which sets it as the image’s alt attribute. **Important:** Ensure you protect your API key. In the above example, the key is loaded from an environment variable and used on the server side (via the `@google/generative-ai` library). This way, the API key is never exposed on the client. The client-side script simply calls your `/alttext` endpoint, and the server handles the secure API call. ## Handling Third-Party Images & API Key Security If your webpage loads images from **third-party sources or external URLs**, the above setup needs extra consideration. The out-of-the-box injected script and middleware assume the images are served by your own application (so the server can access the image files locally). For externally hosted images, you have a couple of options: - **Proxy the image through your server:** Modify the client script `/src/worker.js` to send the image data or URL to your `/alttext` endpoint so your server can fetch the image and generate alt text. This way, the alt text generation still happens on your server (keeping the API key secret), but requires that your server can access the image URL or that the image data is forwarded. - **Client-side API call (not recommended):** Alternatively, you could modify the script to call the Google Generative AI API directly from the client side. **However, you must not expose your API key in the browser.** If you choose this route, implement a secure token exchange or proxy service. For example, your server could provide a short-lived token or endpoint for the client to use instead of the raw API key. In all cases, **securing your API key is critical**. Never embed the Google API key in public frontend code or commit it to a repository. Use environment variables and server-side calls (as shown above) to keep the key safe. ## Contributing Contributions are welcome! If you find a bug or have an idea for an improvement, please open an issue or pull request on the [GitHub repository](https://github.com/sam1git/img-alt-text-webpack-plugin). When contributing code, ensure that it aligns with the project style and includes appropriate updates to documentation or tests (if applicable). By participating, you agree to abide by the repository’s code of conduct. ## License This project is open-source and available under the **MIT License**. Feel free to use it in your projects. See the LICENSE file or package metadata for details.