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

Maintainers

Package info

git.modehaus.de/hyvae/mhinspeya-remoteimages

Type:magento2-module

pkg:composer/mhinspeya/module-remoteimages

Statistics

Installs: 15

Dependents: 0

Suggesters: 0

1.0.0 2026-06-04 12:18 UTC

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

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

SurfaceBehaviour
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-CartCart item image replaced with remote medium image
Checkout CartCart item image block replaced with remote medium image
Admin Product GridThumbnail column shows remote image for quick visual reference
FallbackIf 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:

VariantSuffix 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.jpg becomes https://cdn.example.com/products/shirt_medium.jpg for 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"]
  1. The product model (Model/Catalog/Product) overrides getMediaGalleryImages() to build a virtual DataObject collection from the remote URLs instead of reading from the Magento media database.
  2. Block/Rewrite/Product/ImageFactory overrides the core ImageFactory to inject the remote URL directly into the image block data when a remote image is available.
  3. 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

DependencyVersion
PHP^8.1 (fully compatible with PHP 8.4)
Magento Open Source / Adobe Commerce2.4.62.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:

  1. Go to Stores → Attributes → Product
  2. Click Add New Attribute
  3. Fill in the fields:
FieldValue
Default LabelRemote Images
Catalog Input TypeText Area
Values RequiredNo
Attribute Coderemote_images
ScopeStore View (or Global depending on your setup)
Used in Product ListingYes
Visible on Catalog Pages on StorefrontNo (data is used internally)
  1. 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 ObjectManager usage; replaced with ProductRepositoryInterface DI.
  • 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_version from module.xml.
  • Renamed Plugin\Adminhtml\Thumbnail class to RemoteThumbnailPlugin to avoid class name collision with Magento\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

  1. Fork the repository.
  2. Create a feature branch: git checkout -b feature/your-feature
  3. Commit your changes following Magento Coding Standards.
  4. Push to the branch: git push origin feature/your-feature
  5. 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