mhinspeya / module-remoteimages
Magento 2 module that enables external/remote product images stored as JSON URLs in a custom product attribute to be displayed natively across all catalog surfaces — including product listings, product detail gallery, mini-cart, and checkout cart — without importing images to the Magento media direc
Package info
git.modehaus.de/hyvae/mhinspeya-remoteimages
Type:magento2-module
pkg:composer/mhinspeya/module-remoteimages
Requires
- mhinspeya/backend-mod: ^1.0
This package is not auto-updated.
Last update: 2026-06-04 12:19:31 UTC
README
Magento 2 module · PHP 8.4 compatible · Magento 2.4.6 – 2.4.8
Display external/remote product images — stored as a JSON array of URLs in a custom product attribute — natively across every catalog surface in Magento 2. No image imports, no local media storage, no extra CDN sync required.
Table of Contents
- Overview
- Features
- How It Works
- Requirements
- Installation
- Configuration
- Module Architecture
- Upgrade Notes
- Troubleshooting
- Contributing
- License
Overview
MHinspeya_Remoteimages solves a common integration problem: your product images live on an external CDN, PIM, or ERP system and you need Magento to render them without syncing or re-uploading files into the Magento media directory.
The module reads a custom product attribute called remote_images (a JSON-encoded array of image URLs) and intercepts all standard Magento image rendering points to substitute remote URLs transparently — for both frontend customers and admin users.
Features
| Surface | Behaviour |
|---|---|
| Product Listing (Category Page) | Thumbnail replaced with remote medium image |
| Product Detail Page (Gallery) | Full gallery replaced with remote image set (thumb, medium, large) |
| Mini-Cart | Cart item image replaced with remote medium image |
| Checkout Cart | Cart item image block replaced with remote medium image |
| Admin Product Grid | Thumbnail column shows remote image for quick visual reference |
| Fallback | If no remote_images data exists, native Magento image rendering is used unchanged |
Image size variants are generated automatically from the base URL by appending suffixes:
| Variant | Suffix convention |
|---|---|
| Small (thumbnail) | _small.jpg / _small.jpeg / _small.png |
| Medium (listing, cart) | _medium.jpg / _medium.jpeg / _medium.png |
| Large (gallery zoom) | _large.jpg / _large.jpeg / _large.png |
Example: a base URL of
https://cdn.example.com/products/shirt.jpgbecomeshttps://cdn.example.com/products/shirt_medium.jpgfor listing images.
How It Works
remote_images attribute value (JSON):
["https://cdn.example.com/products/shirt.jpg", "https://cdn.example.com/products/shirt-back.jpg"]
- The product model (
Model/Catalog/Product) overridesgetMediaGalleryImages()to build a virtualDataObjectcollection from the remote URLs instead of reading from the Magento media database. Block/Rewrite/Product/ImageFactoryoverrides the coreImageFactoryto inject the remote URL directly into the image block data when a remote image is available.- Plugin classes intercept gallery JSON, mini-cart item data, and checkout cart rendering to swap in remote URLs at the last moment before output.
No database changes. No media file writes. No re-index required for image changes.
Requirements
| Dependency | Version |
|---|---|
| PHP | ^8.1 (fully compatible with PHP 8.4) |
| Magento Open Source / Adobe Commerce | 2.4.6 – 2.4.8 |
magento/module-catalog | ^105.0 |
magento/module-checkout | ^100.4 |
magento/module-quote | ^101.2 |
Installation
Via Composer (Recommended)
Step 1 — Require the package
composer require mhinspeya/module-remoteimages
If the package is hosted on a private repository, first add the repository to your project's composer.json:
composer config repositories.mhinspeya vcs https://github.com/mhinspeya/module-remoteimages
composer require mhinspeya/module-remoteimages
Step 2 — Enable the module
php bin/magento module:enable MHinspeya_Remoteimages
Step 3 — Run setup upgrade
php bin/magento setup:upgrade
Step 4 — Compile dependency injection
php bin/magento setup:di:compile
Step 5 — Deploy static content (production mode only)
php bin/magento setup:static-content:deploy -f
Step 6 — Flush the cache
php bin/magento cache:flush
Manual Installation
Step 1 — Copy module files
Copy the module directory into your Magento installation:
cp -r /path/to/Remoteimages /path/to/magento/app/code/MHinspeya/Remoteimages
The final directory structure should be:
app/
└── code/
└── MHinspeya/
└── Remoteimages/
├── Block/
│ └── Rewrite/
│ └── Product/
│ └── ImageFactory.php
├── Model/
│ └── Catalog/
│ └── Product.php
├── Plugin/
│ ├── Adminhtml/
│ │ └── RemoteThumbnailPlugin.php
│ ├── CheckoutCart/
│ │ └── ImagePlugin.php
│ ├── Magento/
│ │ └── Catalog/
│ │ └── Block/
│ │ └── Product/
│ │ └── View/
│ │ └── GalleryPlugin.php
│ └── Minicart/
│ └── Image.php
├── etc/
│ ├── adminhtml/
│ │ └── di.xml
│ ├── frontend/
│ │ └── di.xml
│ ├── di.xml
│ └── module.xml
├── composer.json
├── README.md
└── registration.php
Step 2 – 6: Follow the same Steps 2–6 from the Composer installation above.
Configuration
Product Attribute Setup
The module reads a product attribute named remote_images. You must create this attribute in Magento if it does not already exist.
Create via Magento Admin:
- Go to Stores → Attributes → Product
- Click Add New Attribute
- Fill in the fields:
| Field | Value |
|---|---|
| Default Label | Remote Images |
| Catalog Input Type | Text Area |
| Values Required | No |
| Attribute Code | remote_images |
| Scope | Store View (or Global depending on your setup) |
| Used in Product Listing | Yes |
| Visible on Catalog Pages on Storefront | No (data is used internally) |
- Save the attribute and add it to the relevant Attribute Set(s).
Create via Install Data Patch (recommended for automation):
<?php
declare(strict_types=1);
namespace YourVendor\YourModule\Setup\Patch\Data;
use Magento\Catalog\Model\Product;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
class AddRemoteImagesAttribute implements DataPatchInterface
{
public function __construct(
private readonly ModuleDataSetupInterface $moduleDataSetup,
private readonly EavSetupFactory $eavSetupFactory
) {}
public function apply(): self
{
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
$eavSetup->addAttribute(Product::ENTITY, 'remote_images', [
'type' => 'text',
'label' => 'Remote Images',
'input' => 'textarea',
'required' => false,
'visible' => true,
'user_defined' => true,
'default' => null,
'searchable' => false,
'filterable' => false,
'comparable' => false,
'visible_on_front' => false,
'used_in_product_listing' => true,
'unique' => false,
'global' => ScopedAttributeInterface::SCOPE_STORE,
]);
return $this;
}
public static function getDependencies(): array { return []; }
public function getAliases(): array { return []; }
}
Populating Remote Images
Set the remote_images attribute value on any product as a JSON array of absolute image URLs:
[
"https://cdn.example.com/products/shirt.jpg",
"https://cdn.example.com/products/shirt-detail.jpg",
"https://cdn.example.com/products/shirt-back.jpg"
]
- The first URL is used as the primary/main product image.
- Additional URLs appear in the product gallery.
- Magento's native images are used as a fallback if this attribute is empty or absent.
Via REST API:
curl -X PUT \
"https://your-store.com/rest/V1/products/SKU123" \
-H "Authorization: Bearer <admin_token>" \
-H "Content-Type: application/json" \
-d '{
"product": {
"custom_attributes": [
{
"attribute_code": "remote_images",
"value": "[\"https://cdn.example.com/products/shirt.jpg\",\"https://cdn.example.com/products/shirt-back.jpg\"]"
}
]
}
}'
Module Architecture
MHinspeya_Remoteimages
│
├── Preference: Magento\Catalog\Block\Product\ImageFactory
│ └── Block/Rewrite/Product/ImageFactory.php
│ Overrides the image block factory to inject remote URLs
│ into the image block data array when remote_images is set.
│
├── Preference: Magento\Catalog\Model\Product
│ └── Model/Catalog/Product.php
│ Overrides getMediaGalleryImages() to build a virtual
│ DataObject collection from remote URLs.
│
├── Plugin: Magento\Catalog\Block\Product\View\Gallery
│ └── Plugin/Magento/Catalog/Block/Product/View/GalleryPlugin.php
│ Replaces gallery JSON (afterGetGalleryImagesJson) and
│ gallery collection (afterGetGalleryImages) with remote data.
│
├── Plugin: Magento\Checkout\CustomerData\AbstractItem
│ └── Plugin/Minicart/Image.php
│ Replaces mini-cart item image src with remote medium image.
│
├── Plugin: Magento\Checkout\Block\Cart\Item\Renderer
│ └── Plugin/CheckoutCart/ImagePlugin.php
│ Replaces checkout cart item image block URL with remote image.
│
└── Plugin: Magento\Catalog\Ui\Component\Listing\Columns\Thumbnail
└── Plugin/Adminhtml/RemoteThumbnailPlugin.php
Replaces admin product grid thumbnail with remote medium image.
Upgrade Notes
v1.1.0 (Current — PHP 8.4 / Magento 2.4.8)
- Removed
ObjectManagerusage; replaced withProductRepositoryInterfaceDI. - Replaced deprecated
->load()calls with->getById(). - Added full strict type declarations (
declare(strict_types=1)) across all classes. - Added typed class properties (PHP 8.0+ syntax).
- Fixed implicit nullability deprecations in
getRatio()signature (?int). - Removed parent class private property re-declarations (PHP 8.4 deprecation).
- Removed deprecated
setup_versionfrommodule.xml. - Renamed
Plugin\Adminhtml\Thumbnailclass toRemoteThumbnailPluginto avoid class name collision withMagento\Catalog\Ui\Component\Listing\Columns\Thumbnail.
v1.0.0
- Initial release.
Troubleshooting
Images not showing after install
php bin/magento cache:flush
rm -rf generated/code/MHinspeya/Remoteimages
php bin/magento setup:di:compile
remote_images attribute not saving
Ensure the attribute is assigned to the correct Attribute Set for your product type. Check under: Stores → Attributes → Attribute Set → [Your Set] → Unassigned Attributes
Images show in listing but not in gallery
Confirm the remote_images JSON is valid:
echo '[" https://cdn.example.com/img.jpg"]' | python3 -m json.tool
Common mistake: extra whitespace inside the URL string.
Admin grid still shows old Magento images
Clear Magento full-page cache and browser cache. If persisting, regenerate the admin UI component:
php bin/magento cache:clean full_page block_html
Fatal error: Cannot declare class ... Thumbnail
Clear generated code directory and re-compile:
rm -rf generated/code/MHinspeya
php bin/magento setup:di:compile
php bin/magento cache:flush
Contributing
- Fork the repository.
- Create a feature branch:
git checkout -b feature/your-feature - Commit your changes following Magento Coding Standards.
- Push to the branch:
git push origin feature/your-feature - Open a Pull Request.
Please ensure all PHP files pass:
vendor/bin/phpstan analyse --level=8 app/code/MHinspeya/Remoteimages
License
This module is proprietary software owned by MHinspeya. All rights reserved.
Unauthorized copying, distribution, or modification without express written permission is prohibited.
For licensing enquiries: dev@mhinspeya.com
Built with ❤️ by the MHinspeya Development Team