---
title: Admin UI extensions
description: >
Admin UI extensions make it possible to surface contextual app functionality
within the Shopify Admin interface.
api_version: 2024-01
api_name: admin-extensions
source_url:
html: 'https://shopify.dev/docs/api/admin-extensions/2024-01'
md: 'https://shopify.dev/docs/api/admin-extensions/2024-01.md'
---
# Admin UI extensions
Admin UI extensions make it possible to surface contextual app functionality within the Shopify Admin interface.
## Getting started
Use the Shopify CLI to [generate a new extension](https://shopify.dev/apps/tools/cli/commands#generate-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
```bash
# 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.
```
***
## App authentication
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](https://shopify.dev/docs/api/app-bridge-library/reference/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
```tsx
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, () => );
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 Info: {productInfo?.title};
}
```
***
## Direct API access
You can make Shopify Admin API requests directly from your extension using the [query API](https://shopify.dev/docs/api/admin-extensions/api/standard-api#standardapi-propertydetail-query) or the standard [web fetch API](https://developer.mozilla.org/en-US/docs/Web/API/fetch)!
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](https://shopify.dev/docs/apps/auth/oauth/access-modes#online-access) mode by default. If you want to use [offline access](https://shopify.dev/docs/apps/auth/oauth/access-modes#offline-access) mode, you can set the `direct_api_mode` property to `offline` in your [app TOML file](https://shopify.dev/docs/apps/tools/cli/configuration#admin).
Note: Direct API can't be used to manage storefront access tokens.
[Developer guide - Learn more about access scopes](https://shopify.dev/docs/api/usage/access-scopes)
## Query Shopify data
##### Fetch Product data
```tsx
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, () => );
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 The selected product title is {product?.title};
}
```
##### Query Product data
```tsx
import {reactExtension, useApi, Text} from '@shopify/ui-extensions-react/admin';
import {useEffect, useState} from 'react';
const TARGET = 'admin.product-details.block.render';
export default reactExtension(TARGET, () => );
function App() {
// Contextual "input" data passed to this extension:
const {data, query} = useApi(TARGET);
const [product, setProduct] = useState();
useEffect(() => {
const productId = data.selected?.[0]?.id;
query(
`query GetProduct($id: ID!) {
product(id: $id) {
title
}
}
`,
{variables: {id: productId}},
).then(({data}) => setProduct(data.product));
}, [data]);
return The selected product title is {product?.title};
}
```
***
## Custom protocols
Custom protocols make it easier to navigate to common locations, and construct URLs.
##### Shopify Protocol
Use the `shopify:admin` protocol when you want to construct a URL with a root of the Shopify Admin.
##### App Protocol
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.
##### Extension Protocol
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
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
##### Link to Product Page
```tsx
;
```
##### Fetch data
```ts
fetch('shopify:admin/api/graphql.json', {
method: 'POST',
body: JSON.stringify(simpleProductQuery),
});
```
## app:
## Link to Settings
```tsx
;
```
## extension:
## Trigger Action Extension from a Block extension
```tsx
;
```
## /relative/urls
## Link to route in your app
```tsx
;
```
***
## Deploying
Use the Shopify CLI to [deploy your app and its extensions](https://shopify.dev/docs/apps/deployment/extension).
## Deploy an extension
## CLI
```bash
# navigate to your app's root directory:
cd my-app
# deploy your app and its extensions:
npm run deploy
# follow the steps to deploy
```
***
## Security
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)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) for the origin `https://extensions.shopifycdn.com`.
If you have a custom [`Access-Control-Allow-Origin` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin) set, you must include `https://extensions.shopifycdn.com` in the list of allowed origins.
If you are using the [Shopify App Remix Template](https://github.com/Shopify/shopify-app-template-remix), this is done automatically for you.
***
## Tutorials and resources
Deepen your understanding of Admin UI extensions with these tutorials and resources.
[Tutorial - Get started building your first admin extension](#getting-started)
[Component APIs - See all available components](https://shopify.dev/docs/api/admin-extensions/components)
[Reference - View a list of available extension targets](https://shopify.dev/docs/api/admin-extensions/api/extension-targets)
[App authentication - Make authenticated requests to your app's backend](#app-authentication)
[Direct API access - Access the Shopify GraphQL API directly](#direct-api-access)
[Custom protocols - Easily construct URLs to navigate to common locations](#custom-protocols)
[UI reference - Figma UI Kit](https://www.figma.com/community/file/1265417558571498993)
***