# ShipScout documentation

Guides, references, and FAQ for installing and configuring ShipScout.

ShipScout is a Shopify app for running shipping experiments. Merchants define variants — each with its own combination of shipping rates, free-shipping thresholds, and customer-facing copy — and ShipScout serves the right variant to each visitor at checkout so the merchant can measure which configuration drives the most revenue.

Visitors are assigned to a variant deterministically, so the same visitor sees the same variant across visits. Experiment participation is gated by a rollout percentage and an optional targeting tree based on URL parameters or visitor country. Merchants who already run their own experimentation platform can opt out of ShipScout's assignment and pass in their own variant choices instead — see [Bring your own targeting platform](/tasks/bring-your-own-targeting-platform) below.

ShipScout's rates appear at Shopify checkout alongside any other configured rates. Because they're served from a registered carrier service named "ShipScout", they're visible to Shopify Delivery Customization Functions through the standard `source` field on shipping rates. When an order is placed, ShipScout records which variant the customer saw and how much they actually paid for shipping, so per-variant conversion and shipping revenue can be compared in the dashboard.

To keep the rest of your storefront consistent with the variant a visitor is in, ShipScout ships a configurable shipping banner — with templated copy for threshold-based, flat-rate, and always-free shipping scenarios — and a JavaScript SDK (`window.shipscout`) that exposes the assigned variant and threshold details to your theme. Use these to keep product pages, cart drawers, and FAQ pages in sync with what the visitor will see at checkout.

For anything not covered in these pages, email <support@shipscout.app>.

## In this section

{% content-ref url="/pages/-MBeAfhMvsyJprmhb-i8" %}
[Frequently asked questions](/frequently-asked-questions)
{% endcontent-ref %}

## Guides

{% content-ref url="/pages/-MM1ZQwij\_c0Vv-75FYS" %}
[Shipping banner configuration](/tasks/top-bar-integration)
{% endcontent-ref %}

{% content-ref url="/pages/-MBe7CbPucGp8VpLvb6q" %}
[Theme customizations using ShipScout data](/tasks/theme-customizations)
{% endcontent-ref %}

{% content-ref url="/pages/4Zv9uhl4HWEdRIb3Ppba" %}
[Bring your own targeting platform](/tasks/bring-your-own-targeting-platform)
{% endcontent-ref %}

{% content-ref url="/pages/-MDlirSp7pzoOb3veyIX" %}
[Add ShipScout to a shipping zone](/tasks/add-shipscout-to-shipping-zones)
{% endcontent-ref %}

{% content-ref url="/pages/EHo6roC1GsnRRpQTcXph" %}
[Headless stores](/tasks/headless-stores)
{% endcontent-ref %}

{% content-ref url="/pages/e4a24pF4fU6UKpixLdeM" %}
[Recharge (Shopify Checkout)](/tasks/recharge-shopify-checkout)
{% endcontent-ref %}


# Frequently asked questions

## Is ShipScout compatible with my Shopify theme?

ShipScout should work with every Shopify theme. If you are seeing an issue with your theme please contact us at <support@shipscout.app> and we will help you out.

## Can I restrict which destinations I offer ShipScout shipping rates in?

Yes, when you set up the test in ShipScout select the appropriate zones and that test's rates will only be offered to shipping destinations in those countries/provinces. If you modify a Shipping Zone in Shopify it will not change the destinations of any already-created ShipScout tests.

## Can I restrict which products get offered ShipScout rates?

No, not currently.

## How can I show a top bar advertising the shipping promotion to a visitor?

In the ShipScout dashboard you can configure a shipping banner without writing any code. Each variant carries its own static banner text, and you can scope where the banner appears by visitor country directly from the banner editor.

You can also use the Javascript SDK to display the assigned variant's data on your storefront — useful when you need a custom widget instead of (or in addition to) the built-in banner.

## Can I continue to offer some other shipping rates (e.g. Expedited Shipping) along with the ShipScout rates?

Yes. Just leave those other rates enabled and they will appear alongside the ShipScout rate.

## Is ShipScout compatible with Shopify checkout apps?

It should be, yes. ShipScout uses Shopify's CarrierService API to provide shipping rates

