Image SEO, Alt & Title Generator for Magento 2
Generates alt and title text for every Magento 2 product image from a template that can use the product name, SKU, store and category. An empty template falls back to the product name, so no image has a blank alt.
- Free
- MIT license
- Hyvä + Luma
- Magento 2.4.4 to 2.4.9
composer require mage2kishan/module-image-seo
- Adobe CertifiedDeveloper since 2021
- 5.0 on UpworkFrom 100+ reviews
- MIT open sourceRead and change the code
- Hyvä + LumaSame module, both themes
- PHP 8.1 to 8.4Magento 2.4.4 to 2.4.9
What it does for your store
The main features, as listed in the module documentation.
-
Template-Based Alt & Title Generation
Tokens, {{name}}, {{sku}}, {{store}}, {{category}} rendered per image in real time
-
Store View Aware
Scope-respecting, every setting is configurable at default / website / store view level
-
Complete Surface Coverage
Product detail page, main gallery image alt + caption + title
-
Safe Merchant Overrides
Preserves merchant-authored labels, if a product has a custom image label set in admin, that takes precedence
-
Performance Conscious
Runs inline, no external API calls, no DB writes, pure template rendering
-
Clean & Extensible
MEQP compliant, follows Adobe's Magento Extension Quality Program standards
Installation
Run these from your Magento root. Test on staging first.
- 1Require the packageComposer pulls in the base module too.
- 2Upgrade, compile, deployThe usual setup commands.
- 3ConfigureStores, Configuration, Panth Extensions.
$ composer require mage2kishan/module-image-seo $ bin/magento setup:upgrade $ bin/magento setup:di:compile $ bin/magento setup:static-content:deploy -f $ bin/magento cache:flush
Compatibility
| Magento Open Source | 2.4.4 to 2.4.9 |
|---|---|
| Adobe Commerce | 2.4.4 to 2.4.9 |
| PHP | 8.1, 8.2, 8.3, 8.4 |
| Themes | Hyvä and Luma |
| License | MIT, free and open source |
| Requires | mage2kishan/module-core (Composer adds it) |
Documentation
The full module guide, from the README on GitHub.
Overview
Panth Image SEO is a template-based alt and title generator for Magento 2 and Adobe Commerce that fills every product image with descriptive, scope-aware text. Replace blank alt="" attributes across the catalog with one merchant-controlled template that renders on every store view, every theme, and every storefront surface.
The module uses tokens ({{name}}, {{sku}}, {{store}}, {{category}}) and chainable filters (|truncate:N, |title, |upper, |lower, |strip, |default:'value') to optimize alt and title attributes per image in real time. Templates apply to PDP main galleries, fotorama and Hyva carousels, category grids, related, upsell, cross-sell, search results, and CMS product widgets, with multi-image position suffix support such as “Image 2 of 5”.
Image SEO is store-view scoped, so localized storefronts and multi-brand websites get the correct alt text per scope without code changes. Merchant-authored labels are preserved, generic Magento defaults like “main product photo” are replaced, and the module runs inline with zero external API calls or DB writes. Compatible with Hyva and Luma; a pluggable VisionAdapterInterface lets you wire OpenAI Vision or Claude Vision for AI-generated fallback alt text when a token resolves empty.
- Hyva or Luma stores chasing Google Images traffic and richer organic snippets.
- Multi-store catalogs that need per-store-view alt text without manual editing.
- Merchants closing WCAG 2.1 AA and European Accessibility Act image gaps.
What you get
Image SEO ships a complete toolkit to optimize alt and title text behavior across every storefront surface:
- Token-driven alt and title templates with chainable filter syntax.
- Store-view scope so each language or brand gets its own alt text.
- Coverage across PDP galleries, category grids, related, upsell, search, and CMS widgets.
- Merchant overrides preserved; generic Magento placeholders replaced.
- Pluggable
VisionAdapterInterfacefor AI-generated fallback alt text. - Hyva and Luma compatible on Magento 2.4.4-2.4.9 and PHP 8.1-8.4.
Magento 2 Image SEO
Generates the alt and title attributes of product images from templates such as {{name}} - {{store}}, so every product image on the storefront carries descriptive text without editing each image label by hand. It also cleans the filenames of images uploaded through Magento's catalog image uploader.
The module is for store owners who want consistent image alt text for search engines and accessibility across category listings, product pages, widgets and the product gallery. Works with the Hyva and Luma themes.
Product page: kishansavaliya.com/magento-2-image-seo.html
Features
- Alt and title templates with the tokens
{{name}},{{sku}},{{store}}and{{category}}. - Filters that can be chained on any token:
truncate:N,title,upper,lower,stripanddefault:'text'. - Applies to product images rendered through Magento's image blocks and image helper (category listings, search results, related and upsell lists, widgets, product page) and to the product gallery JSON used by the gallery widget.
- In the gallery, captions that were typed by a merchant are kept; empty captions, captions equal to the product name and Magento's placeholder labels are replaced, with "Image N of M" appended when a product has several images.
- Renames images uploaded through Magento's catalog image uploader to a lowercase ASCII filename (transliterated, hyphen separated, at most 120 characters).
- Settings per default, website or store view, so each store view can have its own template and language.
- Output is capped at 250 characters and stray separators from empty tokens are removed.
- No database tables, no cron jobs and no console commands.
Usage
Once enabled, no further action is needed. Where the text is applied:
| Surface | How |
|---|---|
| Category listings, search results, related and upsell lists, widgets | Plugin on Magento\Catalog\Block\Product\ImageFactory sets the image label to the generated alt text. |
Images rendered through Magento\Catalog\Helper\Image |
Plugins on getLabel() return the generated alt text, or the product name when no template output is available. |
Product gallery (Magento\Catalog\Block\Product\View\Gallery) |
The gallery image labels (used for the server-rendered main image on Hyva) and the gallery JSON caption and title are replaced when the existing value is empty, equals the product name or is a placeholder ("Image", "Main product photo"). Merchant-written captions are kept. "Image N of M" is appended when there is more than one image. |
Catalog image uploads (Magento\Catalog\Model\ImageUploader) |
The stored filename is normalised to a clean ASCII slug. Existing files are not renamed. |
Note: on listing and helper-rendered images the generated text replaces whatever label the image had. If you rely on hand-written labels there, keep the module switched off for that store view or make the template reproduce them.
Rendering happens on every request from the templates in configuration; nothing is written to product data, so changing a template takes effect after a cache flush.
Changelog
See CHANGELOG.md.
Compatibility
| Magento Open Source / Adobe Commerce | 2.4.4 to 2.4.9 |
| PHP | 8.1, 8.2, 8.3, 8.4 |
| Themes | Hyva and Luma |
The Composer package requires magento/framework ^103.0, magento/module-store ^101.1, magento/module-catalog ^104.0 and magento/module-config ^101.2.
Requirements
- Magento 2.4.4 or later
- PHP 8.1 to 8.4
mage2kishan/module-core(installed automatically by Composer; provides the shared "Panth Extensions" admin tab)- Optional:
mage2kishan/module-productgallery. When it is installed, its gallery uses the same templates.
Installation
composer require mage2kishan/module-image-seo
bin/magento module:enable Panth_Core Panth_ImageSeo
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
setup:di:compile is only needed in production mode. The module has no static assets.
Check the result with:
bin/magento module:status Panth_ImageSeo
The module is enabled by default with the templates shown below, so product images get the generated text as soon as the cache is flushed.
Configuration
Go to Stores > Configuration > Panth Extensions > Image SEO.
| Setting | Default | What it does |
|---|---|---|
| Enable Template-Based Image Alt/Title | Yes | Master switch for all plugins. |
| Alt Text Template | {{name}} - {{store}} |
Template for the alt attribute. Validated on save: only the tokens and filters listed below are accepted, up to 255 characters. |
| Title Text Template | {{name}} |
Template for the title attribute of gallery images. When empty, the alt text is used. Validated like the alt template. |
| Apply to Gallery Images JSON | Yes | Also writes the generated text into the product gallery JSON. |
Configuration paths: panth_image_seo/image/image_seo_enabled, panth_image_seo/image/alt_template, panth_image_seo/image/title_template, panth_image_seo/image/gallery_seo_enabled.

