> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ordergroove.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ordergroove.com/_mcp/server.

# Dynamic Shipping Restrictions in the Subscription Manager

Your site may have certain products that cannot be shipped to certain states. If this is the case, you can change the state choices available when a customer edits their subscription address.

Below is a step-by-step guide to implementing these restrictions. This guide targets restrictions by product ID, but you can use any identifier — for example, `subscription.extra_data`, product groups, order items, etc. See the [Object Reference](/docs/lifecycle/sm/object-reference) for a full list of available targets.

***

## Subscription Manager Version

The implementation of dynamic shipping restrictions depends on your theme version. Choose the method that matches your installed Subscription Manager version.

### How to Tell What Version You're On

Before the September 2024 release of v25, all Subscription Manager installations were on version 0, displayed in the Theme Designer as version 0.X.X. You can check which version you're on by going to [Ordergroove](https://rc3.ordergroove.com/) > Subscription > Subscription Manager.

***

## Current — smi-templates 25.0.0+

Log in to [Ordergroove](https://rc3.ordergroove.com/) and go to **Subscriptions** > **Subscription Manager** > **Advanced**. Make the following changes to your code:

### Views: order-summary/change-shipping-dialog.liquid

Locate `{% set localized_countries = 'localized_countries' | t %}` and add the following line below it. Modify the state codes to match the states you do not ship to:

```liquid
{% set excluded_states = setting('enabled_states_restricted', ['AK', 'HI']) %}
```

Locate the `<sm-country-state-dropdown>` HTML tag and add a new `.excludedStates` property. The full tag should appear as follows:

```liquid
<sm-country-state-dropdown
  .localizedCountries="{{ localized_countries }}"
  .enabledCountries="{{ enabled_countries }}"
  .excludedStates="{{ excluded_states }}"
>
```

### script.js

Locate the `syncCountryAndStates` function inside the `SMCountryStateDropdown` custom element definition. Inside the `states.forEach` loop, add `if (this.excludedStates.includes(code)) return;` before calling the `createOption` function. The updated function should look similar to this (minor updates may have occurred in your version):

```javascript
async syncCountryAndStates(countryValue) {
  const countriesByCode = await countriesDataPromise;
  const selectedCountry = countriesByCode[countryValue];
  const states = selectedCountry ? selectedCountry.regions : null;

  const currentOptions = this.stateSelect.querySelectorAll('option');
  currentOptions.forEach(option => {
    // Clear all options except default blank option
    if (option.value !== '') option.remove();
  });

  if (states && states.length) {
    states.forEach(({ code, name }) => {
      if (this.excludedStates.includes(code)) return; // this is the updated line
      createOption(code, name, this.stateSelect);
    });
  }
}
```

***

## Subscription Manager 0.33.3 – 0.41.1

Log in to [Ordergroove](https://rc3.ordergroove.com/) and go to **Subscriptions** > **Subscription Manager** > **Advanced**. Make the following changes to your code:

### Views: change-shipment-address.liquid

Locate `{% set localized_countries = 'localized_countries' | t %}` and add the following line below it. Modify the state codes to match the states you do not ship to:

```liquid
{% set excluded_states = setting('enabled_states_restricted', ['AK', 'HI']) %}
```

Locate and replace the `<select>` element for state with the following:

```liquid
<select id='state_{{ order.public_id }}' class='og-form-select' name='state_province_code' required data-excluded_states='[{{ 'excluded_states.map(s=> `"${s}"`).join(",")' | js }}]'>
```

### script.js

Locate `const stateSelectElement = ev.target.closest('form').querySelector('[name="state_province_code"]')` and add the following line below it:

```javascript
const excludedStates = JSON.parse(stateSelectElement.dataset.excluded_states || '');
```

Locate `states.forEach(({ code, name }) => {` and add the following line:

```javascript
if (excludedStates.includes(code)) return;
```

***

## Legacy — Subscription Manager 0.33.2 and Earlier

### Step 1: Set All States for the Shipping Dropdown

Set a list of all `localized_states` you want available for non-restricted products and put that in a JSON object in the `en-US.json` file.

### Step 2: Set the Variables

In `change-shipment-address.liquid`, set the full list of enabled states (`enabled_states_all`) and the list of restricted states (`enabled_states_restricted`). These will be the two lists pulled into the select form based on the criteria. Also set the `states` object pointing to the `localized_states` list defined in step 1.

Then set `restricted_products` to `false` and run a `for` loop to iterate over all items in an order and evaluate the product group name or product ID. `restricted_products` becomes `true` if the product or group is found.

```liquid title="Product ID Example"
{% set enabled_states_all = setting('enabled_states_all', ["AK", "AL", "AR", "AS", "AZ", "CA", "CO", "CT", "DC", "DE", "FL", "GA", "GU", "HI", "IA", "ID", "IL", "IN", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN", "MO", "MP", "MS", "MT", "NC", "ND", "NE", "NH", "NJ", "NM", "NV", "NY", "OH", "OK", "OR", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "VA", "VI", "VT", "WA", "WI", "WV", "WY"]) %}
{% set enabled_states_restricted = setting('enabled_states_restricted', ["CO", "CT", "DC", "DE", "FL"]) %}
{% set states = 'localized_states' | t %}
{% set restricted_products = false %}
{% set current_order_items = order_items | select(order=order.public_id) %}
{% for order_item in current_order_items %}
  {% set restricted_products = (restricted_products or (order_item.product == "42328611848362")) %}
{% endfor%}
```

```liquid title="Product Group Name Example"
{% set enabled_states_all = setting('enabled_states_all', ["AK", "AL", "AR", "AS", "AZ", "CA", "CO", "CT", "DC", "DE", "FL", "GA", "GU", "HI", "IA", "ID", "IL", "IN", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN", "MO", "MP", "MS", "MT", "NC", "ND", "NE", "NH", "NJ", "NM", "NV", "NY", "OH", "OK", "OR", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "VA", "VI", "VT", "WA", "WI", "WV", "WY"]) %}
{% set enabled_states_restricted = setting('enabled_states_restricted', ["CO", "CT", "DC", "DE", "FL"]) %}
{% set states = 'localized_states' | t %}
{% set restricted_products = false %}
{% set current_order_items = order_items | select(order=order.public_id) %}
{% for order_item in current_order_items %}
  {% set product = products | find(id=order_item.product) %}
  {% for group in product.groups %}
    {% if group.name === 'restricted' %}
      {% set restricted_products = true %}
    {% endif%}
  {% endfor %}
{% endfor%}
```

### Step 3: Switch State from Input to Select

Replace the state input field with a select dropdown. Use the `restricted_products` flag to determine which list of states to offer:

```liquid
<div class='og-form-group og-col'>
  <label class='og-form-label {{ 'og-required' if 'required_fields.shipping_address.state_province_code' | setting }}' for='state_{{ order.public_id }}'>
    {{ 'form_address_state' | t }}
  </label>
  <select class='og-form-select' name='state_province_code' id='state_{{ order.public_id }}' ?required='{{ 'required_fields.shipping_address.state_province_code' | setting }}'>
    {% if restricted_products %}
      {% for state_province_code in enabled_states_restricted %}
        <option value='{{ state_province_code }}'>{{ states[state_province_code] }}</option>
      {% endfor %}
    {% else %}
      {% for state_province_code in enabled_states_all %}
        <option value='{{ state_province_code }}'>{{ states[state_province_code] }}</option>
      {% endfor %}
    {% endif %}
  </select>
</div>
```

### Step 4: Disable the "Update All" Checkbox

If a customer has products that aren't shippable to certain states, suppress their ability to use the "update for all" feature when changing their address. This prevents other subscriptions and orders from being updated to an unsupported state.

```liquid
<div class='og-input-group'>
  {% if restricted_products %}
    <input type='checkbox' class='og-check-radio' name='use_for_all' id='use_for_all_{{ order.public_id }}' />
    <label class='og-check-radio-label' for='use_for_all_{{ order.public_id }}'>Use for all shipments</label>
  {% else %}
    <input type='checkbox' disabled="disabled" class='og-check-radio' name='use_for_all' id='use_for_all_{{ order.public_id }}' />
    <label class='og-check-radio-label' for='use_for_all_{{ order.public_id }}'>Use for all shipments disabled due to product shipping restrictions</label>
  {% endif %}
</div>
```

**Example Result**