## I am seeing some strange "\_sc" text on my cart page and other places on my website

Most themes should hide hidden line item properties that start with an underscore. But if you see it you will need to modify your cart.liquid or cart-template.liquid (or any other file) to include a check for hidden line item properties.

Example liquid:

```javascript
{%- for p in properties -%}
  {%- unless p.last == blank or p.last-%}
    {{ p.first }}:{{ p.last }}
  {%- endunless -%}
{%- endfor -%}
```

Change it to check for hidden properties:

```javascript
{%- for p in properties -%}
  {%- unless p.last == blank or p.first == "_sc" -%}
    {{ p.first }}:{{ p.last }}
  {%- endunless -%}
{%- endfor -%}
```

## Is ShipScout compatible with other Shopify shipping apps?

ShipScout will not modify shipping rates provided by other Shopify shipping apps. This means if you have another app providing shipping rates they will appear alongside the ShipScout shipping rates. This will likely confuse customers so we recommend disabling other shipping rates while running a ShipScout test. However, there are cases where you might want to keep these other rates active, like if one of them is an "Expedited Shipping" rate or you are also offering UPS rate-shopped rates and you'd like all of these paid options to appear alongside the ShipScout rates.

## If I don't have any tests live will ShipScout still show customers a shipping rate?

Yes, it can if you enable the Default Shipping Rate in ShipScout.

## Will the same customer see a different ShipScout shipping rate when they re-visit the website?

Every visitor's browser is tracking their variant using Cookies and as long as they are on the same device & browser they will see the same shipping rate for the entire lifetime of a ShipScout test. If somebody visits on their phone and then on their laptop they can be placed in different variants. However, if a visitor returns to the website via and abandoned cart email link on a different device or browser, they will see the same shipping rate they originally saw since the variant has been stored in the cart attributes.

## Why are customers getting free shipping even though they aren't spending enough to meet the free shipping threshold?

This is most likely because of discount codes. By way of example: You set free shipping for orders $50 and above. A customer completes checkout on a $44 order and gets free shipping. The threshold is calculated \*before\* discounts are applied so if the customer had a $55 order they qualified for free shipping even if though they applied a 20% discount code at checkout bringing their total down to $44.

This is not always ideal even though it averages out and still creates accurate test results. The reason for this behavior is that Shopify does not pass shipping apps like ShipScout any details on the discounts applied.

## Does ShipScout use discount codes to provide different shipping rates?

No.

This is important because Shopify only allows the use of 1 discount code at a time so if we used discount codes then your visitors would not be able to use any other discount code.

## How can I preview my top banner integration?

If you'd like to test the top banner & Javascript API implementation you can append this URL parameter to any URL on your website: `?shipscout_preview=yes`

Then, as long as ShipScout is installed, it will display a preview banner. You do not need to have a test live for this to work.

It will also return the following preview parameters in the "response" callback documented in [Theme customizations using ShipScout data](/tasks/theme-customizations). This makes it possible to do a full test of the banner and also test any custom theme integration with the JS API before you go live.

```javascript
{
  experimentId: 0,
  variant: 'A',
  isAssignmentManagedExternally: false,
  threshold: true,
  thresholdValue: 0,
  thresholdValueUnit: 'cents',
  thresholdMetRateAmountCents: 500,
  shippingPriceCents: 500,
  dynamicShipping: false,
  isNewAssignment: true
}
```

## How can I run ShipScout on a subdomain?

If you have Shopify primary store at `https://shop.mystore.com` and a marketing site at `https://mystore.com` and you'd like to have ShipScout run on both you need to include some additional code.

Include the following code snippet in your Shopify store's `theme.liquid` just **before** `{{ content_for_header }}`

```javascript
<script>
window._shipScout = window._shipScout || [];
_shipScout.cookieDomain = 'mystore.com';
/* 
Replace mystore.com with the top level domain of your shopify store 
but do not include any subdomain or leading dot
*/
</script>
```

Add the following snippet on your marketing site. We recommend placing it just before the closing `</head>` tag.

