---
title: Target buyers by country instead of market ID
description: >-
  Learn how to update your app from deprecated single-market endpoints to
  country-based targeting, so your app stays resilient when merchants
  reorganize, activate, deactivate, or delete markets.
source_url:
  html: 'https://shopify.dev/docs/apps/build/markets/target-buyers-by-country'
  md: 'https://shopify.dev/docs/apps/build/markets/target-buyers-by-country.md'
---

# Target buyers by country instead of market ID

If your app uses any of the deprecated single-market endpoints listed below, this guide explains why they're deprecated, what can go wrong, and how to switch to country-based matching.

***

## Deprecated single-market endpoints

The deprecated single-market endpoints are market objects with single market identifiers such as `id`, `name`, `handle`, and `regions`. These endpoints only surface country-based markets:

* **Liquid**: [`Localization.market`](https://shopify.dev/docs/api/liquid/objects/localization#localization-market), [`Country.market`](https://shopify.dev/docs/api/liquid/objects/country#country-market).
* **Storefront API**: [`Localization.market`](https://shopify.dev/docs/api/storefront/latest/objects/Localization#field-Localization.fields.market), [`Country.market`](https://shopify.dev/docs/api/storefront/latest/objects/Country#field-Country.fields.market).
* **Shopify Functions input**: [`Localization { market }`](https://shopify.dev/docs/api/functions/latest/delivery-customization#Input.fields.localization.market), [`deliveryAddress { market }`](https://shopify.dev/docs/api/functions/latest/delivery-customization#Input.fields.cart.deliveryGroups.deliveryAddress.market).
* **Checkout UI extensions**: [`shopify.localization.market`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/platform-apis/localization-api#docsstandardlocalizationapi-propertydetail-localization), [`useLocalizationMarket`](https://shopify.dev/docs/api/checkout-ui-extensions/2025-07/target-apis/platform-apis/localization-api#useLocalizationMarket).
* **GraphQL Admin API**: [`Customer.market`](https://shopify.dev/docs/api/admin-graphql/latest/objects/Customer#field-Customer.fields.market), [`CompanyLocation.market`](https://shopify.dev/docs/api/admin-graphql/latest/objects/CompanyLocation#field-CompanyLocation.fields.market), [`MarketWebPresence.market`](https://shopify.dev/docs/api/admin-graphql/latest/objects/MarketWebPresence#field-MarketWebPresence.fields.market).

***

## Why single-market endpoints are deprecated

Before [market inheritance](https://shopify.dev/docs/apps/build/markets/market-inheritance) was introduced, a buyer belonged to exactly one market, so apps could safely use `market.id` or `market.handle` to decide what experience to show (for example, "if the market is North America, show this banner").

Now, merchants can create child markets (for example, a Canada market under North America). A Canadian buyer matches both markets. The deprecated single-market endpoints only return the most specific one (Canada), not the parent (North America).

If an app was configured to target the "North America" market by ID, Canadian buyers stop matching because the API now returns "Canada" instead. And it happens every time a merchant creates a new child market, forcing merchants to reconfigure the app each time.

**TL;DR:** Market IDs are no longer stable identifiers for targeting buyers.

***

## How to target buyers by country

Instead of matching buyers by market ID, you can match them by country code. Your app can still let merchants select from a list of markets in the UI — the difference is that you store the market's country codes instead of its ID. This guide shows you how to query a market's regions, store the country codes, and match buyers against them — so your app stays resilient regardless of how merchants organize their market hierarchy.

***

## Requirements

* Your app uses one or more of the deprecated market endpoints listed above.
* You have access to the [GraphQL Admin API](https://shopify.dev/docs/api/admin-graphql) to query market regions.
* Your app requests the [`read_markets` access scope](https://shopify.dev/docs/api/usage/access-scopes#authenticated-access-scopes).

***

## Step 1: Query market regions

Use [`market.conditions.regionsCondition.regions`](https://shopify.dev/docs/api/admin-graphql/latest/queries/market) to resolve a market's country codes. Only include regions from active markets (`enabled: true`) — draft markets (`enabled: false`) aren't serving buyers. To list all markets on a store, use the [`markets` query](https://shopify.dev/docs/api/admin-graphql/latest/queries/markets).

## POST https://{shop}.myshopify.com/admin/api/{api\_version}/graphql.json

## GraphQL query

```graphql
query {
  market(id: "gid://shopify/Market/26429947989") {
    id
    name
    enabled
    conditions {
      regionsCondition {
        regions(first: 250) {
          nodes {
            ... on MarketRegionCountry {
              code
            }
          }
        }
      }
    }
  }
}
```

## JSON response

```json
{
  "data": {
    "market": {
      "id": "gid://shopify/Market/26429947989",
      "name": "North America Market",
      "enabled": true,
      "conditions": {
        "regionsCondition": {
          "regions": {
            "nodes": [
              { "code": "CA" },
              { "code": "US" },
              { "code": "MX" }
            ]
          }
        }
      }
    }
  }
}
```

**Note:**

The `MarketRegionCountry` fragment in the query above already filters out [subdivision markets](https://shopify.dev/docs/apps/build/markets/subdivision-markets), which operate at the province or state level. Neither the deprecated single-market endpoints nor the country-based approach in this guide targets subdivision markets.

***

## Step 2: Store regions per market

When a merchant selects markets in your app, resolve each active market's regions and persist a mapping of market ID to country codes. For example, if the merchant selects the North America market (`gid://shopify/Market/26429947989`) with CA, MX, and US regions:

```json
{
  "gid://shopify/Market/26429947989": ["CA", "MX", "US"]
}
```

Store this data in an [app-owned metafield](https://shopify.dev/docs/apps/build/metafields/manage-metafields) or a [metaobject](https://shopify.dev/docs/apps/build/metaobjects) so it's exposable to your storefront or extension context. Alternatively, expose it through an app endpoint that the extension reads at render time.

Storing the market ID alongside the country codes lets you re-fetch or remove the correct entry when a `markets/update` or `markets/delete` webhook fires. At match time, flatten all values into a single set of country codes.

***

## Step 3: Match buyers by country

Match the buyer's country against your stored regions. If your matching logic runs in a storefront or extension context, read the country codes from the metafield or app endpoint you set up in Step 2.

## Before and after

## Before (deprecated)

```javascript
// Brittle: breaks when child markets are created
const naBannerMarketHandles = ["north_america"];
if (naBannerMarketHandles.includes(localization.market.handle)) {
  renderNaBanner();
}
```

## After (region-based)

```javascript
// Resilient: matches any buyer in the target countries
const naBannerRegions = {
  "gid://shopify/Market/26429947989": ["CA", "MX", "US"],
};
const naBannerCountries = new Set(Object.values(naBannerRegions).flat());
if (naBannerCountries.has(localization.country.isoCode)) {
  renderNaBanner();
}
```

The following table lists the deprecated endpoints and their region-based replacements for each API surface:

| Surface | Deprecated endpoint | Migrated endpoint |
| - | - | - |
| Liquid | [`Localization.market`](https://shopify.dev/docs/api/liquid/objects/localization#localization-market) | [`Localization.country.iso_code`](https://shopify.dev/docs/api/liquid/objects/localization#localization-country) |
| Liquid | [`Country.market`](https://shopify.dev/docs/api/liquid/objects/country#country-market) | [`Country.iso_code`](https://shopify.dev/docs/api/liquid/objects/country#country-iso_code) |
| Storefront API | [`Localization.market`](https://shopify.dev/docs/api/storefront/latest/objects/Localization#field-Localization.fields.market) | [`Localization.country.isoCode`](https://shopify.dev/docs/api/storefront/latest/objects/Localization#field-Localization.fields.country) |
| Storefront API | [`Country.market`](https://shopify.dev/docs/api/storefront/latest/objects/Country#field-Country.fields.market) | [`Country.isoCode`](https://shopify.dev/docs/api/storefront/latest/objects/Country#field-Country.fields.isoCode) |
| Shopify Functions | [`Localization { market }`](https://shopify.dev/docs/api/functions/latest/delivery-customization#Input.fields.localization.market) | [`Localization { country { isoCode } }`](https://shopify.dev/docs/api/functions/latest/delivery-customization#Input.fields.localization.country.isoCode) |
| Shopify Functions | [`deliveryAddress { market }`](https://shopify.dev/docs/api/functions/latest/delivery-customization#Input.fields.cart.deliveryGroups.deliveryAddress.market) | [`deliveryAddress { countryCode }`](https://shopify.dev/docs/api/functions/latest/delivery-customization#Input.fields.cart.deliveryGroups.deliveryAddress.countryCode) |
| Checkout UI extensions | [`shopify.localization.market`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/platform-apis/localization-api#docsstandardlocalizationapi-propertydetail-localization) | [`shopify.localization.country.isoCode`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/platform-apis/localization-api#docsstandardlocalizationapi-propertydetail-localization) |
| Checkout UI extensions | [`useLocalizationMarket`](https://shopify.dev/docs/api/checkout-ui-extensions/2025-07/target-apis/platform-apis/localization-api#useLocalizationMarket) | [`shopify.localization.country.isoCode`](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/platform-apis/localization-api#docsstandardlocalizationapi-propertydetail-localization) |
| GraphQL Admin API | [`Customer.market`](https://shopify.dev/docs/api/admin-graphql/latest/objects/Customer#field-Customer.fields.market) | [`Customer.defaultAddress.countryCodeV2`](https://shopify.dev/docs/api/admin-graphql/latest/objects/Customer#field-Customer.fields.defaultAddress.countryCodeV2) |
| GraphQL Admin API | [`CompanyLocation.market`](https://shopify.dev/docs/api/admin-graphql/latest/objects/CompanyLocation#field-CompanyLocation.fields.market) | [`CompanyLocation.shippingAddress.countryCodeV2`](https://shopify.dev/docs/api/admin-graphql/latest/objects/CompanyLocation#field-CompanyLocation.fields.shippingAddress.countryCodeV2) |
| GraphQL Admin API | [`MarketWebPresence.market`](https://shopify.dev/docs/api/admin-graphql/latest/objects/MarketWebPresence#field-MarketWebPresence.fields.market) | [`MarketWebPresence.markets`](https://shopify.dev/docs/api/admin-graphql/latest/objects/MarketWebPresence#field-MarketWebPresence.fields.markets) |

> **Note:** `MarketWebPresence.markets` returns a list of markets, not a country code.

***

## Step 4: Keep regions in sync with webhooks

When a merchant updates or deletes a market, your stored regions can become stale. Subscribe to both webhook topics in your [app configuration file](https://shopify.dev/docs/apps/build/cli-for-apps/app-configuration):

```toml
[webhooks]
api_version = "2026-07"


[[webhooks.subscriptions]]
uri = "/webhooks/markets/update"
topics = [ "markets/update" ]


[[webhooks.subscriptions]]
uri = "/webhooks/markets/delete"
topics = [ "markets/delete" ]
```

* **`markets/update`**: Fires when a market's configuration changes, for example, when a country is added or removed or when the market's status changes between active and draft. Re-fetch the market's regions and status, and update your stored list of country codes. Only include countries from active markets.
* **`markets/delete`**: Fires when a market is deleted. Remove the deleted market's reference from your stored data and recompute the list of country codes from any remaining markets.

A `markets/create` subscription isn't needed. New markets are picked up when the merchant selects them in Step 2, and country-based matching stays resilient until then.

See the [webhooks reference](https://shopify.dev/docs/api/webhooks) for full details on these topics.

**Caution:**

Without the `markets/delete` webhook, a deleted market's country codes persist indefinitely and your app continues targeting buyers it should no longer match.

***
