Commit e45354276ce for woocommerce
commit e45354276cecc405dbb8b455c4955d84d1c1a262
Author: Brian <brian@brianhaas.li>
Date: Fri Jun 12 13:36:12 2026 +0200
feat: Add image_size query parameter to products and variations REST API endpoints (#64009)
* add image size support
* add image_size support
* add image size support
* Add changefile(s) from automation for the following project(s): woocommerce
* fix coderabbit inputs
* add coderabbit inputs
* add Missing PHPDoc for the new $image_size parameter
* add v4
* fix lint error
* add v3 variations rest api
* update rest api docs
* add docs
* add v4 support
* keep src/srcset/sizes aligned with image_size in products responses
---------
Co-authored-by: woocommercebot <woocommercebot@users.noreply.github.com>
Co-authored-by: Karol Manijak <20098064+kmanijak@users.noreply.github.com>
diff --git a/docs/apis/rest-api/v2/product-variations.mdx b/docs/apis/rest-api/v2/product-variations.mdx
index ef20da411a9..80d336f3bd4 100644
--- a/docs/apis/rest-api/v2/product-variations.mdx
+++ b/docs/apis/rest-api/v2/product-variations.mdx
@@ -680,6 +680,7 @@ woocommerce.get("products/22/variations").parsed_response
| `on_sale` | boolean | Limit result set to products on sale. |
| `min_price` | string | Limit result set to products based on a minimum price. |
| `max_price` | string | Limit result set to products based on a maximum price. |
+| `image_size` | string | Use a specific registered image size for the returned variation image `src`. Falls back to the full size if the requested size is not registered. Default is `full`. |
## Update a product variation
This API lets you make changes to a product variation.
@@ -1524,4 +1525,4 @@ woocommerce.post("products/22/variations/batch", data).parsed_response
```
</TabItem>
-</Tabs>
+</Tabs>
\ No newline at end of file
diff --git a/docs/apis/rest-api/v2/products.mdx b/docs/apis/rest-api/v2/products.mdx
index 50082752e17..5a36d74f193 100644
--- a/docs/apis/rest-api/v2/products.mdx
+++ b/docs/apis/rest-api/v2/products.mdx
@@ -1591,6 +1591,7 @@ woocommerce.get("products").parsed_response
| `on_sale` | boolean | Limit result set to products on sale. |
| `min_price` | string | Limit result set to products based on a minimum price. |
| `max_price` | string | Limit result set to products based on a maximum price. |
+| `image_size` | string | Use a specific registered image size for the returned image `src` values. Falls back to the full size if the requested size is not registered. Default is `full`. |
## Update a product
This API lets you make changes to a product.
@@ -3219,4 +3220,4 @@ woocommerce.get("products/22/reviews").parsed_response
```
</TabItem>
-</Tabs>
+</Tabs>
\ No newline at end of file
diff --git a/docs/apis/rest-api/v3/api-reference.mdx b/docs/apis/rest-api/v3/api-reference.mdx
index c5ca47474e6..8f16e774cf3 100644
--- a/docs/apis/rest-api/v3/api-reference.mdx
+++ b/docs/apis/rest-api/v3/api-reference.mdx
@@ -5329,6 +5329,12 @@ woocommerce.get("").parsed_response
"required": false,
"description": "Limit result set to products based on a maximum price.",
"type": "string"
+ },
+ "image_size": {
+ "required": false,
+ "default": "full",
+ "description": "Use a specific registered image size for the returned image src values. Falls back to the full size if the requested size is not registered.",
+ "type": "string"
}
}
},
@@ -5818,6 +5824,12 @@ woocommerce.get("").parsed_response
"enum": [ "view", "edit" ],
"description": "Scope under which the request is made; determines fields present in response.",
"type": "string"
+ },
+ "image_size": {
+ "required": false,
+ "default": "full",
+ "description": "Use a specific registered image size for the returned image src values. Falls back to the full size if the requested size is not registered.",
+ "type": "string"
}
}
},
@@ -6947,6 +6959,12 @@ woocommerce.get("").parsed_response
"required": false,
"description": "Limit result set to products based on a maximum price.",
"type": "string"
+ },
+ "image_size": {
+ "required": false,
+ "default": "full",
+ "description": "Use a specific registered image size for the returned variation image src. Falls back to the full size if the requested size is not registered.",
+ "type": "string"
}
}
},
@@ -7202,6 +7220,12 @@ woocommerce.get("").parsed_response
"enum": [ "view", "edit" ],
"description": "Scope under which the request is made; determines fields present in response.",
"type": "string"
+ },
+ "image_size": {
+ "required": false,
+ "default": "full",
+ "description": "Use a specific registered image size for the returned variation image src. Falls back to the full size if the requested size is not registered.",
+ "type": "string"
}
}
},
@@ -8988,4 +9012,4 @@ woocommerce.get("").parsed_response
```
</TabItem>
-</Tabs>
+</Tabs>
\ No newline at end of file
diff --git a/docs/apis/rest-api/v3/product-variations.mdx b/docs/apis/rest-api/v3/product-variations.mdx
index bbb0a6f15e0..6fb7e30b385 100644
--- a/docs/apis/rest-api/v3/product-variations.mdx
+++ b/docs/apis/rest-api/v3/product-variations.mdx
@@ -313,6 +313,8 @@ This API lets you retrieve and view a specific product variation by ID.
GET /wp-json/wc/v3/products/<product_id>/variations/<id>
```
+Optional query parameter: `image_size` (string). Use a specific registered image size for returned variation image `src`. Falls back to the full size when the requested size is not registered. Default is `full`.
+
<Tabs>
<TabItem value="curl" label="cURL">
@@ -689,6 +691,7 @@ woocommerce.get("products/22/variations").parsed_response
| `stock_status` | string | Limit result set to products with specified stock status. Options: `instock`, `outofstock` and `onbackorder`. |
| `virtual` | boolean | Limit result set to virtual product variations |
| `downloadable` | boolean | Limit result set to downloadable product variations. |
+| `image_size` | string | Use a specific registered image size for the returned variation image `src`. Falls back to the full size if the requested size is not registered. Default is `full`. |
## Update a product variation
@@ -1536,4 +1539,4 @@ woocommerce.post("products/22/variations/batch", data).parsed_response
```
</TabItem>
-</Tabs>
+</Tabs>
\ No newline at end of file
diff --git a/docs/apis/rest-api/v3/products.mdx b/docs/apis/rest-api/v3/products.mdx
index 4344ac24f4b..55bd1f4543f 100644
--- a/docs/apis/rest-api/v3/products.mdx
+++ b/docs/apis/rest-api/v3/products.mdx
@@ -989,6 +989,8 @@ This API lets you retrieve and view a specific product by ID.
GET /wp-json/wc/v3/products/<id>
```
+Optional query parameter: `image_size` (string). Use a specific registered image size for returned image `src` values. Falls back to the full size when the requested size is not registered. Default is `full`.
+
<Tabs>
<TabItem value="curl" label="cURL">
@@ -1536,6 +1538,7 @@ woocommerce.get("products").parsed_response
| `stock_status` | string | Limit result set to products with specified stock status. Options: `instock`, `outofstock` and `onbackorder`. |
| `virtual` | boolean | Limit result set to virtual products. |
| `downloadable` | boolean | Limit result set to downloadable products. |
+| `image_size` | string | Use a specific registered image size for the returned image `src` values. Falls back to the full size if the requested size is not registered. Default is `full`. |
## Duplicate product
@@ -2982,4 +2985,4 @@ woocommerce.post("products/batch", data).parsed_response
```
</TabItem>
-</Tabs>
+</Tabs>
\ No newline at end of file
diff --git a/plugins/woocommerce/changelog/64009-37525-image-size-restapi b/plugins/woocommerce/changelog/64009-37525-image-size-restapi
new file mode 100644
index 00000000000..59c9fd648bb
--- /dev/null
+++ b/plugins/woocommerce/changelog/64009-37525-image-size-restapi
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Add image_size query parameter to the products and product variations REST API endpoints, allowing consumers to request a specific registered WordPress image size.
\ No newline at end of file
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php
index 6fe5f040b3d..51ec47470de 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php
@@ -148,11 +148,18 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr
),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
- 'context' => $this->get_context_param(
+ 'context' => $this->get_context_param(
array(
'default' => 'view',
)
),
+ 'image_size' => array(
+ 'description' => __( 'Image size to return. Accepts any registered WordPress image size.', 'woocommerce' ),
+ 'type' => 'string',
+ 'default' => 'full',
+ 'sanitize_callback' => 'sanitize_text_field',
+ 'validate_callback' => 'rest_validate_request_arg',
+ ),
),
),
array(
@@ -329,7 +336,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr
),
'shipping_class' => $object->get_shipping_class(),
'shipping_class_id' => $object->get_shipping_class_id(),
- 'image' => current( $this->get_images( $object ) ),
+ 'image' => current( $this->get_images( $object, $request['image_size'] ?? 'full' ) ),
'attributes' => $this->get_attributes( $object ),
'menu_order' => $object->get_menu_order(),
'meta_data' => $object->get_meta_data(),
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php
index 5fb0e0ed512..77b6348c31e 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php
@@ -176,11 +176,18 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller {
),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
- 'context' => $this->get_context_param(
+ 'context' => $this->get_context_param(
array(
'default' => 'view',
)
),
+ 'image_size' => array(
+ 'description' => __( 'Image size to return. Accepts any registered WordPress image size.', 'woocommerce' ),
+ 'type' => 'string',
+ 'default' => 'full',
+ 'sanitize_callback' => 'sanitize_text_field',
+ 'validate_callback' => 'rest_validate_request_arg',
+ ),
),
),
array(
@@ -516,10 +523,11 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller {
* Get the images for a product or product variation.
*
* @param WC_Product|WC_Product_Variation $product Product instance.
+ * @param string $image_size WordPress registered image size. Default 'full'.
*
* @return array
*/
- protected function get_images( $product ) {
+ protected function get_images( $product, $image_size = 'full' ) {
$images = array();
$attachment_ids = array();
@@ -543,7 +551,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller {
continue;
}
- $attachment = wp_get_attachment_image_src( $attachment_id, 'full' );
+ $attachment = wp_get_attachment_image_src( $attachment_id, $image_size );
if ( ! is_array( $attachment ) ) {
continue;
}
@@ -1004,7 +1012,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller {
$base_data['tags'] = $this->get_taxonomy_terms( $product, 'tag' );
break;
case 'images':
- $base_data['images'] = $this->get_images( $product );
+ $base_data['images'] = $this->get_images( $product, $request['image_size'] ?? 'full' );
break;
case 'attributes':
$base_data['attributes'] = $this->get_attributes( $product );
@@ -2575,6 +2583,13 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller {
),
'sanitize_callback' => 'wp_parse_list',
);
+ $params['image_size'] = array(
+ 'description' => __( 'Image size to return. Accepts any registered WordPress image size.', 'woocommerce' ),
+ 'type' => 'string',
+ 'default' => 'full',
+ 'sanitize_callback' => 'sanitize_text_field',
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
return $params;
}
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php
index 410c6c40e5f..5013c1a6423 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php
@@ -156,7 +156,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V
),
'shipping_class' => $object->get_shipping_class(),
'shipping_class_id' => $object->get_shipping_class_id(),
- 'image' => $this->get_image( $object, $context ),
+ 'image' => $this->get_image( $object, $context, isset( $request['image_size'] ) ? $request['image_size'] : 'full' ),
'gallery_image_ids' => $object instanceof WC_Product ? array_map( 'intval', $object->get_gallery_image_ids() ) : array(),
'attributes' => $this->get_attributes( $object ),
'menu_order' => $object->get_menu_order(),
@@ -448,11 +448,12 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V
/**
* Get the image for a product variation.
*
- * @param WC_Product_Variation $variation Variation data.
- * @param string $context Context of the request: 'view' or 'edit'.
+ * @param WC_Product_Variation $variation Variation data.
+ * @param string $context Context of the request: 'view' or 'edit'.
+ * @param string $image_size Optional. WordPress registered image size to use for the image src. Default 'full'.
* @return array
*/
- protected function get_image( $variation, $context = 'view' ) {
+ protected function get_image( $variation, $context = 'view', $image_size = 'full' ) {
if ( ! $variation->get_image_id( $context ) ) {
return;
}
@@ -463,7 +464,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V
return;
}
- $attachment = wp_get_attachment_image_src( $attachment_id, 'full' );
+ $attachment = wp_get_attachment_image_src( $attachment_id, $image_size );
if ( ! is_array( $attachment ) ) {
return;
}
@@ -1287,6 +1288,14 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V
'validate_callback' => 'rest_validate_request_arg',
);
+ $params['image_size'] = array(
+ 'description' => __( 'Use a specific registered image size for the returned variation image src. Falls back to the full size if the requested size is not registered.', 'woocommerce' ),
+ 'type' => 'string',
+ 'default' => 'full',
+ 'sanitize_callback' => 'sanitize_text_field',
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+
return $params;
}
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php
index d4296b32f87..59353f4afa8 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php
@@ -161,10 +161,11 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller {
/**
* Get the images for a product or product variation.
*
- * @param WC_Product|WC_Product_Variation $product Product instance.
+ * @param WC_Product|WC_Product_Variation $product Product instance.
+ * @param string $image_size Image size to use. Default 'full'.
* @return array
*/
- protected function get_images( $product ) {
+ protected function get_images( $product, $image_size = 'full' ) {
$images = array();
$attachment_ids = array();
@@ -188,7 +189,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller {
continue;
}
- $attachment = wp_get_attachment_image_src( $attachment_id, 'full' );
+ $attachment = wp_get_attachment_image_src( $attachment_id, $image_size );
if ( ! is_array( $attachment ) ) {
continue;
@@ -204,8 +205,8 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller {
'src' => current( $attachment ),
'name' => get_the_title( $attachment_id ),
'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ),
- 'srcset' => (string) wp_get_attachment_image_srcset( $attachment_id, 'full' ),
- 'sizes' => (string) wp_get_attachment_image_sizes( $attachment_id, 'full' ),
+ 'srcset' => (string) wp_get_attachment_image_srcset( $attachment_id, $image_size ),
+ 'sizes' => (string) wp_get_attachment_image_sizes( $attachment_id, $image_size ),
'thumbnail' => current( $thumbnail ),
);
}
diff --git a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Products/Controller.php b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Products/Controller.php
index bf4fb934f72..6c6b8cd1ce4 100644
--- a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Products/Controller.php
+++ b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Products/Controller.php
@@ -277,9 +277,10 @@ class Controller extends WC_REST_Products_V2_Controller {
* Get the images for a product or product variation.
*
* @param WC_Product|WC_Product_Variation $product Product instance.
+ * @param string $image_size Image size to use for the src. Default 'full'.
* @return array
*/
- protected function get_images( $product ) {
+ protected function get_images( $product, $image_size = 'full' ) {
$images = array();
$attachment_ids = array();
@@ -303,7 +304,7 @@ class Controller extends WC_REST_Products_V2_Controller {
continue;
}
- $attachment = wp_get_attachment_image_src( $attachment_id, 'full' );
+ $attachment = wp_get_attachment_image_src( $attachment_id, $image_size );
if ( ! is_array( $attachment ) ) {
continue;
@@ -319,8 +320,8 @@ class Controller extends WC_REST_Products_V2_Controller {
'src' => current( $attachment ),
'name' => get_the_title( $attachment_id ),
'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ),
- 'srcset' => (string) wp_get_attachment_image_srcset( $attachment_id, 'full' ),
- 'sizes' => (string) wp_get_attachment_image_sizes( $attachment_id, 'full' ),
+ 'srcset' => (string) wp_get_attachment_image_srcset( $attachment_id, $image_size ),
+ 'sizes' => (string) wp_get_attachment_image_sizes( $attachment_id, $image_size ),
'thumbnail' => current( $thumbnail ),
);
}