npm package: @loophq/onstore-sdk
Description: An SDK for integrating with loop returns on-store api
Author: Jesse Breneman
Latest version: 1.5.14

# Loop Onstore SDK

An SDK for easily getting started with the Loop Returns onstore API.

## Installing

### Add via CDN

The easiest way to get started is to link it into your page via CDN and then use the global variable exposed to use the library.

```
<script src="https://cdn.jsdelivr.net/npm/@loophq/onstore-sdk@latest/dist/loop-onstore-sdk.min.js"></script>
<script>
    LoopOnstore.init();
</script>
```

### Module builds

If you have a build process in place you can install via npm or yarn and import and use it as you need.

```
npm i @loophq/onstore-sdk
```

```
import { init } from '@loophq/onstore-sdk';

init();
```

## Examples

```
<script src="https://unpkg.com/@loophq/onstore-sdk@latest/dist/loop-onstore-sdk.js"></script>
<script>
    LoopOnstore.init({
        key: '1234567890',
        attach: '#checkout-button'
    });
</script>
...
<!-- sidecart -->
<button id="checkout-button">Check out</button>
```

There's a single method that must be called for Loop Onstore to work correctly. You must run `init()` on any page you want this to be active on. We generally suggest putting this just above the `</body>` tag in your `theme.liquid` file.

You'll need to pass in an options object that contains several things--an API key with the cart scope enabled, and any elements you want to attach to. An API key can be gotten by contacting support, and you'll need to find a selector for any checkout buttons you have, either on the cart page or in your sidecart if you use one.

## Styling

Loop Onstore SDK injects a bar with the amount of credit available and a return to Loop Returns button. Default styling is applied, but you can further customize it with CSS as you see fit. To easily style it in browser, you can run `LoopOnstore.testMode()` in your browser console to see what elements we inject into the DOM, and style accordingly. If you just want to customize colors, you can just set these CSS custom properties and the changes will cascade through:

```
.loop-onstore {
    --loop-primary-color: black;
    --loop-text-color: white;
    --loop-button-background: white;
    --loop-button-text: black;
}
```

You may also want to hide certain elements when a user is in the on-store flow. We also add the `.loop-returns-activated` class to the body of your page when on-store is active. You can use this to hide or adjust elements as you see fit. Some elements we recommend looking at are:

### Alternative payments or home try-on

Your store may offer alternative payment options, instead of using Shopify checkout. Because these are not available on Loop On-Store, all alternative payment methods should be hidden. Common alternative payment methods include AfterPay, Google Pay & Paypal. These buttons typically appear on Side Carts and Cart pages. Similarly, if there are buttons for a Home Try-On program, those should also be removed.

### Help chat widgets

It's not uncommon for your store to have a help chat widget at the bottom of their site. This will collide with the Loop On-Store credit indicator and should be adjusted when in the On-Store experience. You should use CSS to move the chat button up when in the returns experience to accommodate for the Loop on-store credit indicator.

### Mobile checkout

Mobile bottom-bar add-to-cart buttons can cause trouble for the Loop On-Store experience and should be accounted for. An easy solution for this problem is using the `.loop-returns-activated` class and either move the elements around or simply adding `display: none;` to the items you don't want to show up.

### Popups and light boxes offering discount codes and special offers

It’s a common paradigm now for Shops to show special offers through a pop up modal when a customer enters their site. Anything deviated from a customer adding product to there caught is distracting for returning customers, especially since these discounts will not apply to items bought using the Loop On-Store Experience. It is recommended that these be hidden.

## API

Loop Onstore SDK exposes methods you can use to easily integrate with the Loop onstore API. If you're using the CDN link, you'll access these using the global variable `LoopOnstore`. If you're installing via package manager you can import the methods individually to use.

### init(options: object)

Initializes the Loop onstore. You'll want to run this on every page load.

```
LoopOnstore.init({
    key: '1234567890',
    attach: '.checkout-button'
});
```

Also dispatches the event `Loop:Cart Updated` on the document. This can be used for sidecarts to listen to and update if they don't automatically.

Example:
```
document.addEventListener('Loop:Cart Update', function (e) {
    console.log('The Cart has finished updating!')
}, false);
```

#### options

Type: `object`

##### key

Type: `string`

Required. This is your API key. You'll want to make sure that it has the cart scope.

##### attach

Type: `string`

Required. This is a selector for any elements you want to attach to. The SDK uses `document.querySelectorAll()` under the hood and will attach to any elements that it finds. Generally we recommend that you attach to your checkout button, either on your cart page or in your sidecart if you use one of those instead.

### isActive

Returns true if the on-store is active.

```
if (LoopOnstore.isActive()) {
    // Do stuff
}
```

### submit(variants?: array)

```
LoopOnstore.submit(); // Pulls the Shopify cart
LoopOnstore.submit([1234567890, 0987654321]); // Set the Loop cart to these variants
```

Sync a list of variants to the Loop onstore API. If you pass in an array of variant ids, it will use that, otherwise it queries Shopify for the current cart and uses that to create a Loop cart. Once a Loop cart has been created, you'll be sent back to the Loop Returns app.

#### variants

