Commit 95395451d55 for woocommerce

commit 95395451d55afdd200e21bfc962de6c421981974
Author: Luigi Teschio <gigitux@gmail.com>
Date:   Fri Sep 18 14:42:41 2026 +0200

    Hide incompatible WooCommerce template parts in the inserter (#68856)

    * Fix incompatible template parts appearing in the inserter

    * Add changelog for template part inserter fix

    * Improve E2E test

    * fix selector

    * fix E2E test

    * fix logic

diff --git a/plugins/woocommerce/changelog/fix-hide-incompatible-template-parts b/plugins/woocommerce/changelog/fix-hide-incompatible-template-parts
new file mode 100644
index 00000000000..339efa282c9
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-hide-incompatible-template-parts
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Hide Mini Cart and Add to Cart with Options template parts from the block inserter, including instance variations.
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/index.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/index.tsx
index 0040333b435..97a1cb64b90 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/index.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/index.tsx
@@ -5,7 +5,6 @@ import { button } from '@wordpress/icons';
 import { getPlugin, registerPlugin } from '@wordpress/plugins';
 import { registerProductBlockType } from '@woocommerce/atomic-utils';
 import type { BlockConfiguration } from '@wordpress/blocks';
-import { addFilter } from '@wordpress/hooks';

 /**
  * Internal dependencies
@@ -46,30 +45,3 @@ registerProductBlockType< Attributes >(
 		isAvailableOnPostEditor: true,
 	}
 );
-
-// Remove the Add to Cart + Options template part from the block inserter.
-addFilter(
-	'blocks.registerBlockType',
-	'woocommerce/area_add-to-cart-with-options',
-	function ( blockSettings, blockName ) {
-		if ( blockName === 'core/template-part' ) {
-			return {
-				...blockSettings,
-				variations: blockSettings.variations.map(
-					( variation: { name: string } ) => {
-						if (
-							variation.name === 'area_add-to-cart-with-options'
-						) {
-							return {
-								...variation,
-								scope: [],
-							};
-						}
-						return variation;
-					}
-				),
-			};
-		}
-		return blockSettings;
-	}
-);
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/index.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/index.tsx
index 2701681464a..d2f0fb709f2 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/index.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/index.tsx
@@ -4,7 +4,6 @@
 import { miniCartAlt } from '@woocommerce/icons';
 import { Icon } from '@wordpress/icons';
 import { registerBlockType } from '@wordpress/blocks';
-import { addFilter } from '@wordpress/hooks';
 /**
  * Internal dependencies
  */
@@ -44,28 +43,3 @@ registerBlockType( metadata, {
 		return null;
 	},
 } );
-
-// Remove the Mini Cart template part from the block inserter.
-addFilter(
-	'blocks.registerBlockType',
-	'woocommerce/area_mini-cart',
-	function ( blockSettings, blockName ) {
-		if ( blockName === 'core/template-part' ) {
-			return {
-				...blockSettings,
-				variations: blockSettings.variations.map(
-					( variation: { name: string } ) => {
-						if ( variation.name === 'area_mini-cart' ) {
-							return {
-								...variation,
-								scope: [],
-							};
-						}
-						return variation;
-					}
-				),
-			};
-		}
-		return blockSettings;
-	}
-);
diff --git a/plugins/woocommerce/client/blocks/assets/js/filters/hide-incompatible-template-parts.ts b/plugins/woocommerce/client/blocks/assets/js/filters/hide-incompatible-template-parts.ts
new file mode 100644
index 00000000000..811d8107439
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/assets/js/filters/hide-incompatible-template-parts.ts
@@ -0,0 +1,46 @@
+/**
+ * External dependencies
+ */
+import type { BlockVariation } from '@wordpress/blocks';
+import { addFilter } from '@wordpress/hooks';
+
+// These areas require their owning WooCommerce block to render correctly.
+const INCOMPATIBLE_TEMPLATE_PART_AREAS = [
+	'mini-cart',
+	'add-to-cart-with-options',
+];
+
+addFilter(
+	'blocks.registerBlockType',
+	'woocommerce/hide-incompatible-template-parts',
+	(
+		blockSettings: { variations?: BlockVariation< { area?: string } >[] },
+		blockName: string
+	) => {
+		if (
+			blockName !== 'core/template-part' ||
+			! blockSettings.variations
+		) {
+			return blockSettings;
+		}
+
+		return {
+			...blockSettings,
+			variations: blockSettings.variations.map( ( variation ) => {
+				if (
+					INCOMPATIBLE_TEMPLATE_PART_AREAS.includes(
+						variation.attributes?.area ?? ''
+					)
+				) {
+					return {
+						...variation,
+						scope: ( variation.scope ?? [] ).filter(
+							( scope ) => scope !== 'inserter'
+						),
+					};
+				}
+				return variation;
+			} ),
+		};
+	}
+);
diff --git a/plugins/woocommerce/client/blocks/assets/js/index.js b/plugins/woocommerce/client/blocks/assets/js/index.js
index d481cda11f1..28ae6325465 100644
--- a/plugins/woocommerce/client/blocks/assets/js/index.js
+++ b/plugins/woocommerce/client/blocks/assets/js/index.js
@@ -5,5 +5,6 @@ import '../css/editor.scss';
 import '../css/style.scss';
 import './filters/block-list-block';
 import './filters/get-block-attributes';
