--- title: Communicate with a server description: Learn how to fetch data from your development server to your POS UI extension. api_version: 2025-01 api_name: pos-ui-extensions source_url: html: 'https://shopify.dev/docs/api/pos-ui-extensions/2025-01/server-communication' md: >- https://shopify.dev/docs/api/pos-ui-extensions/2025-01/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 ```tsx import React from 'react'; import { Tile, useApi, reactExtension } from '@shopify/ui-extensions-react/point-of-sale'; const SmartGridTile = () => { const api = useApi<'pos.home.tile.render'>(); return ( ); }; export default reactExtension('pos.home.tile.render', () => { return }) ``` ##### Modal ```tsx import React, { useEffect, useState } from 'react'; import { Screen, useApi, reactExtension, Text } from '@shopify/ui-extensions-react/point-of-sale'; const SmartGridModal = () => { const api = useApi<'pos.home.modal.render'>(); const [authenticated, setAuthenticated] = useState(); const [error, setError] = useState(); const [sessionToken, setSessionToken] = useState(); useEffect(() => { api.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} ); } export default reactExtension('pos.home.modal.render', () => { return }) ```