Type: `array`

Not required, if not set we query the Shopify cart directly. This should be an array of variant ids. The on-store API does not accept a quantity, so if you need more than one of the same variant, you'll need to add it to the array twice.

### backToLoop(token?: string)

```
LoopOnstore.backToLoop(); // Sends you back without saving the user's cart.
LoopOnstore.backToLoop('2e99758548972a8e8822ad47fa1017ff72f06f3ff6a016851f45c398732bc50c'); // Sends you back to loop with this cart.
```

Sends you back to Loop. You _must_ set the token you get from the Loop Onstore API when calling this if you want your user to have their cart when they return. The `submit()` method calls this automatically so generally you don't need to call this yourself.

#### token

Type: `string`

Not required. Calling with a token sends you back with that cart, otherwise you get sent back without making changes to the users cart.

### testMode()

This will send you into the onstore experience with fake data. You'll want to walk through the entire flow to make sure it works properly, but this is nice for testing that all of the functionality is attaching properly, and for styling the bar that we generate.

### debug()

Toggle debug messages on and off, which will log to the console what's happening. Running the testMode method will enable this automatically. You should enable this if you're setting up an on-store integration or if something doesn't seem like it's working right.

### setKey(key: string)

Sets your Loop onstore api key. This is required to communicate with the Loop Onstore API. Generally you'll want to do this via the `init()` method instead of directly here.

#### key

Type: `string`

Required. This is your API key. You'll want to make sure that it has the cart scope.

### attach(selector: string)

Pass this a css selector for your checkout button and the SDK will call the submit method automatically when a user is in the onstore flow. See examples to see how this works. Generally you'll want to do this via the `init()` method instead of directly here.

#### selector

Type: `string`

Required. This is a selector for any elements you want to attach to. The SDK uses `document.querySelectorAll()` under the hood and will attach to any elements that it finds. Generally we recommend that you attach to your checkout button, either on your cart page or in your sidecart if you use one of those instead.

## Events

In addition to the API, we also fire events at certain points in the flow. These events are fired on the document, meaning you can hook into them by adding an event listener to the document like so: `document.addEventListener('Loop:Activated', () => {});`.

### Activated

**Event:** `Loop:Activated`

This fires as we're activating the on-store experience. Note that this will only fire if the user is coming from the Loop app or is already in an on-store experience. You will not see this fire for normal users, only if on-store is active.

#### Example
```
document.addEventListener('Loop:Activated', () => {});
```

### Cart Update

**Event:** `Loop:Cart Update`

This fires every time we update the Shopify cart.

#### Example
```
document.addEventListener('Loop:Cart Update', () => {});
```

### Back To Loop

**Event:** `Loop:Back To Loop`

This fires directly before the user gets redirected back to the Loop app.

#### Example
```
document.addEventListener('Loop:Back To Loop', () => {});
```

## Versioning

We use [SemVer](http://semver.org/) for versioning.

## Development

Run `npm i` to install dependencies.

### Developing locally
To develop locally, run `npm run dev`. This will spin up a webpack dev server with everything you need to get going.

### Building the library

Run `npm run build` and the library will be built in production mode in `/dist`.

## License

This project is licensed under the MIT License.

## Releasing

0. If this is your first time releasing, ask in the engineering team channel to be added to the loop npm organization. Make sure you log in to npm in your terminal as well.
1. On your machine, check out the branch you'd like to release. This can either be a feature branch or a release branch if you have multiple features to package together as a release. This branch should be PRed into `main` and be approved by a peer before releasing.
2. Compile the sdk
    ```
    npm run build
    ```

3. Figure out the version number this release will be. We follow [SemVer](https://semver.org/). Since this project is in maintenance, releases will generally be small enough to be patches vs minor versions.
4. Bump the version and publish the library to npm. **Make sure you are on the branch you intend to release, this will modify your `package.json` and you MUST be on a non-`master` branch for this to be mergeable.**
5. Once you identify the proper version you want, you will run the command to bump that version.  The current version can be found in the `package.json` file
    1. EX: If I want to publish version 1.2.3 I would run `npm version 1.2.3`
    2. NOTE: The loop-shopify-app and on-store SDK versions WILL be different and that is ok! They are two separate apps
6. Once you bumped the version, you can now publish the package, with or without a tag
    1. If I wanted to create a beta tag for my version, I would run `npm publish --tag beta`
    2. If I DID NOT want to add a tag, I would simply run `npm publish`
    3. **NOTE: If you have trouble navigating to npm through the command line, sign into NPM on its own and then try to publish again: [npm site](https://www.npmjs.com/)**
7. **[SITUATIONAL]** If you are using a tag, like latest or beta, you will also want to complete the step of cache purging
    1. Visit [this website](https://www.jsdelivr.com/tools/purge)
    2. Purge the specific tagged version by putting it into the text box.
    3. EX: If I wanted to purge the beta version of my package it would look like this:
    `https://cdn.jsdelivr.net/npm/@loophq/onstore-sdk@beta/dist/loop-onstore-sdk.min.js`
8. Push all changes to Gitlab.
9. In Gitlab, once you have the needed approvals, merge the release branch into master.