---
gid: a31f1697-7808-4d38-927c-f8c545bec25d
title: Build an admin action
description: Learn how to create admin action extensions on resource and index pages in the Shopify admin.
---
This guide is the first part in a four-part tutorial series on how to build a feature using admin action and block extensions. The guide demonstrates how to build a basic action extension that enables users to log issues on products that can be tracked and resolved. The guide also demonstrates how to create admin action extensions that can be launched from an admin block extension with extra context about what resource or data the action should pre-populate for editing.
![The issue tracker action over a modal. The action has input fields for a title and description.](/assets/admin/admin-actions-and-block/build-an-admin-action/opened-action.png)
## What you'll learn
In this tutorial, you'll learn how to do the following tasks:
- Create an admin action extension that displays on the product details page
- Fetch information to populate the extensions's initial state
- Create a UI for the extension that enables it to gather more input from merchants
- Update the data using GraphQL based on merchant input
- Run the extension locally and test it on a development store
Scaffold an app with the `write_products` access scope that uses [Shopify CLI 3.48 or higher](/docs/api/shopify-cli#upgrade).
- If you created a Remix app, then the `write_products` access scope is automatically granted to your app.
- If you created an extension-only app, then you need to explicitly grant the `write_products` access scope to your [custom app](/docs/apps/auth/access-token-types/admin-app-access-tokens#changing-api-scopes).
## Create a new extension
Use Shopify CLI to [generate starter code](/docs/api/shopify-cli/app/app-generate-extension) for your action extension.
1. Navigate to your app directory:
```bash
cd
```
2. Run the following command to create a new admin action extension:
```bash
shopify app generate extension --template admin_action --name issue-tracker-action --flavor react
```
The command creates a new extension template in your app's `extensions` directory with the following structure:
```text
extensions/issue-tracker-action
├── README.md
├── locales
│ ├── en.default.json // The default locale for the extension
│ └── fr.json // The French language translations for the extension
├── package.json
├── shopify.extension.toml // The config file for the extension
└── src
└── AdminAction.jsx // The code that defines the action's UI and behavior
```
## Write the extension's UI
Complete the following steps to write the extension's UI:
### Review the configuration
The extension's `.toml` file stores the extension's static configuration. To have the issue tracker display product detail pages, validate that the `target` is set to `admin.product-details.action.render`.
[admin.product-details.action.render](/docs/api/admin-extensions/latest/api/extension-targets#extensiontargets-propertydetail-adminproductdetailsactionrender)
### Update title
To update the display name when merchants select the action from the menu, in locale files edit the `name` value. The action extension uses the [i18n API](/docs/api/admin-extensions/api/action-extension-api#actionextensionapi-propertydetail-i18n) to translate strings so that your app is more accessible to a wider audience. This API gives you access to the strings stored in the locale files, and automatically chooses the correct string for the current user's locale.
### Translate title
Optionally translate your title to French.
### Use UI components
Admin UI extensions are rendered using [Remote UI](https://github.com/Shopify/remote-dom/tree/remote-ui), which is a fast and secure remote-rendering framework. Because Shopify renders the UI remotely, components used in the extensions must comply with a contract in the Shopify host. We provide these components through the admin UI extensions library.
[Admin UI extensions components](/docs/api/admin-extensions/components)
### Note the export
You can view the source of your extension in the `src/ActionExtension.jsx` file. This file defines a functional React component exported to run at the extension's target. You can create the extension's body by importing and using components from the `@shopify/ui-extensions-react/admin` package.
The extension point in the component export must match the extension point defined in your `.toml` file, or the extension won't render.
### Render a UI
To build your action's UX, return some components from `src/ActionExtension.jsx`.
At this point, you can use the developer console to [run your app's server and preview your extension](#step-4-test-the-extension). After you preview the extension, changes to your extension's code automatically reload the extension that you're previewing. This enables you to preview your extension and see it update live as you make changes to the code.
## Write the extension logic and connect to the GraphQL Admin API
After defining the extension's UI, use standard React tooling to write the logic that controls the extension.
When you're writing extensions, you don't need proxy calls to the [GraphQL Admin API](/docs/api/admin-graphql) through your app's backend. Instead, your extension can use [direct API access](/docs/api/admin-extensions#directapiaccess) to create requests directly using `fetch`. This helps extensions be more performant and responsive for merchants.
In this step, you'll create a utility file to contain GraphQL queries that the extension uses to read and write data to the metafield API.
Your app can also get data from the extension APIs, which includes data on the current resource from the `data` API.
Add new file at `./src/utils.js`. This file contains the GraphQL queries that the extension uses to read and write data to the GraphQL Admin API.
[metafieldDefinitionCreate](/docs/api/admin-graphql/latest/mutations/metafieldDefinitionCreate)
[metafieldsSet](/docs/api/admin-graphql/latest/mutations/metafieldsSet)
Import the `getIssues` utility method and use it to update the extension state.
Call the `updateIssues` utility method when the form is submitted.
## Test the extension
After you've built the extension, test it with the following steps:
1. Navigate to your app directory:
```bash
cd
```
2. To build and preview your app, either start or restart your server with the following command:
```bash
shopify app dev
```
3. Press `p` to open the developer console.
4. In the developer console page, click on the preview link for the issue tracker action extension.
5. The product details page opens. If you don't have a product in your store, then you need to create one.
6. To launch your extension, in the top right of the page click the **More actions** dropdown list and select your extension.
7. Fill out the modal and click **Create**.
8. Validate that the metafield is created and populated with your issue text, by navigating to the metafields card at the bottom of the page, and select **Show all**.
Update your code to the control the form and write the data to the admin metafield API using the methods from `./src/utils.js`.
### Next steps
#### Block extension
Complete the next guide in this tutorial series by building a block extension to list the issues created by the action extension.
#### Extension targets
Learn about the surfaces in the Shopify admin where you can create admin extensions.
#### Components
Learn about the full set of available components for writing admin UI extensions.