+import './filters/hide-incompatible-template-parts';
 import './filters/unregister-block-types';
 import './base/components/notice-banner/style.scss';
diff --git a/plugins/woocommerce/tests/e2e/tests/site-editor/template-parts-inserter.spec.ts b/plugins/woocommerce/tests/e2e/tests/site-editor/template-parts-inserter.spec.ts
new file mode 100644
index 00000000000..56171165a90
--- /dev/null
+++ b/plugins/woocommerce/tests/e2e/tests/site-editor/template-parts-inserter.spec.ts
@@ -0,0 +1,65 @@
+/**
+ * External dependencies
+ */
+import { Admin, Editor, PageUtils } from '@wordpress/e2e-test-utils-playwright';
+
+/**
+ * Internal dependencies
+ */
+import { test, expect } from '../../fixtures/fixtures';
+import { ADMIN_STATE_PATH } from '../../playwright.config';
+
+test.use( { storageState: ADMIN_STATE_PATH } );
+
+test.describe( 'Template parts in the Site Editor inserter', () => {
+	test( 'shows only compatible template parts', async ( { page } ) => {
+		const editor = new Editor( { page } );
+		const admin = new Admin( {
+			page,
+			editor,
+			pageUtils: new PageUtils( { page } ),
+		} );
+		await admin.visitSiteEditor( { canvas: 'edit' } );
+		await page
+			.getByRole( 'button', { name: 'Block Inserter', exact: true } )
+			.click();
+
+		await test.step( 'can insert a template part not related to Mini-Cart and Add to Cart + Options', async () => {
+			await page
+				.getByRole( 'searchbox', { name: 'Search' } )
+				.fill( 'Footer' );
+
+			await expect(
+				page.locator( '.editor-block-list-item-template-part' )
+			).toBeVisible();
+		} );
+
+		await test.step( "can't insert the Mini Cart template part", async () => {
+			await page
+				.getByRole( 'searchbox', { name: 'Search' } )
+				.fill( 'Mini-Cart' );
+			const miniCart = page
+				.getByRole( 'listbox', { name: 'Blocks', exact: true } )
+				.getByRole( 'option', { name: 'Mini-Cart', exact: true } );
+			await expect( miniCart ).toHaveCount( 1 );
+			await expect( miniCart ).toBeVisible();
+		} );
+
+		await test.step( 'hides the Add to Cart + Options template parts', async () => {
+			for ( const productType of [
+				'Simple',
+				'Variable',
+				'Grouped',
+				'External',
+			] ) {
+				const title = `${ productType } Product Add to Cart + Options`;
+				await page
+					.getByRole( 'searchbox', { name: 'Search' } )
+					.fill( title );
+				await expect(
+					page.getByRole( 'option', { name: title, exact: true } )
+				).toHaveCount( 0 );
+			}
+		} );
+	} );
+} );