# Migrating from v3

Batch Web SDK v4 is a major release, which introduces **breaking changes** from 3.x. This guide describes how to update the script in a website already using a previous version.

### Upgrading the SDK version

To upgrade from v3 to v4, you need to change the SDK version in two places:

* On your page script or tag manager, replace `https://via.batch.com/v3/bootstrap.min.js` with `https://via.batch.com/v4/bootstrap.min.js`.
* Download the new [SDK files](https://download.batch.com/sdk/web/BatchSDK-web-4.1.2.zip) and update your service worker implementation
  * If you're using `batchsdk-worker-loader.js`, simply replace this file with the new one.
  * If you added Batch in your custom service worker implementation, set `BATCHSDK_MAJOR_VERSION`'s value to `4`.

### Service worker configuration

This version introduced a new way of configuring your service worker implementation and especially if you need to specify a registration for a sub-scope that does not control the current page.

If you were using `serviceWorkerPathOverride`, `useExistingServiceWorker` or `serviceWorkerTimeout` to integrate Batch with your own service worker (or uploading to a folder of your site), you will have to modify the Batch's SDK setup as following since this keys does not exist anymore.

```js

 batchSDK('setup', {
   ...,
   
   // Optional service worker related configuration.
   serviceWorker: {
     
     // Optional - default: 10 seconds. 
     // Maximum waiting time for your Service Worker to be ready. 
     // Replaces `serviceWorkerTimeout` but works the same.
     waitTimeout: 5,

     // Optional - default: true. 
     // Whether Batch should automatically register its service worker.
     // Replaces `useExistingServiceWorker` and works in the opposite way (default true, false to disable).
     automaticallyRegister: false,

     // Optional. A promise that resoves a service worker registration.
     // Allows you to have Batch use a specific Service Worker registration.  
     // This can be a Service Worker registration for a sub-scope that does not control the current page.
     // Requires `automaticallyRegister` to be false.
     registration: navigator.serviceWorker.register("your_custom_path")
   }
  });

```

{% hint style="warning" %}
When using `registration`, Batch can't check that your Service Worker will properly work, your integration might break if your SW is not valid for push notifications.
{% endhint %}

For more information, please see the following sections :

* [Uploading the Service Worker to a folder of your website](/developer/sdk/web/advanced/declare-path-service-worker.md#uploading-the-service-worker-to-a-folder-of-your-website)
* [Integrating Batch with an existing Service Worker](/developer/sdk/web/advanced/integrating-batch-with-existing-service-worker.md)
* [Registering a Service Worker in a sub-scope](/developer/sdk/web/advanced/declare-path-service-worker.md#registering-a-service-worker-in-a-sub-scope)

### Profile data collection

#### Data collection

This version follows Batch's pivot to being an omnichannel platform. It allows you to collect data for your **Projects** and **Profiles**. If you are not familiar with these two concepts, please see [this guide](https://doc.batch.com/getting-started/other/overview-guides/98-send-emails-with-batch#create-a-project) beforehand.

First of all, most of the user-related write APIs have been removed. Reading methods are still usable since we do not provide yet a way to get synced data for a Profile, but keep in mind that the data returned is only about your installation and not your Profile.

To interacts with our user-centered model, you should now use the `profile()` method. Let's see a migration example.

If you were previously doing something like that:

```javascript
batchSDK(api => {
  api.setCustomUserID("custom_user_id");
  api.setUserLanguage("en")
  api.setUserRegion("EN")
  api.editUserData(editor => {
    editor.removeAttribute("age")
    editor.setAttribute("is_premium", true);
    editor.addTag("favorites", "fashion")
    editor.addTag("interests", "shoes");
    editor.removeTag("interests", "cars")
  });
  api.setCustomUserID(null)
});
```

You should now do:

{% tabs %}
{% tab title="JavaScript (ES8)" %}

```javascript
batchSDK(async api => {
    const profile = await api.profile();
    await profile.identify({customId: "custom_user_id"});
    await profile.edit(editor => {
      editor.setLanguage("en")
        .setRegion("EN")
        .removeAttribute("age")
        .setAttribute("is_premium", true)
        .setAttribute("favorites", ["fashion"])
        .addToArray("interests", ["shoes"])
        .removeFromArray("interests", ["cars"])
    })
    await profile.identify(null);
});
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
batchSDK(api => {
    api.profile().then(profile => {
      profile.identify({customId: "custom_user_id"}).then(profile => {
        profile.edit(editor => {
          editor.setLanguage("en")
            .setRegion("EN")
            .removeAttribute("age")
            .setAttribute("is_premium", true)
            .setAttribute("favorites", ["fashion"])
            .addToArray("interests", ["shoes"])
            .removeFromArray("interests", ["cars"])
        }).then(profile => {
          profile.identify(null)
        })
      })
    })
});
```

{% endtab %}
{% endtabs %}

To see in details what's precisely changed since V3 please consult our [changelog](https://doc.batch.com/developer/sdk/web/advanced/pages/tu4omOvyqzzGK35iNKmp#id-4.0.0-14-12-2023) or visit the [APIs Reference](https://doc.batch.com/web-api-reference/).

For more information, please see the following sections :

* [Custom user id](/developer/sdk/web/profile-data/custom-user-id.md)
* [Custom region/language](/developer/sdk/web/profile-data/custom-locale.md)
* [Custom user attributes](/developer/sdk/web/profile-data/attributes.md)
* [Email subscription](/developer/sdk/web/profile-data/email-subscription.md)

#### Data migration

To make it easier to collect data to a Profile, Batch has added two automatic ways to migrate old installation's data on a Profile. So the first time a user will visit your website running on v4 :

* He will be automatically identified (logged-in) if he had a Batch `custom_user_id` set on the local storage.
* Its natives (language/region) and customs data will be automatically migrate to a Profile if your app is attached to a Project.

You may want to disable these migrations, to do so please update your Batch's SDK setup as following:

```js

batchSDK('setup', {
  ...,
  // Optional - migrations related configuration.
  migrations: {
  
    // Optional - Specific SDK v4 migrations
    v4: {
  
      // Whether Batch should automatically identify logged-in user when running the SDK for the first time.
      // This mean user with a custom_user_id will be automatically attached a to a Profile  and can be targeted within a Project scope.
      // Optional - default: true
      customID: false,
  
      // Whether Batch should automatically attach current installation's data (language/region/customDataAttributes...)
      // to the User's Profile when running the SDK for the first time.
      // Optional - default: true
      customData: false,
    }
  }
});

```

#### Event data

Batch Web SDK v4 introduced two new types of attribute that can be attached to an event : **Array** and **Object**.

We also took the liberty of updating the tracking event method.

What's change:

* Optional `tag` attribute is no longer available and has been replaced by `$tags` as reserved key under the `attributes` object.
* Optional `label` attribute is no longer available and has been replaced by `$label` as reserved key under the `attributes` object.

{% hint style="info" %}
Limits are unchanged and still 200 chars max for $label and 10 items max for $tags .
{% endhint %}

So if you were previously doing something like:

```js
batchSDK(api => {
  api.trackEvent("add_to_cart", {
    label: "accessories",
    tags: ["winter-sale", "woman"],
    attributes: {
      sub_category: "bags", 
      product_page_url: new URL("https://batch.com/product-page"),
      end_of_sale_date: new Date("2022-02-08T15:00:00Z"),
    },
  });
})
```

You should now do:

```js
batchSDK(api => {
  api.trackEvent("add_to_cart", {
    attributes: {
      sub_category: "bags", 
      product_page_url: new URL("https://batch.com/product-page"),
      end_of_sale_date: new Date("2022-02-08T15:00:00Z"),
      $label: "accessories",
      $tags: ["winter-sale", "woman"],
    },
  });
})
```

For more information, please visit our [custom event guide](/developer/sdk/web/profile-data/events.md).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://doc.batch.com/developer/sdk/web/advanced/3x-migration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
