Creating Custom Admin Pages Using App Bridge UI Components

Table of Contents
Big thanks to our contributors those make our blogs possible.

Our growing community of contributors bring their unique insights from around the world to power our blog. 

Introduction

Building powerful, cohesive admin interfaces is a cornerstone of modern web applications. If you’re developing a Shopify app or any system with an embedded admin experience, App Bridge UI components provide a robust, consistent, and accessible foundation. App Bridge—Shopify’s JavaScript library for embedding apps into the Shopify admin—includes prebuilt React components for modals, resource pickers, navigations, and more. In this post, we’ll walk through how to leverage App Bridge UI components to create custom admin pages that blend seamlessly with the Shopify admin. You’ll learn how to:

  • Set up App Bridge in your project
  • Use core UI components for layout and navigation
  • Implement common patterns like embedded Resource Pickers, Resource Lists, and Modals
  • Manage actions, toasts, and alerts via the App Bridge Action API
  • Structure your code for maintainability and future enhancements

By the end, you’ll have a clear blueprint for crafting admin pages that feel native, guide your users effectively, and adhere to Shopify’s Polaris design system principles.

1. Setting Up App Bridge in Your Project

Before using UI components, you need to initialize App Bridge and connect it to the Shopify admin context.

1.1 Install Dependencies

bashCopyEditnpm install @shopify/app-bridge-react @shopify/app-bridge @shopify/polaris
  • @shopify/app-bridge-react provides React helpers for App Bridge.
  • @shopify/app-bridge is the core library.
  • @shopify/polaris brings in UI styles and components.

1.2 Initialize App Bridge

Create a provider at the root of your admin app:

jsxCopyEdit// App.jsx
import React from 'react';
import {Provider as AppBridgeProvider} from '@shopify/app-bridge-react';
import {AppProvider as PolarisProvider} from '@shopify/polaris';
import {ClientRouter, RoutePropagator} from '@shopify/app-bridge-react';
import {BrowserRouter} from 'react-router-dom';

function App() {
  const config = {
    apiKey: process.env.SHOPIFY_API_KEY,
    shopOrigin: new URLSearchParams(window.location.search).get('shop'),
    forceRedirect: true,
  };

  return (
    <BrowserRouter>
      <AppBridgeProvider config={config}>
        <RoutePropagator />
        <PolarisProvider i18n={{}}>
          <ClientRouter />
          {/* Your routes/components */}
        </PolarisProvider>
      </AppBridgeProvider>
    </BrowserRouter>
  );
}
export default App;
  • Provider: Makes App Bridge and Polaris available throughout.
  • RoutePropagator/ClientRouter: Syncs React Router with App Bridge navigation.

2. Structuring a Custom Admin Page

A typical admin page needs a header, navigation, and main content area. App Bridge UI components help you compose these quickly.

2.1 Page Layout with Polaris

Use Polaris’s Page component to handle spacing, titles, and breadcrumbs:

jsxCopyEditimport {Page, Layout} from '@shopify/polaris';

function OrdersReportPage() {
  return (
    <Page title="Custom Orders Report" breadcrumbs={[{content: 'Home', url: '/'}]}>
      <Layout>
        <Layout.Section>
          {/* Content goes here */}
        </Layout.Section>
      </Layout>
    </Page>
  );
}

2.2 Embedding in Shopify Admin

Ensure this route is mounted under your App Bridge router:

jsxCopyEdit// routes.jsx
import {Route} from 'react-router-dom';
import OrdersReportPage from './OrdersReportPage';

export default function Routes() {
  return (
    <>
      <Route path="/" element={<HomePage />} />
      <Route path="/orders-report" element={<OrdersReportPage />} />
    </>
  );
}

3. Implementing Core App Bridge UI Components

Let’s explore key App Bridge UI components and how to apply them.

3.1 Using Modals for Data Collection

Modals are ideal for collecting filter criteria or confirmations.

jsxCopyEditimport {useState, useCallback} from 'react';
import {Button, Modal, TextContainer} from '@shopify/polaris';

function FilterModal() {
  const [active, setActive] = useState(false);
  const toggleActive = useCallback(() => setActive(a => !a), []);

  return (
    <>
      <Button onClick={toggleActive}>Filter Orders</Button>
      <Modal
        open={active}
        onClose={toggleActive}
        title="Filter Orders"
        primaryAction={{
          content: 'Apply',
          onAction: () => {
            // apply filter logic
            toggleActive();
          },
        }}
      >
        <Modal.Section>
          <TextContainer>
            <p>Select your filter criteria below.</p>
            {/* Inputs go here */}
          </TextContainer>
        </Modal.Section>
      </Modal>
    </>
  );
}

3.2 Resource Picker for Customer or Product Selection