Tokens
| Token | Value |
|---|---|
{{name}} |
Product name |
{{sku}} |
Product SKU |
{{store}} |
Name of the current store view |
{{category}} |
Name of the product's current category, when Magento has one in context (for example on a category page); empty otherwise |
Unknown tokens and filters are rejected when the configuration is saved. Separators left behind by empty tokens (-, |, commas) are cleaned up, so {{name}} - {{category}} renders as just the product name when there is no category.
Filters
Filters are appended to a token with | and run from left to right, for example {{name|lower|title|truncate:40}}.
| Filter | Effect |
|---|---|
truncate:N |
Cuts the value to N characters and appends ... (N defaults to 60 when omitted). |
title |
Title case. |
upper |
Upper case. |
lower |
Lower case. |
strip |
Removes HTML tags and collapses whitespace. |
default:'text' |
Uses text when the value is empty. |
Template examples
Alt: {{name}} - {{store}}
Title: {{name}}
Alt: {{name|truncate:80}} | {{store}}
Title: {{name}}
Alt: {{name}} in {{category|default:'our catalogue'}}
Title: {{name}}
Alt: [{{sku|upper}}] {{name}} | {{store}}
Title: {{name|truncate:60}}
For a multilingual store, set a different Alt Text Template on each store view.
Uninstallation
bin/magento module:disable Panth_ImageSeo
composer remove mage2kishan/module-image-seo
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
The module creates no database tables and does not modify product data. Configuration values remain in core_config_data until removed. Filenames that were normalised at upload time are not changed back.
License
MIT License. Free and open source. The package is published on Packagist and can be installed with Composer; see the product page for the terms of use.
Developer Notes
- Module name:
Panth_ImageSeo - Composer package:
mage2kishan/module-image-seo - PHP namespace:
Panth\ImageSeo - Template engine:
Panth\ImageSeo\Model\ImageSeo\AltGenerator; resolver with the configured templates:Panth\ImageSeo\Model\ImageSeo\ImageTemplateResolver(getAlt(),getTitle(),resolve()). - Extension point:
Panth\ImageSeo\Model\ImageSeo\VisionAdapterInterface. The defaultNullVisionAdapterdoes nothing; a custom adapter can be bound through a DI preference to supply generated descriptions when the generator is called with an image path. No image analysis is performed by default. - Upgrade from Panth Advanced SEO: the data patch
MigrateConfigPathsmoves saved values frompanth_seo/image/*topanth_image_seo/image/*duringsetup:upgrade. When a value already exists under the new path for the same scope, the existing value is kept and the legacy row is left in place. - ACL resource for the configuration section:
Panth_ImageSeo::config
| Module Category | SEO & Indexing |
|---|---|
| Best For | All Sizes |
FAQ
Will this overwrite my custom image labels?
No. Merchant-authored labels (anything other than empty, the product name, Image, main product photo, or the raw filename) are preserved. Only Magento's default placeholders get upgraded to template output.
Does it work with Hyva?
Yes. The module injects into getGalleryImagesJson, which Hyva reads for its Alpine.js gallery. Category tile alt attributes go through ImageFactory, which Hyva's product/list.phtml also uses.
Does it work with Luma?
Yes. Luma's fotorama gallery reads from the same caption field, and Luma's category grid uses the same ImageFactory path.
Is Panth_Core required?
Yes. mage2kishan/module-core is a required dependency and is pulled in automatically by Composer. Core provides the admin tab layout and common utilities.
Can I use AI-generated alt text?
Yes. The module ships with a VisionAdapterInterface and a NullVisionAdapter default. You can swap the preference in your di.xml to a custom adapter that calls OpenAI Vision, Claude Vision, or Google Cloud Vision for a vision-generated alt as the fallback when templates render empty. The vision adapter only fires when no template output was produced.
Does it support multi-store / multi-language?
Yes. Every configuration setting respects Magento's standard scope hierarchy (default → website → store view). Configure a different alt template per store view and the plugins automatically honor it.
What about the `title` attribute on `<img>` tags?
The module renders a separate title template so you can produce short, branded titles ({{name}}) while the alt attribute carries the SEO keyword copy ({{name}} | {{store}} | {{category}}).
Can I disable it temporarily?
Yes. Flip the master toggle to No in admin config and all plugins become no-ops instantly. The module's index data is not deleted, so re-enabling is instant.
Does it touch the database?
No. The module is pure template rendering, no DB tables created, no writes. All state lives in Magento's cached scope config.
What if I want to disable only the gallery injection but keep tile alt working?
Set Apply to Gallery Images JSON to No. The master toggle stays on, so category tiles and widgets still get template alt; only the gallery JSON is left untouched.
Is it compatible with Varnish / Redis FPC?
Yes. The module doesn't cache anything itself, it relies on Magento's native block cache and FPC. Template rendering is idempotent, so cache hit rate is unaffected.
Questions before you install?
Send me your composer.json and I will check for conflicts first. Free. Installation is +$45, custom work is quoted first.