---
title: Hide admin UI extensions
description: Learn how to conditionally hide admin action and block UI extensions in the Shopify admin.
source_url:
html: https://shopify.dev/docs/apps/build/admin/actions-blocks/hide-extensions?extension=react
md: https://shopify.dev/docs/apps/build/admin/actions-blocks/hide-extensions.md?extension=react
---
# Hide admin UI extensions
This guide is the final part of a five-part tutorial series that describes how to build UI extensions that display as actions and blocks in Shopify admin. Before starting this guide, you'll need to build or copy the code for the issue tracker admin action and admin block from the [tutorial for connecting UI extensions to your app's backend](https://shopify.dev/docs/apps/build/admin/actions-blocks/connect-app-backend).
Alternatively, you can complete this section immediately after completing the [build an admin action](https://shopify.dev/docs/apps/build/admin/actions-blocks/build-admin-action) and [build an admin block](https://shopify.dev/docs/apps/build/admin/actions-blocks/build-admin-block) tutorials.
So far you've created UI extensions that add an action and block that allows merchants to create and track issues in their Shopify admin. In this tutorial, you'll learn how to hide a UI extension when it's not relevant to the target.
To demonstrate conditional logic, we'll check the variant count of a product to determine if the UI extension should be visible. If the product has more than one variant, then the UI extension will be visible. If the product has only one variant, then the UI extension will be hidden.
## What you'll learn
In this tutorial, you'll learn how to do the following tasks:
* Minimize the block when it's not relevant to the target.
* Hide the menu item that launches the action when it's not relevant to the target.
## Requirements
[Tutorials](https://shopify.dev/docs/apps/admin/admin-actions-and-blocks)
You've completed or copied the code from the [admin action tutorial](https://shopify.dev/docs/apps/build/admin/actions-blocks/build-admin-action) and the [admin block tutorial](https://shopify.dev/docs/apps/build/admin/actions-blocks/build-admin-block).
## Project
[View on GitHub](https://github.com/Shopify/example-admin-action-and-block-preact)
## Collapse an admin block
If an admin block isn't relevant on a page, then you can collapse it to minimize disruption for merchants, while still enabling them to see that they have pinned it to the page. To minimize an admin block, you can return `null` inside the `AdminBlock` component of your UI extension.
### Use the `getIssues` function to determine if the admin block should be visible.
Initialize a state variable called `shouldRender` and set it to `false`. You're already using the `getIssues` function to get metafield values. Using the same function, check if the product has more than one variant. If it does, then set the `shouldRender` state to `true`.
## /extensions/issue-tracker-conditional-block/src/BlockExtension.jsx
```jsx
import { render } from "preact";
import { useEffect, useMemo, useState } from "preact/hooks";
import { getIssues, updateIssues } from "../../issue-tracker-block/src/utils";
export default async () => { {
render(, document.body);
}
const PAGE_SIZE = 3;
function Extension() {
const { i18n, data, navigation } = shopify;
const [issues, setIssues] = useState([]);
const productId = data.selected[0].id;
const issuesCount = issues.length;
const totalPages = issuesCount / PAGE_SIZE;
const [loading, setLoading] = useState(true);
const [_, setInitialValues] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [shouldRender, setShouldRender] = useState(false);
useEffect(() => {
(async function getProductInfo() {
const productData = await getIssues(productId);
setLoading(false);
if (productData?.data?.product?.variants?.edges.length > 1) {
setShouldRender(true);
}
if (productData?.data?.product?.metafield?.value) {
```
### Conditionally return JSX content based on the result of the get​Product​Variants function.
If `shouldRender` is `true`, then render the block's content. If it's `false`, then return `null` to collapse the block.
Use the `collapsedSummary` to provide meaningful information to the merchant about why the block is collapsed.
## /extensions/issue-tracker-conditional-block/src/BlockExtension.jsx
```jsx
import { render } from "preact";
import { useEffect, useMemo, useState } from "preact/hooks";
import { getIssues, updateIssues } from "../../issue-tracker-block/src/utils";
export default async () => { {
render(, document.body);
}
const PAGE_SIZE = 3;
function Extension() {
const { i18n, data, navigation } = shopify;
const [issues, setIssues] = useState([]);
const productId = data.selected[0].id;
const issuesCount = issues.length;
const totalPages = issuesCount / PAGE_SIZE;
const [loading, setLoading] = useState(true);
const [_, setInitialValues] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [shouldRender, setShouldRender] = useState(false);
useEffect(() => {
(async function getProductInfo() {
const productData = await getIssues(productId);
setLoading(false);
if (productData?.data?.product?.variants?.edges.length > 1) {
setShouldRender(true);
}
if (productData?.data?.product?.metafield?.value) {
```
## Test hiding the admin block
After you've updated the UI extension, test that the admin block collapses with the following steps:
1. Navigate to your app directory:
## Terminal
```bash
cd
```
2. To build and preview your app, either start or restart your server with the following command:
## Terminal
```bash
shopify app dev
```
3. Press `p` to open the developer console.
4. In the Dev Console page, click on the preview link for the issue tracker UI extension.
5. If there are any product variants, delete them and confirm that the admin block is collapsed.
6. Add a product variant with two options and confirm that the admin block expands.
### Hide an admin action
Hiding a UI extension's admin action uses a second script to control the visibility of the action in the **More actions** menu. This script only runs after the page is loaded and doesn't maintain state.
Add a field to your TOML file to specify the path to the `shouldRender` script.
## /extensions/issue-tracker-conditional-action/shopify.extension.toml
```toml
api_version = "2025-10"
[[extensions]]
name = "t:name"
handle = "conditional-admin-action-extension"
type = "ui_extension"
# Only 1 target can be specified for each Admin action condition extension
[[extensions.targeting]]
module = "./src/ActionExtension.jsx"
target = "admin.product-details.action.render"
# This is the relative path to the module that contains the logic to determine if the action trigger should be visible.
[extensions.targeting.should_render]
module = "./src/condition/shouldRender.js"
```
Create a `condition/shouldRender.js` file in the same `src` directory as the extension that you want to control.
## /extensions/issue-tracker-conditional-action/src/condition/shouldRender.js
```javascript
///
import { getVariantsCount } from "../utils";
export default async function extension() {
const { data } = shopify;
const variantCount = await getVariantsCount(data.selected[0].id);
return { display: variantCount > 1 };
}
```
Register your module by defining an `extension` function that is the `default` `export` of the file.
## /extensions/issue-tracker-conditional-action/src/condition/shouldRender.js
```javascript
///
import { getVariantsCount } from "../utils";
export default async function extension() {
const { data } = shopify;
const variantCount = await getVariantsCount(data.selected[0].id);
return { display: variantCount > 1 };
}
```
Create a function called `getVariantsCount` to use Direct API to fetch variants of the product in your `utils.js` file.
## /extensions/issue-tracker-conditional-action/src/utils.js
```javascript
export async function updateIssues(id, newIssues) {
// This example uses metafields to store the data. For more information, refer to https://shopify.dev/docs/apps/custom-data/metafields.
return await makeGraphQLQuery(
`mutation SetMetafield($namespace: String!, $ownerId: ID!, $key: String!, $type: String!, $value: String!) {
metafieldDefinitionCreate(
definition: {namespace: $namespace, key: $key, name: "Tracked Issues", ownerType: PRODUCT, type: $type, access: {admin: MERCHANT_READ_WRITE}}
) {
createdDefinition {
id
}
}
metafieldsSet(metafields: [{ownerId:$ownerId, namespace:$namespace, key:$key, type:$type, value:$value}]) {
userErrors {
field
message
code
}
}
}
`,
{
ownerId: id,
namespace: "$app:issues",
key: "issues",
type: "json",
value: JSON.stringify(newIssues),
},
);
}
export async function getIssues(productId) {
// This example uses metafields to store the data. For more information, refer to https://shopify.dev/docs/apps/custom-data/metafields.
const res = await makeGraphQLQuery(
`query Product($id: ID!) {
product(id: $id) {
metafield(namespace: "$app:issues", key:"issues") {
value
}
}
}
`,
{ id: productId },
);
if (res?.data?.product?.metafield?.value) {
return JSON.parse(res.data.product.metafield.value);
}
}
async function makeGraphQLQuery(query, variables) {
const graphQLQuery = {
query,
variables,
};
const res = await fetch("shopify:admin/api/graphql.json", {
method: "POST",
body: JSON.stringify(graphQLQuery),
});
if (!res.ok) {
console.error("Network error");
}
return await res.json();
}
// Use direct API calls to fetch data from Shopify.
// See https://shopify.dev/docs/api/admin-graphql for more information about Shopify's GraphQL API
export async function getVariantsCount(id) {
const getProductQuery = {
query: `query Product($id: ID!) {
product(id: $id) {
variantsCount {
count
}
}
}`,
variables: { id },
};
const res = await fetch("shopify:admin/api/graphql.json", {
method: "POST",
body: JSON.stringify(getProductQuery),
});
if (!res.ok) {
console.error("Network error");
}
const productData = await res.json();
return productData.data.product.variantsCount.count;
}
```
Use the `getVariantsCount` function to determine the number of variants on the product. Return an object with a key of `display` and a Boolean value to control whether the action extension menu item is visible.
## /extensions/issue-tracker-conditional-action/src/condition/shouldRender.js
```javascript
///
import { getVariantsCount } from "../utils";
export default async function extension() {
const { data } = shopify;
const variantCount = await getVariantsCount(data.selected[0].id);
return { display: variantCount > 1 };
}
```
## Test hiding the admin action
After you've updated the UI extensions that provide your admin action and block, test them with the following steps:
1. Navigate to your app directory:
## Terminal
```bash
cd
```
2. To build and preview your app, either start or restart your server with the following command:
## Terminal
```bash
shopify app dev
```
3. Press `p` to open the developer console.
4. Delete any variants that were added in the previous section.
5. If there are any product variants, delete them and confirm that the admin action is not visible in the More actions menu.
6. Add a product variant with two options and confirm that the admin action is visible in the **More actions** menu.
## /extensions/issue-tracker-conditional-block/src/BlockExtension.jsx
```jsx
import { render } from "preact";
import { useEffect, useMemo, useState } from "preact/hooks";
import { getIssues, updateIssues } from "../../issue-tracker-block/src/utils";
export default async () => { {
render(, document.body);
}
const PAGE_SIZE = 3;
function Extension() {
const { i18n, data, navigation } = shopify;
const [issues, setIssues] = useState([]);
const productId = data.selected[0].id;
const issuesCount = issues.length;
const totalPages = issuesCount / PAGE_SIZE;
const [loading, setLoading] = useState(true);
const [_, setInitialValues] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [shouldRender, setShouldRender] = useState(false);
useEffect(() => {
(async function getProductInfo() {
const productData = await getIssues(productId);
setLoading(false);
if (productData?.data?.product?.variants?.edges.length > 1) {
setShouldRender(true);
}
if (productData?.data?.product?.metafield?.value) {
```
## Tutorial complete!
Congratulations! You learned how to hide your UI extension's admin blocks and actions when they are not relevant to a given target. Keep the momentum going with these related resources.
[](https://shopify.dev/docs/api/admin-extensions)
[Admin UI extension APIs](https://shopify.dev/docs/api/admin-extensions)
[Learn about the admin UI extension APIs.](https://shopify.dev/docs/api/admin-extensions)
[](https://github.com/Shopify/ui-extensions)
[Participate](https://github.com/Shopify/ui-extensions)
[File any issues or feature requests on the UI Extensions GitHub repository.](https://github.com/Shopify/ui-extensions)
[](https://shopify.dev/docs/apps/deployment/app-versions)
[Deploy](https://shopify.dev/docs/apps/deployment/app-versions)
[Learn how to deploy your UI extensions to merchants.](https://shopify.dev/docs/apps/deployment/app-versions)