--- title: App Home (UI Extension) description: > Build App Home surfaces as UI extensions using the `admin.app.home.render` target. This surface combines the persistent workspace of App Home with the extension model of admin UI extensions. api_version: 2026-07-rc source_url: html: 'https://shopify.dev/docs/api/app-home-ui-extension/latest' md: 'https://shopify.dev/docs/api/app-home-ui-extension/latest.md' api_name: app-home-ui-extension --- # App Home UI extensions App Home is a dedicated area in [Shopify admin](https://shopify.dev/docs/apps/build/admin) for your app to render its landing page and UI. Merchants use the UI in this space to navigate to your app's other extensions, open modals and workflows, and access your app's data. App Home UI extensions render your app's landing page as a Preact-based extension module, so you can ship App Home alongside your other [admin UI extensions](https://shopify.dev/docs/api/admin-extensions) from the same app bundle. Shopify hosts the entire extension, so you don't need to run or deploy a web server for the App Home experience. Use this when you're building a custom app and want the persistent, full-page workspace of App Home without managing your own hosting. ## When to use this extension type **Note:** App Home UI extensions can be used only for custom-distribution apps. If you want to build a public app you can distribute through the Shopify App Store, then use the iframe-based [App Home](https://shopify.dev/docs/api/app-home) solution. With App Home UI extensions, you can build a custom app without managing your own hosting. Shopify hosts the entire extension, including your JavaScript bundle and static assets, so you can deploy your whole app to Shopify with `shopify app deploy`. There's no web server to provision, no infrastructure to maintain, and no separate iframe-hosted frontend to ship. This works well for simple, self-contained apps that fit inside the [Remote DOM runtime](https://shopify.dev/docs/api/admin-extensions) and don't need their own backend. If your app needs [webhooks](https://shopify.dev/docs/api/webhooks), background jobs, or other server-side functionality, then you'll still need to host your own backend for those use cases and call it from the extension. To build a landing page for your app in the App Home surface, you can use an App Home UI extension (described in this reference), or build an [iframe-based App Home](https://shopify.dev/docs/api/app-home) app. Use App Home UI extensions when you want: * A custom app you can deploy entirely to Shopify, with no hosting of your own. * A persistent, full-page app workspace that's part of your extension bundle rather than a separate iframe-hosted web app. * A single source of truth for your app's primary UI alongside your other admin UI extensions. * The performance and design-system benefits of [Polaris web components](https://shopify.dev/docs/api/app-home-ui-extension/latest/web-components) without hosting a web server for the App Home experience. Use the iframe-based App Home when your app needs a full backend with server-side rendering, webhooks, or access to browser APIs that aren't available in the Remote DOM runtime. To learn more about the differences between App Home UI extensions and iframe-based App Home apps, see [Apps in App Home](https://shopify.dev/docs/apps/build/app-home). *** ## Getting started App Home UI extensions are a special type of [admin UI extensions](https://shopify.dev/docs/api/admin-extensions) that render a landing page for your app as a Preact-based extension module. You configure it the same way as any other admin UI extension, with a [`shopify.extension.toml`](https://shopify.dev/docs/apps/build/app-extensions/configure-app-extensions#how-it-works) configuration file and a TSX or JSX module. To start building your first App Home UI extension, scaffold it using [Shopify CLI](https://shopify.dev/docs/api/shopify-cli). You can either add your extension to an existing app, or create a new extension-only app from scratch. The command creates a framework for building an extension-only app that includes a basic App Home landing page using the `admin.app.home.render` target. ##### Scaffold a new app ```terminal shopify app init # select "Build an extension-only app" when prompted ``` ##### Add to an existing app ```terminal cd my-app shopify app generate extension # select the "App Home UI" extension type when prompted ``` *** ## Building your extension App Home UI extensions render your app's landing page in the App Home surface using the [`admin.app.home.render` target](https://shopify.dev/docs/api/app-home-ui-extension/latest/targets). To build your app, you use target APIs that provide access to data and functionality, and web components to render your app's UI. ### APIs: Define what your extension does Your extension can use APIs to perform actions like launching Shopify admin workflows, querying the GraphQL Admin API, and storing data in browser storage. When your extension runs, Shopify provides a `shopify` global object that you use to access data and features. Most APIs for App Home UI extensions are properties on this object. For example, `shopify.intents` launches Shopify admin workflows, `shopify.query` runs GraphQL Admin API queries, and `shopify.storage` stores data in browser storage. If your app uses ESLint, then update your configuration to include the global `shopify` object to prevent linting errors. [Reference - Explore all target APIs](https://shopify.dev/docs/api/app-home-ui-extension/latest/target-apis) ## Launch a Shopify workflow with intents ```tsx async function createProduct() { const activity = shopify.intents.invoke('create:shopify/Product'); const result = await activity; if (result.code === 'ok') { shopify.toast.show('Product created'); } } ``` ## ESLint configuration ```javascript module.exports = { globals: { shopify: 'readonly', }, }; ``` ### Web components: Design your interface Web components are the UI building blocks that you use to display data and trigger API functions. These components are native UI elements that follow [Shopify's design system](https://shopify.dev/docs/apps/design) and are built with [remote-dom](https://github.com/Shopify/remote-dom), Shopify's library for building cross-platform user interfaces. Use web components to build interfaces that integrate with Shopify's admin design system. [Reference - Explore all web components](https://shopify.dev/docs/api/app-home-ui-extension/latest/web-components) ## Build a page with sections and actions ```html 3 products are below your restock threshold. Review these items and reorder before they sell out. Review products ``` *** ## Configuration Admin UI extensions rely on a `shopify.extension.toml` file that contains the extension's configuration. This includes the extension name, type, API version, and targeting definitions. The `name` value is what displays in the admin interface to merchants, so consider this value carefully. We recommend that the `api_version` reflects the latest supported API version. ### Properties App Home UI extensions use the following configuration properties: ##### `api_version` required The version of the API that's being used for the extension. If provided in the `[[extensions]]` array, then the specified API version is used instead of the root level `api_version`. ##### `[[extensions]]` required The name of the array that contains all extensions listed in the TOML file. Contains the following properties: * `type`: required The extension type. For App Home UI extensions, use `ui_extension`. * `name`: required The merchant-facing name of the extension. After you [generate an extension](https://shopify.dev/docs/api/shopify-cli/app/app-generate-extension), you're prompted to provide a name for your extension. The `name` property is translatable if it starts with a `t:` and uses a key defined in your translation data. **Limitations**: * 5 characters minimum * 30 characters maximum * `handle`: required The unique internal identifier for the extension. After you create a draft version of the extension, or deploy an extension, you can't change the `handle` value. **Limitations**: * Allowed characters: `a-z`, `A-Z`, `0-9`, `-` * 100 characters maximum * Must be unique within the app * `uid`: required The extension user identifier that must be unique within the app. An app-scoped identifier used by `shopify app deploy` to determine whether an extension is being created, updated, or deleted. * `description`: optional The merchant-facing description of the extension. ##### `[[extensions.targeting]]` required The name of the array that contains a target and its associated module. Contains the following properties: * `target`: required An identifier that specifies where you're injecting your extension into the admin interface. For App Home UI extensions, use `admin.app.home.render`. * `module`: required The path to the JavaScript or TypeScript file that contains your extension code. This file exports the extension function that renders your UI or handles events. * `assets`: The path to the directory that contains your extension's static files (such as images and icons). Allowed file extensions are `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.avif`, `.ico`, `.txt`, `.md`, and `.json`. SVG files aren't supported in the asset bundle. For per-file and total bundle size limits, see [Limits](#limits). **Important:** When you upload assets, the content must comply with Shopify's [API Terms of Service](https://www.shopify.com/legal/api-terms). Don't upload personally identifiable information (PII), and ensure you have the rights to all assets you upload. ## shopify.extension.toml ```toml api_version = "2026-07" [[extensions]] type = "ui_extension" name = "App Home" handle = "app-home" uid = "f62f100d-15e6-9866-eda9-23f99de4b5d26e347042" [[extensions.targeting]] target = "admin.app.home.render" module = "./src/Home.tsx" assets = "./assets" ``` *** ## Direct API access Use direct API access when your extension needs to query or modify Shopify data in real-time. For example, you might want to update product metafields, fetch detailed order information, or modify inventory levels. You can make [GraphQL Admin API](https://shopify.dev/docs/api/admin-graphql) requests directly from your extension using the [`query`](https://shopify.dev/docs/api/admin-extensions/latest/api/standard-api#standardapi-propertydetail-query) method in the Standard API or the standard [web fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch). Any `fetch()` calls from your extension to the GraphQL Admin API are automatically authenticated by default. You must declare all required [access scopes](https://shopify.dev/docs/api/usage/access-scopes) in your app's TOML file. **Note:** Direct API can't be used to manage storefront access tokens. ## Query Shopify data directly ##### Using fetch ```tsx import {render} from 'preact'; export default async () => { const products = await getProducts(); render(, document.body); }; async function getProducts() { const res = await fetch('shopify:admin/api/graphql.json', { method: 'POST', body: JSON.stringify({ query: ` query GetProducts { products(first: 5) { nodes { id title } } } `, }), }); const {data} = await res.json(); return data.products.nodes; } function Extension({products}) { return ( {products.map((product) => ( {product.title} ))} ); } ``` ##### Using shopify.query ```tsx import {render} from 'preact'; export default async () => { const { data: {products}, } = await shopify.query( ` query GetProducts { products(first: 5) { nodes { id title } } } `, ); render(, document.body); }; function Extension({products}) { return ( {products.map((product) => ( {product.title} ))} ); } ``` *** ## Custom protocols Custom protocols make it easier to navigate to common locations and construct URLs within your extensions. ### Shopify protocol Use the `shopify:admin` protocol when you want to construct a URL with a root of the Shopify admin. ## Shopify protocol ##### Link to product page ```tsx Link to Product Page; ``` ##### Fetch data ```typescript fetch('shopify:admin/api/graphql.json', { method: 'POST', body: JSON.stringify(simpleProductQuery), }); ``` ### App protocol Use the `app:` protocol to construct a URL for your app. Shopify handles constructing the base URL for your app. This works for both apps rendered in the Shopify admin and standalone apps. ## App protocol ```tsx App settings; ``` ### 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 apps rendered in the Shopify admin and standalone apps. ## Relative URLs ```tsx View reviews; ``` *** ## Limits Keep these limits in mind when you design your App Home UI extension. They apply at deployment, so your bundle won't upload if it exceeds them. * **Compiled bundle size:** 64 KB compressed. Shopify enforces this at deployment to keep load times fast. See [analyze your bundle size](https://shopify.dev/docs/apps/build/app-extensions#analyzing-bundle-size) for help staying under the limit. * **Static asset file size:** Each asset file can be up to 1 MB. * **Static asset bundle:** Your bundle can include up to 500 files, with a total size of 50 MB. * **Targets per app:** Each app can have only one `admin.app.home.render` target. *** ## Testing and deployment After you've built your extension, test it thoroughly and deploy it to production. ### Local testing **Info:** As of API version `2026-04`, you can write unit tests for admin UI extensions using [`@shopify/ui-extensions-tester`](https://github.com/Shopify/ui-extensions/blob/2026-04-rc/packages/ui-extensions-tester/README.md). Check out the [example test suite](https://github.com/Shopify/ui-extensions/tree/2026-04-rc/examples/testing/admin-testing-example) to get started. To run your extension locally during development, start a dev server using [Shopify CLI](https://shopify.dev/docs/api/shopify-cli). The `dev` command creates a preview of your extension on your chosen [dev store](https://shopify.dev/docs/apps/build/dev-dashboard/development-stores). If your extension is built on an app with a backend, then this command also serves your backend locally using a Cloudflare tunnel. The dev server automatically reloads your extension when you make changes to your code, so you can test updates in real-time. ## Start development server ```terminal shopify app dev ``` ### Deployment Deploy your extension to production using [Shopify CLI](https://shopify.dev/docs/api/shopify-cli). The Shopify CLI `deploy` command builds your extension bundle and uploads everything to Shopify. ### Versioning Polaris reference docs follow [Shopify's API versioning policy](https://shopify.dev/docs/api/usage/versioning). Each stable version is supported for a minimum of 12 months. Older versions continue to work, they just won't have dedicated docs on Shopify.dev. [Shopify CLI](https://shopify.dev/docs/api/shopify-cli) already prevents deploys targeting API versions older than 12 months, so we recommend keeping your extensions on a supported version. ***