Use App Bridge’s ResourcePicker to let merchants choose Shopify resources:

jsxCopyEditimport {ResourcePicker} from '@shopify/app-bridge-react';

function SelectProducts({open, onSelection, onCancel}) {
  return (
    <ResourcePicker
      resourceType="Product"
      open={open}
      onSelection={resources => {
        onSelection(resources.selection);
      }}
      onCancel={onCancel}
      showVariants={false}
      showHidden={false}
    />
  );
}

Integrate it inside a page:

jsxCopyEditfunction OrdersReportPage() {
  const [pickerOpen, setPickerOpen] = useState(false);

  return (
    <Page title="Custom Orders Report">
      <Button onClick={() => setPickerOpen(true)}>Select Products</Button>
      <SelectProducts
        open={pickerOpen}
        onSelection={items => {
          // update state with selected items
          setPickerOpen(false);
        }}
        onCancel={() => setPickerOpen(false)}
      />
    </Page>
  );
}

3.3 Resource List for Displaying Data

Use Polaris’s ResourceList to show selected items:

jsxCopyEditimport {ResourceList, Avatar, TextStyle} from '@shopify/polaris';

function ProductsList({items}) {
  return (
    <ResourceList
      resourceName={{singular: 'product', plural: 'products'}}
      items={items}
      renderItem={item => {
        const {id, title, image} = item;
        return (
          <ResourceList.Item id={id} media={<Avatar source={image.src} />}>
            <h3>
              <TextStyle variation="strong">{title}</TextStyle>
            </h3>
          </ResourceList.Item>
        );
      }}
    />
  );
}

Combine selection and display:

jsxCopyEditfunction OrdersReportPage() {
  const [selectedProducts, setSelectedProducts] = useState([]);

  return (
    <Page title="Custom Orders Report">
      {/* ...ResourcePicker code... */}
      <ProductsList items={selectedProducts} />
    </Page>
  );
}

4. Managing App Bridge Actions: Toasts, Redirects, and More

Beyond UI, App Bridge’s Action API lets you push toasts, handle redirections, and interact with the host.

4.1 Displaying Toast Messages

jsxCopyEditimport {useAppBridge} from '@shopify/app-bridge-react';
import {Toast} from '@shopify/app-bridge/actions';

function showToast(app) {
  const toastOptions = {message: 'Report generated successfully', duration: 3000};
  const toast = Toast.create(app, toastOptions);
  toast.dispatch(Toast.Action.SHOW);
}

// In component:
const app = useAppBridge();
<Button onClick={() => showToast(app)}>Generate Report</Button>

4.2 Redirecting Within the Admin

jsxCopyEditimport {Redirect} from '@shopify/app-bridge/actions';

function redirectToHome(app) {
  const redirect = Redirect.create(app);
  redirect.dispatch(Redirect.Action.APP, '/');
}

// Usage:
<Button onClick={() => redirectToHome(app)}>Back to Dashboard</Button>

5. Best Practices and Architectural Tips

5.1 Encapsulate App Bridge Logic

Create custom hooks for common actions:

jsxCopyEdit// useAppBridgeActions.js
import {useAppBridge} from '@shopify/app-bridge-react';
import {Toast, Redirect} from '@shopify/app-bridge/actions';

export function useToasts() {
  const app = useAppBridge();
  return message => {
    Toast.create(app, {message, duration: 3000}).dispatch(Toast.Action.SHOW);
  };
}

export function useRedirect() {
  const app = useAppBridge();
  return path => {
    Redirect.create(app).dispatch(Redirect.Action.APP, path);
  };
}

5.2 Lazy‑Load Heavy Components

To reduce bundle size:

jsxCopyEditimport dynamic from 'next/dynamic';

const ResourcePicker = dynamic(() => import('@shopify/app-bridge-react').then(mod => mod.ResourcePicker), {
  ssr: false,
});

5.3 Theming and Styling

Leverage Polaris tokens for consistent spacing, typography, and colors. Override less frequently, and always test on both light and dark admin themes.

Conclusion

By combining App Bridge’s embedding framework with Polaris UI components, you can create custom admin pages that fit natively within Shopify’s admin interface. From setting up App Bridge and structuring your layout to integrating Resource Pickers, modals, toasts, and redirects, the tools you need are at your fingertips. Remember to encapsulate repetitive logic in custom hooks, lazy‑load large components, and adhere to Polaris styling guidelines. With this approach, your embedded app will feel intuitive, performant, and professionally polished—delighting merchants and unlocking new possibilities for your application’s user experience.

Let's connect on TikTok

Join our newsletter to stay updated

Sydney Based Software Solutions Professional who is crafting exceptional systems and applications to solve a diverse range of problems for the past 10 years.

Share the Post

Related Posts