From c9310242ef9f839ea963ebb8ce0e6fd24eea8b73 Mon Sep 17 00:00:00 2001 From: Elmin Didic Date: Thu, 30 Apr 2026 15:53:58 -0500 Subject: [PATCH 1/2] feat(react-grab): add `silent` option to suppress intro log Lets consumers opt out of the intro banner and version-check console.log so it isn't picked up by tools like Sentry that forward console output as breadcrumbs. Co-Authored-By: Claude Opus 4.7 --- .changeset/silent-intro-option.md | 7 +++++++ packages/react-grab/src/core/index.tsx | 4 +++- packages/react-grab/src/types.ts | 7 +++++++ packages/react-grab/src/utils/get-script-options.ts | 3 +++ 4 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 .changeset/silent-intro-option.md diff --git a/.changeset/silent-intro-option.md b/.changeset/silent-intro-option.md new file mode 100644 index 000000000..a0658a7f7 --- /dev/null +++ b/.changeset/silent-intro-option.md @@ -0,0 +1,7 @@ +--- +"react-grab": minor +"grab": minor +"@react-grab/cli": minor +--- + +Add `silent` option to suppress the React Grab intro banner and version-check log. Useful when console output is forwarded to error tracking services like Sentry. diff --git a/packages/react-grab/src/core/index.tsx b/packages/react-grab/src/core/index.tsx index 8dba00964..64910846e 100644 --- a/packages/react-grab/src/core/index.tsx +++ b/packages/react-grab/src/core/index.tsx @@ -197,7 +197,9 @@ export const init = (rawOptions?: Options): ReactGrabAPI => { } hasInited = true; - logIntro(); + if (!initialOptions.silent) { + logIntro(); + } // eslint-disable-next-line @typescript-eslint/no-unused-vars -- need to omit enabled from settableOptions to avoid circular dependency const { enabled: _enabled, ...settableOptions } = initialOptions; diff --git a/packages/react-grab/src/types.ts b/packages/react-grab/src/types.ts index 31910ad6f..b46eb876a 100644 --- a/packages/react-grab/src/types.ts +++ b/packages/react-grab/src/types.ts @@ -252,6 +252,13 @@ export interface Options { * @default true */ freezeReactUpdates?: boolean; + /** + * Suppress the React Grab intro banner and version-check log. + * Useful when console output is forwarded to error tracking + * services like Sentry. + * @default false + */ + silent?: boolean; } export interface SettableOptions extends Options { diff --git a/packages/react-grab/src/utils/get-script-options.ts b/packages/react-grab/src/utils/get-script-options.ts index 98d1c37da..9c8eefe37 100644 --- a/packages/react-grab/src/utils/get-script-options.ts +++ b/packages/react-grab/src/utils/get-script-options.ts @@ -30,6 +30,9 @@ const parseOptionsFromJson = (rawValue: unknown): Partial | null => { if (typeof rawValue.freezeReactUpdates === "boolean") { parsedOptions.freezeReactUpdates = rawValue.freezeReactUpdates; } + if (typeof rawValue.silent === "boolean") { + parsedOptions.silent = rawValue.silent; + } if (Object.keys(parsedOptions).length === 0) return null; return parsedOptions; From 17ad71007d9fe91ffaca612040a183fbc5604f08 Mon Sep 17 00:00:00 2001 From: Elmin Didic Date: Fri, 1 May 2026 15:36:49 -0500 Subject: [PATCH 2/2] fix(react-grab): mark `silent` as init-only in `SettableOptions` `silent` is consumed during `init()` and has no effect at runtime, so exposing it on `api.setOptions()` would type-check as a no-op. Override it as `never` in `SettableOptions` to match the existing `enabled` pattern, and strip it alongside `enabled` before forwarding to the plugin registry. Co-Authored-By: Claude Opus 4.7 --- packages/react-grab/src/core/index.tsx | 4 ++-- packages/react-grab/src/types.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/react-grab/src/core/index.tsx b/packages/react-grab/src/core/index.tsx index 64910846e..4f0f1c30f 100644 --- a/packages/react-grab/src/core/index.tsx +++ b/packages/react-grab/src/core/index.tsx @@ -201,8 +201,8 @@ export const init = (rawOptions?: Options): ReactGrabAPI => { logIntro(); } - // eslint-disable-next-line @typescript-eslint/no-unused-vars -- need to omit enabled from settableOptions to avoid circular dependency - const { enabled: _enabled, ...settableOptions } = initialOptions; + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- need to omit init-only options from settableOptions to avoid circular dependency + const { enabled: _enabled, silent: _silent, ...settableOptions } = initialOptions; return createRoot((dispose) => { let disposed = false; diff --git a/packages/react-grab/src/types.ts b/packages/react-grab/src/types.ts index b46eb876a..27c58f71f 100644 --- a/packages/react-grab/src/types.ts +++ b/packages/react-grab/src/types.ts @@ -263,6 +263,7 @@ export interface Options { export interface SettableOptions extends Options { enabled?: never; + silent?: never; } export interface SourceInfo {