Building with Remix

Integrate your Shopify Remix App with Mantle

This guide will walk you through creating a Shopify app with Mantle integration to manage customer data and billing. The complete code for this sample app is available at https://github.com/Hey-Mantle/mantle-shop-example.

1. Create your Shopify app

Start by setting up a standard Shopify Remix app:

  1. Follow the official guide at https://shopify.dev/docs/apps/getting-started/create
  2. Create an empty .env file in your project root if it doesn't already exist

2. Add the app to Mantle

  1. In your Mantle dashboard, click Add app
  2. Once added, go to Settings for the app and create a new API key
  3. Add these environment variables to your .env file:
    MANTLE_APP_ID=your_app_id_here
    MANTLE_API_KEY=your_api_key_here

3. Add Mantle helper library

Install the Mantle Polaris library, which includes React components and the Mantle client:

npm install @heymantle/polaris

This package includes both @heymantle/react and @heymantle/client as dependencies.

4. Add mantleApiToken to Session model

Store the Mantle customer API token in your database by updating the Session model:

  1. Open prisma/schema.prisma
  2. Add the mantleApiToken field to the Session model:
model Session {
  id          String    @id
  shop        String
  state       String
  isOnline    Boolean   @default(false)
  scope       String?
  expires     DateTime?
  accessToken String
  userId      BigInt?
  mantleApiToken String?
}
  1. Run the migration:
npm run prisma migrate dev -- --name add-mantle-api-token-to-session

5. Identify shops to Mantle when they install the app

Update app/shopify.server.js to identify shops to Mantle during installation:

  1. Import the Mantle client at the top of the file:
import { MantleClient } from "@heymantle/client"
  1. Add the identify request to the afterAuth function:
afterAuth: async ({ session, admin }) => {
  shopify.registerWebhooks({ session });

  // fetch current shop and identify to Mantle
  const response = await admin.graphql(
    `#graphql
      query getShop {
        shop {
          id
        }
      }`,
  );
  const responseJson = await response.json();
  const shop = responseJson.data?.shop;
  const mantleClient = new MantleClient({
    appId: process.env.MANTLE_APP_ID,
    apiKey: process.env.MANTLE_APP_API_KEY,
  });
  const identifyResponse = await mantleClient.identify({
    platform: "shopify",
    platformId: shop.id,
    myshopifyDomain: session.shop,
    accessToken: session.accessToken,
  });
  const mantleApiToken = identifyResponse?.apiToken;
  await prisma.session.update({
    where: { id: session.id },
    data: { mantleApiToken },
  });
}

6. Add MantleProvider context to your frontend

Update app/routes/app.jsx to include the MantleProvider component:

  1. Modify the loader function to include the Mantle API token:
export const loader = async ({ request }) => {
  const { session: _session } = await authenticate.admin(request);

  const { mantleApiToken } = await prisma.session.findUnique({
    where: { id: _session.id },
  });

  return json({
    apiKey: process.env.SHOPIFY_API_KEY || "",
    mantleAppId: process.env.MANTLE_APP_ID || "",
    mantleApiToken,
  });
};
  1. Add the MantleProvider component to wrap your app content:
import { MantleProvider } from "@heymantle/react";

export default function App() {
  const { apiKey, mantleAppId, mantleApiToken } = useLoaderData();

  return (
    <AppProvider isEmbeddedApp apiKey={apiKey}>
      <MantleProvider
        appId={mantleAppId}
        customerApiToken={mantleApiToken}
      >
        <NavMenu>
          <Link to="/app" rel="home">
            Home
          </Link>
          <Link to="/app/additional">Additional page</Link>
          <Link to="/app/plans">Plans</Link>
        </NavMenu>
        <Outlet />
      </MantleProvider>
    </AppProvider>
  );
}

7. Add plans page

  1. First, create some plans in your Mantle dashboard:

    • Go to your app in the Mantle dashboard
    • Navigate to Plans
    • Click Add plan and create at least one plan
  2. Configure your Shopify app for public distribution:

  3. Create a new file app/routes/app.plans.jsx with the following content:

import { Layout, Page } from "@shopify/polaris";
import { TitleBar } from "@shopify/app-bridge-react";
import { PlanCardStack, PlanCardType } from "@heymantle/polaris";
import { useMantle } from "@heymantle/react";

export default function PlansPage() {
  const { customer, plans, client } = useMantle();

  const handleSelectPlan = async ({ plan, discount }) => {
    const subscription = await client.subscribe({
      planId: plan.id,
      discountId: discount?.id,
      returnUrl: "/app/plans",
    });
    const url = subscription.confirmationUrl;
    open(url, "_top");
  };

  return (
    <Page>
      <TitleBar title="Select a plan" />
      <Layout>
        <Layout.Section>
          <PlanCardStack
            cardType={PlanCardType.Highlighted}
            customer={customer}
            plans={plans}
            onSelectPlan={handleSelectPlan}
          />
        </Layout.Section>
      </Layout>
    </Page>
  );
}

Wrapping it up

You now have a Shopify app with Mantle integrated and a functional plans page! Your app can now:

  • Identify customers to Mantle during installation
  • Display available plans to customers
  • Allow customers to subscribe to plans
  • Track customer data and subscriptions

This integration enables you to manage billing, track usage, and analyze customer behavior all through the Mantle dashboard. If you have questions or need assistance, reach out to the Mantle team at [email protected].


Did this page help you?