--- title: Communicate with a server description: Learn how to fetch data from your development server to your POS UI extension. api_version: 2025-10 api_name: pos-ui-extensions source_url: html: https://shopify.dev/docs/api/pos-ui-extensions/latest/server-communication md: https://shopify.dev/docs/api/pos-ui-extensions/latest/server-communication.md --- # Communicate with a server Learn how to fetch data from your development server to your POS UI extension. ## Authenticating with a development server Often, an extension running on a simulator or a device will need to communicate with a development server running on a local machine. One solution is to use the [session API](https://shopify.dev/docs/api/pos-ui-extensions/apis/session-api) to get session tokens, and to pass these tokens to your development servers for [authentication](https://shopify.dev/docs/apps/auth/session-tokens/getting-started) using the [shopify\_app gem](https://github.com/Shopify/shopify-api-ruby). ## CORS considerations Requests originating from an extension will be of origin **cdn.shopify.com** and **extensions.shopifycdn.com**. Your server needs to allow requests from both origins. ## HTTPS requirement Shopify POS will refuse to fetch any non-HTTPS requests. Therefore, you must find a way to host your development server where it serves HTTPS requests. For example, a standard rails server will run on `localhost:3000`. Attempting to access this server from an Android emulator using `10.0.2.2:3000` will fail. One strategy is to use [Cloudflare Quick Tunnels](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/do-more-with-tunnels/trycloudflare/), which provide an HTTPS URL to connect. ## Example extension Here is an example extension that presents a Smart Grid tile. When tapped, the tile will present a modal that uses the Session API to get a session token, and then fetches a test endpoint on the development server. ### Examples * #### Example extension ##### Tile ```jsx import {render} from 'preact'; export default function extension() { render(, document.body); } function SmartGridTile() { return ( shopify.action.presentModal()} /> ); } ``` ##### Modal ```jsx import {render} from 'preact'; import {useState, useEffect} from 'preact/hooks'; export default function extension() { render(, document.body); } function SmartGridModal() { const [authenticated, setAuthenticated] = useState(); const [error, setError] = useState(); const [sessionToken, setSessionToken] = useState(); useEffect(() => { shopify.session.getSessionToken().then((token) => { setSessionToken(token); fetch('https://YOUR_DEVELOPMENT_SERVER/api/extensions/test', { method: 'GET', mode: 'cors', credentials: 'include', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, }, }) .then((response) => setAuthenticated(response.status)) .catch(setError); }); }, []); return ( Token: {sessionToken} Authenticated: {authenticated} Error: {error} ); } ```