```javascript
<script>
//Include in theme.liquid before {{ content_for_header }}

window._shipScout = window._shipScout || [];
window.Shopify = window.Shopify || {};

Shopify.shop = 'mystore.myshopify.com';
/* 
Replace mystore.mystore.com with the Shopify domain (should always include
".myshopify.com") excluding https:// 
*/

_shipScout.cookieDomain = 'mystore.com';
/*
Replace mystore.com with your domain but do not include
a leading dot or the subdomain
*/
</script>
<script async src="https://web.shipscout.app/app.min.js"></script>
```

## How can I test my existing shipping rates (without a free shipping threshold) against the same rates with a free shipping threshold?

For example:

* **Control**: Current shipping rates, no free-shipping threshold
* **Variant 1**: Current shipping rates plus free shipping over $60

In ShipScout, leave the Control variant alone (Control visitors see your existing rates exactly as they are today) and add a **Free shipping** rate to Variant 1 with a "When cart subtotal is at least $60" condition:

![Variants section of the experiment editor showing the default Control variant and a Variant 1 carrying a "Free shipping" rate that applies when cart subtotal is at or above $60.](https://868424754-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBe743z7FL4vw9wddyQ%2Fuploads%2Fgit-blob-ca974c583a159701e8f4f84a9b5fc19ee80df79d%2Ffaq-threshold-vs-no-threshold.png?alt=media)

## How can I avoid the brief layout flicker as the top banner appears?

It takes a second for the ShipScout script to load (since we don't want it to block the loading of anything else on your page) and you will notice that the appearance of top banner is slightly delayed. You can fix this by adding this element to the area you'd like the shipping banner to appear:

`<div class="shipscout-placeholder" style="min-height: 36px; background: red;"></div>`

That example will show an empty red shipping banner with a height of 36px until the ShipScout banner gets placed inside that element.

## How can I load ShipScout faster?

ShipScout will load asynchronously on your store so that it doesn't block any other assets. This is the recommended practice from Shopify. If you'd like to have ShipScout load synchronously and sooner then you can add this code just before the closing \</head> tag. It's important that it comes **after** the {{ content\_for\_header }} liquid code.

```javascript
<!-- Start ShipScout Code -->
<script src="https://web.shipscout.app/app.min.js"></script>
<!-- End ShipScout Code -->

</head>
```

## Is ShipScout compatible with Recharge?

**Recharge with Shopify Checkout**

If you are on the newer Shopify Checkout version of Recharge everything will work as expected.

**Recharge with legacy Recharge Checkout**

If you are on the legacy Recharge though your customers will be excluded from the *Orders* and *Checkout* data in ShipScout test results.

First, determine which version Recharge checkout is in use: <https://support.rechargepayments.com/hc/en-us/articles/360008681834-Identifying-which-checkout-is-in-use>

Here's what you can expect depending on your version of Recharge:

* **Shopify Checkout Integration**

  Your customers will pass through the Shopify checkout. First time subscription orders will be placed in a ShipScout variant and will receive the relevant shipping rate. Subscription renewal orders will not be included in your test results.
* **Recharge Checkout on Shopify (legacy Recharge, before Nov 2nd, 2020)**

  These customer will have their *Visit* and *Add to Cart* events tracked in your test results.

  In the Recharge dashboard if you have the Shipping Setup set to "Get all rates from Shopify" then the customer will see the Variant A shipping rate of the current test as a fallback rate. They won't be included in the test results though.

  In the Recharge dashboard if you have the Shipping Setup set to "Use Recharge zones, rates and integrations" then the customer will not see any ShipScout shipping rates and will also not be included in the test results.

  All Recharge customers will be excluded from *Checkout* and *Order* events.

## My Shopify theme does not add line item properties when adding items to the cart, what can I do?

In order to have the proper rates appear at checkout your cart's line items need a special ShipScout line item property.

We try to insert an input field on the product page to make sure that the necessary hidden line item property is set when adding to cart. Even if it's not we check for a subsequent /cart.js call and analyze that to see if the properties are still missing.

Some themes, however, don't have a product page form and also won't call /cart.js after adding an item to the cart. In this case you will need to explicitly set the line item property when calling the /add.js endpoint.

Locate the code in your theme that's adding to cart. It may look something like this:

```
jQuery.post('/cart/add.js', {
  items: [
    {
      quantity: 1,
      id: 35286064136352
    }
  ]
});
```

You will then want to introduce the ShipScout line item property like this:

```
jQuery.post('/cart/add.js', {
  items: [
    {
      quantity: 1,
      id: 35286064136352,
      properties: (typeof window.ShipScoutLineItemProperty !== 'undefined' ? { "_sc": window.ShipScoutLineItemProperty } : null)
    }
  ]
});
```

## How can I force a visitor into a specific variant?

You can force visitors to receive the shipping rates of a specific variant by including an `ss` URL parameter. For example, any visitors arriving to your website with the following URL will be receive the shipping rates as if they were in variant B:

`https://myshopname.com?ss=B`

If you have other URL parameters already you can include it like this:

`https://myshopname.com?other_param=test&ss=B`

For variant A you'd simply use this URL:

`https://myshopname.com?ss=A`

It's important to note that, even though this visitor will see the shipping rates from a particular variant they will \*not\* be included in any of the ShipScout data for that test (visitor, add to cart, checkout, order counts). This is because, for a test to be valid, each visitor must be randomly placed in a variant, not forced into one.


# Shipping banner configuration

Using ShipScout, you can add a shipping banner to your website. Each variant in your test can carry its own static banner text, and you can scope where the banner appears by visitor country.

### Layout and placement

There are two out-of-the-box layouts for the shipping banner: floating widget and top bar. We recommend the floating widget — it works in every theme. The top bar layout works in most themes, but for a few themes ShipScout cannot determine where to place it.

You can opt into the top bar layout in any theme by adding the following placeholder where you'd like the banner to appear:

```
<div class="shipscout-placeholder"></div>
```

{% hint style="info" %}
You can add as many placeholder elements as you need; we'll replace them all with the banner.
{% endhint %}

### The banner text

Every variant carries a single banner text. Whatever you write is what the visitor sees — there's no template language and no rate-state-driven message switching.

Each variant in your test can have its own banner text, so the banner is part of the treatment you're A/B testing. The shop-level banner text is the fallback shown when no test is running.

### Country targeting

You can restrict the banner to specific countries directly from the banner editor. Pick the countries the banner should show in, and visitors outside that list will not see it. Leave the country list empty to show the banner globally.

This applies both during a live test (per-variant country list) and to the shop-level banner shown outside a live test. The visitor's country is determined from their IP address.

{% hint style="info" %}
Country targeting only affects banner display. The shipping rates themselves are scoped by your Shopify shipping zones — country targeting on the banner doesn't change which destinations qualify for ShipScout rates.
{% endhint %}


# Theme customizations using ShipScout data

The definitive guide to updating shipping related copy and UI throughout your shop

### Introduction

As you design your test, it's critical that you update the places in your shop that mention your shipping rate. Here's a list of places that merchants typically show shipping rate information:

* Top announcement banner
* Upsell modal
* Product detail page
* Cart and cart drawer
* Shipping policy page
* FAQ

Depending on the implementation of the copy or UI element, your approach to update it may differ. We offer two different ways to update your theme. Our goal is make it as easy as possible for you to make sure your customers see the right shipping information.

{% hint style="info" %}
Please give us feedback at <support@shipscout.app> on how we can improve our developer SDK.
{% endhint %}

### Using Javascript (Recommended approach)

If the area you're trying to update cannot be updated via liquid because it is rendered via javascript or by a different app, you can use our Javascript API to drive it.

Include the following JavaScript wherever you'd like (we recommend somewhere before the closing \</head> tag). It will execute as soon as ShipScout has loaded and will inform you on which test the current user is in.

```javascript
<script>
window._shipScout = window._shipScout || [];
_shipScout.push(function (response) {

    /*
        example response object
        {
            experimentId: 1,
            variant: 'B',
            isAssignmentManagedExternally: false,
            threshold: true,
            thresholdType: 'pricing',
            thresholdValue: 5000,
            thresholdValueUnit: 'cents',
            thresholdMetRateAmountCents: 0,
            shippingPriceCents: 1000,
            dynamicShipping: false,
            lineItemProperty: '0467e6f7-8d66-4610-a939-da76dd9f7a68_1_B',
            isNewAssignment: false
        }
    */
    
    //apply any exchange rates to currency if necessary
    var thresholdCents = (window.Shopify && Shopify.currency && Shopify.currency.rate) ? response.thresholdValue * Shopify.currency.rate : response.thresholdValue;
    var flatrateCents = (window.Shopify && Shopify.currency && Shopify.currency.rate) ? response.shippingPriceCents * Shopify.currency.rate : response.shippingPriceCents;

    
    //format currency
    var currencyFormat = ShipScoutGetCurrency();
    
    //get threshold amount with currency symbol
    var thresholdAmount = ShipScoutFormatMoney(thresholdCents, currencyFormat);

    //get flat rate amount with currency symbol
    var flatrateAmount = ShipScoutFormatMoney(flatrateCents, currencyFormat);

    //==== insert your code below to dynamically update elements ====//

    //example updating an element on the page dynamically with the threshold amount
    var el = document.getElementById("foo-bar");
    
    if(response.thresholdValue === 0) {
        el.innerHTML = "FREE!";
    } else {
        el.innerHTML = thresholdAmount;
    }
    
});
</script>
```

Here's a description of the properties and values to expect in the response object.

<table data-header-hidden><thead><tr><th width="292">Property</th><th>Value Type</th><th>Example</th><th>Description</th></tr></thead><tbody><tr><td>Property</td><td>Value Type</td><td>Example</td><td>Description</td></tr><tr><td>experimentId</td><td>integer</td><td>1</td><td>The experiment ID. <code>0</code> when previewing.</td></tr><tr><td>variant</td><td>string | undefined</td><td>A</td><td>The variant this visitor is assigned to. Undefined if no live experiment applies.</td></tr><tr><td>isAssignmentManagedExternally</td><td>boolean</td><td>false</td><td>True if your own targeting platform is responsible for assigning the variant. See <a href="/tasks/bring-your-own-targeting-platform">Bring your own targeting platform</a>.</td></tr><tr><td>threshold</td><td>boolean</td><td>true</td><td>True if there's a free shipping<br>threshold for this visitor.</td></tr><tr><td>thresholdType</td><td>string | undefined</td><td>pricing</td><td>Either <code>"pricing"</code> (threshold based on cart subtotal) or <code>"items"</code> (threshold based on item count). Only present if <code>threshold</code> is true.</td></tr><tr><td>thresholdValue</td><td>integer | undefined</td><td>5000</td><td>Only present if <code>threshold</code> is true.<br><br>The amount required to unlock the threshold rate, in the unit given by <code>thresholdValueUnit</code>.</td></tr><tr><td>thresholdValueUnit</td><td>string | undefined</td><td>cents</td><td>The unit <code>thresholdValue</code> is measured in (e.g. <code>"cents"</code> or <code>"items"</code>).</td></tr><tr><td>thresholdMetRateAmountCents</td><td>integer | undefined</td><td>0</td><td>Only present if <code>threshold</code> is true.<br><br>The shipping price, in cents, once the threshold amount is met.</td></tr><tr><td>shippingPriceCents</td><td>integer</td><td>1000</td><td>The shipping price, in cents, before any threshold is met.</td></tr><tr><td>dynamicShipping</td><td>boolean</td><td>false</td><td>True if the shipping price is calculated dynamically at checkout (e.g. carrier-calculated rates) rather than being a fixed value.</td></tr><tr><td>lineItemProperty</td><td>string | undefined</td><td>0467e6f7-8d66-4610-a939-da76dd9f7a68_1_B</td><td>The cart attribute value that should be attached to line items so ShipScout can attribute the conversion. Set automatically on themed stores; headless stores must set it manually.</td></tr><tr><td>isNewAssignment</td><td>boolean</td><td>true</td><td>True if the ShipScout response data changed during this page load. Useful for optimizing expensive effects.</td></tr></tbody></table>

If there's no live experiment but you do have a Default Shipping Rate set in ShipScout, the rate settings will still be returned by the JS SDK. `experimentId` will be `0` and `variant` will be undefined in that case.

{% tabs %}
{% tab title="Testing the SDK without a live test" %}
You can append ?shipscout\_preview=yes to any URL on your website to test your SDK integration without a live test. Appending this URL will simulate these hard-coded values for the SDK:

```javascript
{
  experimentId: 0,
  variant: 'A',
  isAssignmentManagedExternally: false,
  threshold: true,
  thresholdValue: 0,
  thresholdValueUnit: 'cents',
  thresholdMetRateAmountCents: 500,
  shippingPriceCents: 500,
  dynamicShipping: false,
  isNewAssignment: true
}
```

If you need to overwrite these hard-coded preview values to simulate a different setup or variant you can do that like this:

```javascript
window._shipScout = window._shipScout || [];
_shipScout.push(function (response) {

   //Temporarily overwrite the response for testing
   response = {
      ...response,
      thresholdValue: 5000,
      variant: 'B',
   }

})
```

{% endtab %}
{% endtabs %}

### Using liquid

If your copy and/or variables are primarily set in your theme, this is the best method for updating it.

**Step 1 - update the places that refer to the shipping threshold value**

In liquid, you can access the shipping rate threshold value from the cart object in liquid. This value will be updated to reflect the correct thresholdValue for the given user.

Here's a example code snippet that checks for the shipscout threshold value and has a default value in case that is not set. This pattern is great to ensure that uninstalling ShipScout doesn't impact the shop.

```liquid
{%- if cart.attributes._sc_threshold_min_value %}
  {%- assign threshold_in_cents = cart.attributes._sc_threshold_min_value -%}
{%- else -%}
  {%- assign threshold_in_cents = SOMETHING_ELSE -%}
{%- endif -%}
```

**Step 2 - Dynamically re-render sections using this variable after the variant data changes**

When a customer visits your store for the first time, ShipScout will assign a variant to the customer after the page loads via javascript. This happens after the liquid page gets rendered. Since on this first page load, the liquid page was rendered based on no variant, the threshold value won't necessarily match the variant threshold value.

To dynamically render sections, add this code to the \<head /> of your shop:

<pre class="language-html"><code class="lang-html"><strong>&#x3C;script>
</strong>  window._shipScout = window._shipScout || [];
  _shipScout.push(async function (response) {
      // Only update section if assignment data is new
      if (response.isNewAssignment) {
          // Update header using shopify Section API
          const announcementBarID = "announcement_bar_section_id";
          let announcementBarHTML = await (await fetch(`?section_id=${announcementBarID}`)).text();
          document.getElementById('announcement-bar').innerHTML = announcementBarHTML;

          // Update cart using shopify Section API
          const cartID = "cart"
          let header = await (await fetch(`?cart=${cartID}`)).text()
          document.getElementById('cart').innerHTML = header

          // ...etc
      }
  });
&#x3C;/script>
</code></pre>


# Bring your own targeting platform

You can use your own targeting/experimentation platform to determine which test variant your visitors should be in. This guide will walk you through setting this up.

{% hint style="warning" %}
Requires engineering work
{% endhint %}

### Why would I want this?

Many of our merchants use a generalized A/B test platform for non-shipping rate experiments. This feature allows you to utilize the power of ShipScout's shipping rate configurability with your own existing targeting tool.

### Step 1 - Set up your test

Create a ShipScout test as you normally would. BYOTP is available to all types of tests: threshold, flat rate and custom.

### Step 2 - Enable "Use your own targeting platform"

In the **Audience** section, expand the **External assignment** row and enable "Use your own targeting platform".

<figure><img src="https://868424754-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBe743z7FL4vw9wddyQ%2Fuploads%2Fgit-blob-84dbe6babab91a0f84fae53798e806c844e4bad5%2Fbyotp-toggle.png?alt=media" alt="The Audience section of the experiment editor with the &#x27;External assignment&#x27; disclosure row expanded, showing the unchecked &#x27;Use your own targeting platform (disables ShipScout)&#x27; checkbox."><figcaption></figcaption></figure>

### Step 3 - Integrate your platform

Use the ShipScout javascript SDK to assign a variant to your visitors. For theme based shops, no pre-setup is necessary. For headless shops, you'll need to install the javascript SDK by following this guide: [Headless stores](/tasks/headless-stores).

Here's an example of assigning variant A to all visitors:

<pre class="language-javascript"><code class="lang-javascript">// Init ShipScout - this must run before you assign the variant
!function(s) { s.shipscout = s.shipscout || (e, a) => { s.shipscout._queue?.push({ type: e, ...a }); }; s.shipscout._queue = s.shipscout._queue || [];}(window)

<strong>// Assign the variant
</strong>window.shipscout("assign", {
  variantKey: "A" // all visitors will be assigned to variant A
});
</code></pre>

Here's a more plausible example that shows how you might get an assignment from a targeting platform and map it to a ShipScout variant

```javascript
// Init ShipScout
!function(s) { s.shipscout = s.shipscout || (e, a) => { s.shipscout._queue?.push({ type: e, ...a }); }; s.shipscout._queue = s.shipscout._queue || [];}(window)

// Get assignment from you experimentation platform
const assignment = ExampleTargtingPlatform.getAssignment();

// Map assignment to ShipScout variants. ShipScout variants are always
//  capital letters starting from A.
let shipScoutAssignment;
if (assignment === "12390424") {
  shipScoutAssignment = "A";
} else if (assignment === "4214900") {
  shipScoutAssignment = "B";
}

// Assign the variant
window.shipscout("assign", {
  variantKey: shipScoutAssignment
});
```

A few things to keep in mind:

* Once a visitor is assigned to a variant, their assignment will persist for the duration of the test.
* Once a test ends, the assignment code will noop so you can clean it up at your leisure. But be sure to clean it up before you start your next experiment.

### Step 4 - Test your changes

In order to test the assignments, you will need to launch your test. Assignments will not work in draft mode.


# Add ShipScout to a shipping zone

Sometimes Shopify won't automatically add ShipScout to all your Shopify shipping zones. Follow these steps to fix this issue.

1\. Click the "edit zone" link in ShipScout

![](https://868424754-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBe743z7FL4vw9wddyQ%2Fuploads%2Fgit-blob-20acbd7cd4766c8d14434f507c9c010b4ee0a907%2Fimage.png?alt=media)

2\. Click "Add Rate" for the zone you are trying to fix:

![](https://868424754-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBe743z7FL4vw9wddyQ%2Fuploads%2Fgit-blob-f79945ec44392c91255dd231ba3ef70c30591f7d%2Fimage.png?alt=media)

3\. Fill out the new Rate popup:

![](https://868424754-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBe743z7FL4vw9wddyQ%2Fuploads%2Fgit-blob-d9001637dc866419d0cdcb27bab9ebcc403d1d24%2Fimage.png?alt=media)

4\. Click "save" in the top bar:

![](https://868424754-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBe743z7FL4vw9wddyQ%2Fuploads%2Fgit-blob-16bc37490209817ab1d810125690447f7cebc64c%2Fimage.png?alt=media)

5\. Back in ShipScout click "refresh zones" and the error should disappear:

![](https://868424754-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBe743z7FL4vw9wddyQ%2Fuploads%2Fgit-blob-73f6322d5a32864ef7893af0feeca98fc1ff59ef%2Fimage.png?alt=media)


# Headless stores

ShipScout can run on headless stores with a little bit of setup.

## Step 1: initialize ShipScout

You will need to configure ShipScout and load the ShipScout SDK. To do so, include the following html/javascript on your site before the closing \</head> tag:

<pre class="language-javascript"><code class="lang-javascript">&#x3C;script>

    window._shipScout = window._shipScout || [];
    window.Shopify = window.Shopify || {};
    
    /* 
    Replace mystore.mystore.com with the Shopify domain (should always include
    ".myshopify.com") excluding https:// 
    */
    Shopify.shop = 'mystore.myshopify.com';

    /*
    Replace mystore.com with your domain but do not include
    a leading dot or the subdomain
    */
<strong>    window.shipScoutCookieDomain = 'mystore.com';
</strong>
&#x3C;/script>
&#x3C;script async src="https://web.shipscout.app/app.min.js">&#x3C;/script>
</code></pre>

Warning: the configuration (the code in the first script tag) must be run before the `app.min.js` is loaded. If the SDK loads before the configuration, ShipScout will not track conversions correctly.

## Step 2: update cart items with ShipScout data

To track conversions, you will need to set a custom ShipScout attribute (sometimes referred to as a line item property) on each and every item that is added to a customer's cart. Set this attribute to `window.ShipScoutLineItemProperty`.

For example, if you are using the graphql api, here is a snippet of

```javascript
// This is an illustration of the customAttributes section of the graphQl query
// If the above cookies exist then pass in those values as a customAttribute

customAttributes: [
   // Any existing custom attributes go here
   //  and add the new ShipScout custom attribute like this:
   {
      key: '_sc',
      value: (typeof window.ShipScoutLineItemProperty !== 'undefined' ? window.ShipScoutLineItemProperty : "")
   }
]
```

## Step 3: track the add to cart event

*Note: if you are using the /cart.js step, you can ignore this step.*

If you're using the GraphQL Storefront API to manage the cart state, you will need to fire the "Add to cart" event by calling `window.ShipScoutTrackAddToCart()`. It is safe to call this function repeatedly on every add to cart; only the initial event will be tracked.

```javascript
// Track the "Add to cart" event
if(typeof window.ShipScoutTrackAddToCart === "function") {
    window.ShipScoutTrackAddToCart()
}
```


# Recharge (Shopify Checkout)

{% hint style="warning" %}
This guide uses Shopify Scripts, which Shopify is deprecating. The same logic can be implemented as a [Shopify Delivery Customization Function](https://shopify.dev/docs/apps/build/checkout/delivery-customizations) — reach out to <support@shipscout.app> for help porting it.
{% endhint %}

### **First time subscription orders**

If your store is on Shopify Checkout first time subscription orders will receive the same shipping rates that non-subscription orders will get. This means that first time subscription orders are subject to the shipping rates of the variant of the visitor.

Stores will often want to offer $0 shipping on all first time subscription orders.

This can be done by creating a "Free Subscription Shipping" shipping rate in Shopify:

![](https://868424754-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBe743z7FL4vw9wddyQ%2Fuploads%2Fgit-blob-9e88cf5f7969941bd2fd9d8b10bc40e5f6999f6e%2Fimage.png?alt=media)

In order to make sure the "Free Subscription Shipping" rate does not appear to non-subscription orders we need to use a Shopify Script to only allow it to be visible on subscription orders. The Shopify Script does not affect recurring orders.

Shopify Shipping Script:

![](https://868424754-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBe743z7FL4vw9wddyQ%2Fuploads%2Fgit-blob-c65691b192cacfe9bf3a704a674bb093ec8a3fdb%2Fimage.png?alt=media)

```ruby
#Show the free subscription rate if the cart contains a subscription item

#Check to see if the cart contains a subscription item
has_subscription = false
Input.cart.line_items.each do |line_item|
  if line_item.selling_plan_id
    has_subscription = true
    break
  end
end

#Show the Free Subscription Shipping rate if the cart contains a subscription item otherwise hide it
Input.shipping_rates.delete_if do |shipping_rate|
  if has_subscription
    if shipping_rate.name == 'Free Subscription Shipping'
      false #show rate
    else
      true #hide rate
    end
  else
    if shipping_rate.name == 'Free Subscription Shipping'
      true #hide rate
    else
      false #show rate
    end
  end
end

Output.shipping_rates = Input.shipping_rates
```

### Recurring subscription orders

The shipping price charged on recurring orders can be set several ways. This depends on which version of Recharge you're on and also if you were migrated at some point from the legacy version.

The first place to check is Recharge > Settings > Shipping Settings:

![](https://868424754-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MBe743z7FL4vw9wddyQ%2Fuploads%2Fgit-blob-3539d72f8991b3f9684d35b841d4006a43420410%2Fimage.png?alt=media)

If you see a screen like this then you can configure the recurring shipping price here. Be careful though, any changes here will affect the shipping price charged for all ongoing renewals.

You can always email us for more help: <support@shipscout.app>


