From 51a79335109f42d5e3598850b228c7c100825a10 Mon Sep 17 00:00:00 2001 From: Tyler Date: Fri, 10 Jul 2026 09:08:34 -0600 Subject: [PATCH 1/3] fix(ga4): use sdk.cma directly in Sidebar instead of useCMA [AIS-59] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit useCMA() from react-apps-toolkit internally calls createClient() from contentful-management, which can fail due to CJS/ESM interop issues introduced in newer app-sdk versions. Mirrors the fix applied to AssignContentTypeSection in the config screen — use sdk.cma directly since app-sdk >= 4.20 exposes it on the SDK instance. Co-Authored-By: Claude Sonnet 4.6 --- apps/google-analytics-4/frontend/src/locations/Sidebar.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/google-analytics-4/frontend/src/locations/Sidebar.tsx b/apps/google-analytics-4/frontend/src/locations/Sidebar.tsx index 1984f175b9..41ac0d8a2a 100644 --- a/apps/google-analytics-4/frontend/src/locations/Sidebar.tsx +++ b/apps/google-analytics-4/frontend/src/locations/Sidebar.tsx @@ -1,5 +1,5 @@ import AnalyticsApp from 'components/main-app/AnalyticsApp/AnalyticsApp'; -import { useCMA, useSDK } from '@contentful/react-apps-toolkit'; +import { useSDK } from '@contentful/react-apps-toolkit'; import { SidebarExtensionSDK } from '@contentful/app-sdk'; import { useMemo } from 'react'; import { Skeleton } from '@contentful/f36-components'; @@ -13,7 +13,6 @@ import { contentfulContext } from 'helpers/contentfulContext'; const Sidebar = () => { const sdk = useSDK(); - const cma = useCMA(); const installationParameters = sdk.parameters.installation as | AppInstallationParameters | undefined; @@ -26,8 +25,8 @@ const Sidebar = () => { (rule) => rule.contentTypeId === currentContentType ); const api = useMemo( - () => new Api(contentfulContext(sdk), cma, serviceAccountKeyId), - [cma, sdk, serviceAccountKeyId] + () => new Api(contentfulContext(sdk), sdk.cma, serviceAccountKeyId), + [sdk, serviceAccountKeyId] ); const hasInstallationParams = serviceAccountKeyId && propertyId; From c72c7d30ef7f75855127199ee177f4fe88646d8a Mon Sep 17 00:00:00 2001 From: Tyler Date: Fri, 10 Jul 2026 09:39:29 -0600 Subject: [PATCH 2/3] fix(ga4): loosen ZRunReportData Zod schema for optional proto3 fields [ES-433] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit currencyCode and timeZone in ResponseMetaData are optional proto3 fields. When not set (e.g. non-ecommerce GA4 properties), protobufjs binary decode produces undefined for both the field value and the oneof discriminator (_currencyCode / _timeZone). JSON.stringify drops undefined keys entirely, so the frontend receives a JSON payload where those fields are absent. The previous strict z.string() on these fields caused ZodError for any property without currency tracking → malformedApiResponse error type → generic "We couldn't load Google Analytics data" message. Also widens propertyQuota from z.null() to z.unknown() since high-traffic properties return a QuotaStatus object rather than null. Co-Authored-By: Claude Sonnet 4.6 --- .../frontend/src/apis/apiTypes.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/google-analytics-4/frontend/src/apis/apiTypes.ts b/apps/google-analytics-4/frontend/src/apis/apiTypes.ts index d87adc6c5c..455ff72a17 100644 --- a/apps/google-analytics-4/frontend/src/apis/apiTypes.ts +++ b/apps/google-analytics-4/frontend/src/apis/apiTypes.ts @@ -52,13 +52,16 @@ export const ZRunReportData = z.object({ minimums: z.array(ZRow), rowCount: z.number(), metadata: z.object({ - currencyCode: z.string(), + // currencyCode is an optional proto3 field — absent from JSON when not set (non-ecommerce properties) + currencyCode: z.string().optional(), dataLossFromOtherRow: z.boolean(), - timeZone: z.string(), - _currencyCode: z.string(), - _timeZone: z.string(), + timeZone: z.string().optional(), + // _currencyCode/_timeZone are protobuf oneof discriminators — absent from JSON when field is not set + _currencyCode: z.string().optional(), + _timeZone: z.string().optional(), }), - propertyQuota: z.null(), + // null when quota tracking is disabled; object when property has quota data + propertyQuota: z.unknown(), kind: z.string(), }); From 2011febcf801a2e4fc35b25d15687b9c6cd58760 Mon Sep 17 00:00:00 2001 From: Tyler Date: Fri, 10 Jul 2026 09:51:08 -0600 Subject: [PATCH 3/3] fix(ga4): remove inline comments from ZRunReportData schema Co-Authored-By: Claude Sonnet 4.6 --- apps/google-analytics-4/frontend/src/apis/apiTypes.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/google-analytics-4/frontend/src/apis/apiTypes.ts b/apps/google-analytics-4/frontend/src/apis/apiTypes.ts index 455ff72a17..7a173899c5 100644 --- a/apps/google-analytics-4/frontend/src/apis/apiTypes.ts +++ b/apps/google-analytics-4/frontend/src/apis/apiTypes.ts @@ -52,15 +52,12 @@ export const ZRunReportData = z.object({ minimums: z.array(ZRow), rowCount: z.number(), metadata: z.object({ - // currencyCode is an optional proto3 field — absent from JSON when not set (non-ecommerce properties) currencyCode: z.string().optional(), dataLossFromOtherRow: z.boolean(), timeZone: z.string().optional(), - // _currencyCode/_timeZone are protobuf oneof discriminators — absent from JSON when field is not set _currencyCode: z.string().optional(), _timeZone: z.string().optional(), }), - // null when quota tracking is disabled; object when property has quota data propertyQuota: z.unknown(), kind: z.string(), });