From cb31b4829d9a35e2c1b16c5e6fa12a2c612e43a9 Mon Sep 17 00:00:00 2001 From: Igor Kozlov Date: Fri, 14 Aug 2026 15:09:39 -0400 Subject: [PATCH] Support the ui_extension_bundle_size_exception capability Adds ui_extension_bundle_size_exception to the extension capabilities schema so extensions declaring it in shopify.extension.toml include it in the configuration deployed to Shopify. The backend raises the Remote DOM compressed bundle size limit for extensions declaring this capability when the app has been granted a bundle size exception approval scope by Shopify. Intentionally undocumented: grants are shared directly with partners who requested an exception. --- .changeset/spicy-crabs-bundle.md | 5 ++ .../app/src/cli/models/extensions/schemas.ts | 1 + .../specifications/ui_extension.test.ts | 47 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 .changeset/spicy-crabs-bundle.md diff --git a/.changeset/spicy-crabs-bundle.md b/.changeset/spicy-crabs-bundle.md new file mode 100644 index 00000000000..2a336a70518 --- /dev/null +++ b/.changeset/spicy-crabs-bundle.md @@ -0,0 +1,5 @@ +--- +'@shopify/app': minor +--- + +Support the ui_extension_bundle_size_exception extension capability diff --git a/packages/app/src/cli/models/extensions/schemas.ts b/packages/app/src/cli/models/extensions/schemas.ts index 04978437b76..da5fea4dc87 100644 --- a/packages/app/src/cli/models/extensions/schemas.ts +++ b/packages/app/src/cli/models/extensions/schemas.ts @@ -26,6 +26,7 @@ const CapabilitiesSchema = zod.object({ api_access: zod.boolean().optional(), collect_buyer_consent: CollectBuyerConsentCapabilitySchema.optional(), iframe: IframeCapabilitySchema.optional(), + ui_extension_bundle_size_exception: zod.boolean().optional(), }) const SupportedFeaturesSchema = zod.object({ diff --git a/packages/app/src/cli/models/extensions/specifications/ui_extension.test.ts b/packages/app/src/cli/models/extensions/specifications/ui_extension.test.ts index 3d5d5f6f1a1..bbd3d1997a0 100644 --- a/packages/app/src/cli/models/extensions/specifications/ui_extension.test.ts +++ b/packages/app/src/cli/models/extensions/specifications/ui_extension.test.ts @@ -942,6 +942,53 @@ Please check the configuration in ${uiExtension.configurationPath}`), }) }) + test('includes the ui_extension_bundle_size_exception capability in the deploy config', async () => { + await inTemporaryDirectory(async (tmpDir) => { + // Given + vi.spyOn(loadLocales, 'loadLocalesConfig').mockResolvedValue({}) + const configurationPath = joinPath(tmpDir, 'shopify.extension.toml') + const allSpecs = await loadLocalExtensionsSpecifications() + const specification = allSpecs.find((spec) => spec.identifier === 'ui_extension')! + const parsed = specification.parseConfigurationObject({ + targeting: [ + { + target: 'EXTENSION::POINT::A', + module: './src/ExtensionPointA.js', + }, + ], + api_version: '2025-10' as const, + name: 'UI Extension', + type: 'ui_extension', + handle: 'test-ui-extension', + capabilities: { + ui_extension_bundle_size_exception: true, + }, + settings: {}, + }) + if (parsed.state !== 'ok') { + throw new Error("Couldn't parse configuration") + } + const uiExtension = new ExtensionInstance({ + configuration: parsed.data, + directory: tmpDir, + specification, + configurationPath, + entryPath: '', + }) + + // When + const deployConfig = await uiExtension.deployConfig({ + apiKey: 'apiKey', + appConfiguration: placeholderAppConfiguration, + }) + + // Then + expect(deployConfig?.capabilities).toStrictEqual({ + ui_extension_bundle_size_exception: true, + }) + }) + }) + test('returns supported_features with runs_offline true when configured', async () => { await inTemporaryDirectory(async (tmpDir) => { // Given