Skip to main content

Admin UI extensions

Admin UI extensions make it possible to surface contextual app functionality within the Shopify Admin interface.

Use the Shopify CLI to generate a new extension within your app.

If you already have a Shopify app, you can skip right to the last command shown here.

Generate an extension

CLI

# scaffold an app if you don't already have one:
npm init @shopify/app@latest --name my-app

# navigate to your app's root directory:
cd my-app

# generate a new extension:
npm run generate extension
# follow the steps to create a new
# extension in ./extensions.

Admin UI extensions can also make authenticated calls to your app's backend. When you use fetch() to make a request to your app's configured auth domain or any of its subdomains, an Authorization header is automatically added with a Shopify OpenID Connect ID Token. There's no need to manually manage session tokens.

Relative URLs passed to fetch() are resolved against your app's app_url. This means if your app's backend is on the same domain as your app_url, you can make requests to it using fetch('/path').

Make requests to your app's backend

Get Product Data

import {reactExtension, useApi, Text} from '@shopify/ui-extensions-react/admin';
import {useEffect, useState} from 'react';

// Get product info from app backend
async function getProductInfo(id) {
const res = await fetch(`/api/products/${id}`);
return res.json();
}

const TARGET = 'admin.product-details.block.render';

export default reactExtension(TARGET, () => <App />);

function App() {
// Contextual "input" data passed to this extension:
const {data} = useApi(TARGET);
const productId = data.selected?.[0]?.id;

const [productInfo, setProductInfo] = useState();
useEffect(() => {
getProductInfo(productId).then(setProductInfo);
}, [productId]);

return <Text>Info: {productInfo?.title}</Text>;
}

You can make Shopify Admin API requests directly from your extension using the query API or the standard web fetch API!

Any fetch() calls from your extension to Shopify's Admin GraphQL API are automatically authenticated by default. These calls are fast too, because Shopify handles requests directly.

Direct API requests use online access mode by default. If you want to use offline access mode, you can set the direct_api_mode property to offline in your app TOML file.

Note: Direct API can't be used to manage storefront access tokens.

Query Shopify data

import {reactExtension, useApi, Text} from '@shopify/ui-extensions-react/admin';
import {useEffect, useState} from 'react';

async function getProduct(id) {
const res = await fetch('shopify:admin/api/graphql.json', {
method: 'POST',
body: JSON.stringify({
query: `
query GetProduct($id: ID!) {
product(id: $id) {
title
}
}
`,
variables: {id},
}),
});
return res.json();
}

const TARGET = 'admin.product-details.block.render';

export default reactExtension(TARGET, () => <App />);

function App() {
// Contextual "input" data passed to this extension:
const {data} = useApi(TARGET);

const [product, setProduct] = useState();
useEffect(() => {
const productId = data.selected?.[0]?.id;
getProduct(productId).then(({data}) => setProduct(data.product));
}, [data]);

return <Text strong>The selected product title is {product?.title}</Text>;
}

Custom protocols make it easier to navigate to common locations, and construct URLs.

Use the shopify:admin protocol when you want to construct a URL with a root of the Shopify Admin.

Use the app: protocol to construct a URL for your app. Shopify will handle constructing the base URL for your app. This works for both embedded and non-embedded apps.

Triggers an action extension from a block extension using the extension: protocol. The extensionTarget is the target of the action extension. The handle is the handle of the action extension that will be opened.

Relative urls are relative to your app and are useful when you want to link to a route within your app. This works for both embedded and non-embedded apps.

Shopify:admin

Deploy an extension

CLI

# navigate to your app's root directory:
cd my-app

# deploy your app and its extensions:
npm run deploy

# follow the steps to deploy

UI Extensions run on a different origin than the Shopify Admin. For network calls to succeed, your server must support cross-origin resource sharing (CORS) for the origin https://extensions.shopifycdn.com.

If you have a custom Access-Control-Allow-Origin header set, you must include https://extensions.shopifycdn.com in the list of allowed origins.

If you are using the Shopify App Remix Template, this is done automatically for you.