Docs

Web SDK 2.0

What changes when you move the Grovs Web SDK from 1.x to 2.0

2.0.0 is a TypeScript rewrite of the Web SDK that brings it to parity with the iOS and Android SDKs. Your existing 1.x code keeps working: the constructor and every callback method are preserved as a deprecated compatibility layer. Two accessors now return corrected values, and the SDK starts sending events that 1.x never sent.

The Web SDK's current major version is 2.0.0, not 3.0.0. The 3.0 major used by the native SDKs is where the deprecated 1.x layer is scheduled for removal.

Checklist

  1. Bump the dependency to 2.0.0.
  2. Fix code that compensated for the swapped accessors.
  3. Expect a step change in your dashboards.
  4. Move to the new API at your own pace — the 1.x surface is removed in 3.0.
  5. Check the other behavior changes.

1. Bump the version

Bash
npm install grovs@^2.0.0

The package now publishes only dist/, with ESM, CommonJS, and IIFE builds plus type declarations. If you imported anything from grovs/src, that path no longer exists.

2. Check userIdentifier() and userAttributes()

This is the only 1.x behavior deliberately not preserved.

1.x assigned the authenticate response backwards, putting the user identifier into the attributes slot and the attributes into the identifier slot. 2.0 fixes it:

Call1.x returned2.0 returns
userIdentifier()the user attributesthe user identifier
userAttributes()the user identifierthe user attributes

If you noticed this and compensated — reading userAttributes() when you wanted the identifier — remove that workaround. Your code still compiles and runs after upgrading; it simply returns the wrong value.

3. Events now actually fire

1.x shipped an event queue whose addEvent() had no callers, so the web reported zero installs, opens, and engagement time. 2.0 emits the full set: install and reinstall, app_open, time_spent, reactivation, plus your custom events.

Expect a step change in your dashboards on the day you upgrade. The series was flat zero before and will not be afterwards. That is the defect being fixed, but it looks like an anomaly if nobody was told.

4. Move to the new API

Constructing the default export returns the deprecated 1.x surface, so existing npm and CDN integrations (new Grovs(...) and new Grovs.default(...)) keep working without edits. The same class is also reachable as Grovs.V1. Each deprecated method logs one warning naming its replacement.

// 1.x — still works, deprecated
import Grovs from "grovs";
 
const sdk = new Grovs("your-api-key", false, (data) => console.log(data));
await sdk.start();
 
// 2.0
import Grovs from "grovs";
 
await Grovs.configure({
  apiKey: "your-api-key",
  testEnvironment: false,
  onDeeplink: (payload) => console.log("deep link", payload),
  onError: (code, message) => console.error("grovs error", code, message),
});

The constructor and Grovs.configure() each build their own client. Using both on one page runs sessions, launch events, and timers twice. Pick one; the SDK warns if it sees both.

Method mapping

1.x2.0
new Grovs(key, testEnv, cb) + .start()Grovs.configure({ apiKey, testEnvironment, onDeeplink })
createLink(title, subtitle, imageURL, data, ok, err)generateLink({ title, subtitle, imageURL, data }) → Promise
setUserIdentifier, setUserAttributessame signature, corrected values
userIdentifier(), userAttributes()Grovs.userIdentifier, Grovs.userAttributes (accessors), corrected values
authenticated()isAuthenticated()
getAllReceivedData()allReceivedPayloadsSinceStartup()
showMessagesList()unchanged, now returns a Promise
getMessages(page, ok, err)getMessages(page) → Promise
getNumberOfUnreadMessages(ok, err)numberOfUnreadMessages() → Promise
markMessageAsRead(msg, ok, err)markMessageAsRead(id) → Promise

5. Check the other behavior changes

Errors reach your code. Pass onError to configure. Every failure in 1.x was a bare console.log, so a broken install was undetectable. See Handling SDK errors.

Automatic screen tracking is on. autoTrackScreenViews defaults to true, so single-page-app route changes fire screen_view events. This applies to the 1.x constructor too, which cannot turn it off. Pass autoTrackScreenViews: false to Grovs.configure() to opt out, and use aliases to collapse high-cardinality URLs.

PROJECT-KEY replaces PROJECT_KEY on the wire. No action needed on Grovs cloud. If you self-host behind nginx, note that nginx drops underscored headers under its default configuration, so this removes a latent 403.

Importing during server rendering no longer throws. Call configure on the client; a server-side call logs and reports through onError once per call.

Optional cookieDomain. 1.x wrote a host-only cookie. Set cookieDomain if you need identity to span subdomains. A host-only cookie left by 1.x that shadows the new one is repaired on the next write.

Stored state is per project. The queue, session, and counters are keyed by project and by testEnvironment. Launch counters written by 1.x are carried over, so a returning visitor is not reported as a reinstall; an unsent 1.x queue has no known owner and is dropped rather than sent under the current project.

The messages UI is redesigned. It renders in a shadow root, no longer loads a third-party font, no longer paints its backdrop red, and renders titles as text rather than HTML. It is themeable — see Styling the messages UI.

Purchases and custom redirects are now sent correctly. 1.x sent both under field names the backend does not read, so they were silently dropped.

What's new in 2.0

Nothing here is required:

Verifying the upgrade

Turn on info logging and confirm configure resolves true:

const ready = await Grovs.configure({
  apiKey: "your-api-key",
  testEnvironment: true,
  debugLevel: "info",
  onError: (code, message) => console.error(code, message),
});
console.log("Grovs configured:", ready);

Then open the page through a Grovs link and check that onDeeplink fires, and that app_open and — if you kept automatic screen tracking — screen_view events appear in the dashboard under names you recognize.

See also

Edit this page on GitHubLast updated 2026-09-15