Show Geo Support Links by Visitor IP in Shopify

Autor:Lisa Farrell · 2026-06-01

Cross-border Shopify stores often need different support channels for different regions. Theme JavaScript can call https://my.ipin.io/info and show a suitable support link while keeping a default contact option.

API explanation

A browser-side call checks the visitor IP and returns the visitor IP, country, region, and city. It is suitable for localized content display.

{"ip":"185.220.236.7","country":"TW","region":"Taiwan","city":"Taipei"}

Use cases

These scenarios show the value of the IP information interface while clearly separating server IP from visitor IP.

  • These scenarios show the value of the IP information interface while clearly separating server IP from visitor IP.
  • Show Geo Support Links by Visitor IP in Shopify
  • API explanation
  • SEO and UX recommendations

Implementation logic

Before implementation, identify the requester: server requests return server IP, while browser requests return visitor IP.

  • Before implementation, identify the requester: server requests return server IP, while browser requests return visitor IP.
  • A browser-side call checks the visitor IP and returns the visitor IP, country, region, and city. It is suitable for localized content display.
  • All examples below use https://my.ipin.io/info directly, with localized comments and interface text.
  • Default content should remain complete and readable, while regional content acts as an enhancement. Search engines can crawl stable content, and the page remains usable if the API fails.

Code example

All examples below use https://my.ipin.io/info directly, with localized comments and interface text.

theme.liquid

<a class="ipin-support-btn" href="/support">Support</a>
<script>
document.addEventListener("DOMContentLoaded", async function () {
  const buttons = document.querySelectorAll(".ipin-support-btn");
  const map = { TW: "/support/tw", US: "/support/us", JP: "/support/jp" };
  try {
    // Browser-side call to /info: detects the visitor IP.
    const info = await fetch("https://my.ipin.io/info").then(res => res.json());
    buttons.forEach(btn => btn.href = map[info.country] || "/support");
  } catch (e) {
    // Keep the default value when the API request fails.
    buttons.forEach(btn => btn.href = "/support");
  }
});
</script>

SEO and UX recommendations

Default content should remain complete and readable, while regional content acts as an enhancement. Search engines can crawl stable content, and the page remains usable if the API fails.

Common mistakes

The following issues affect article accuracy, code usability, and the credibility of the API explanation.

  • The following issues affect article accuracy, code usability, and the credibility of the API explanation.
  • Default content should remain complete and readable, while regional content acts as an enhancement. Search engines can crawl stable content, and the page remains usable if the API fails.
  • Before implementation, identify the requester: server requests return server IP, while browser requests return visitor IP.
  • These scenarios show the value of the IP information interface while clearly separating server IP from visitor IP.

Summary

A browser-side call checks the visitor IP and returns the visitor IP, country, region, and city. It is suitable for localized content display.

FAQ

The questions below are written specifically for this article and are directly related to the implementation.

Question:Why is Shopify suitable for browser-side calls?
Answer:Theme JavaScript runs in the visitor browser, so the response represents the visitor IP.
Question:Why does the example use a class instead of an ID?
Answer:A page can contain multiple support buttons, and a class lets the script update all of them.
Question:Can this support WhatsApp, LINE, or email?
Answer:Yes. Configure the right support URL for each country in the mapping table.
Question:What happens if the API fails?
Answer:The default support link stays visible and usable.
Question:Where should the code be placed?
Answer:Place it before the closing body tag in theme.liquid or in the template that renders the support block.