Skip to main content

Interacting with Shopify Admin

Once you set up your backend, you can use the authenticate.admin function to integrate your app with Shopify Admin.

This function works for both embedded and non-embedded apps, and ensures the app is installed on the current store.

It returns a context with functions to enable loaders and actions to respond to any requests made by or in Shopify Admin.

This page goes over the basics of authenticating those requests, and some of the things you can do with it, like querying the Admin API.


Anchor to authAuthenticating requests

To authenticate admin requests you can call authenticate.admin(request) in a loader or an action.

If there's a session for this user, then this loader will return null. If there's no session for the user, then the loader will throw the appropriate redirect Response.

Tip

If you are authenticating more than one route, then we recommend using Remix layout routes to automatically authenticate them.

/app/routes/**/*.tsx

import {LoaderFunction, ActionFunction} from '@remix-run/node';

import {authenticate} from '~/shopify.server';

export const loader: LoaderFunction = async ({request}) => {
await authenticate.admin(request);

// App logic

return null;
};

export const action: ActionFunction = async ({request}) => {
await authenticate.admin(request);

// App logic

return null;
};

The OAuth process can't happen inside the admin iframe, and this package is capable of detecting that scenario and properly redirecting using the Remix ErrorBoundary export to set the correct headers for App Bridge.

Use the abstractions provided by this package in your authenticated routes, to automatically set up the error and headers boundaries to redirect outside the iframe when needed.

Tip

You can also add this to a Remix layout if you want to authenticate more than one route, but make sure to call the Shopify boundary methods whenever you need to add your own exports.

/app/routes/**/*.tsx

import {useRouteError} from '@remix-run/react';
import {boundary} from '@shopify/shopify-app-remix';

export function ErrorBoundary() {
return boundary.error(useRouteError());
}

export const headers = (headersArgs) => {
return boundary.headers(headersArgs);
};

Anchor to cors-authAuthenticating cross-origin admin requests

If your Remix server is authenticating an admin extension, then a request from the extension to Remix will be cross-origin.

Here authenticate.admin provides a cors function to add the required cross-origin headers.

/app/routes/**/*.tsx

import {json, LoaderFunction} from '@remix-run/node';

import {authenticate} from '~/shopify.server';

export const loader: LoaderFunction = async ({request}) => {
const {cors} = await authenticate.admin(request);

// App logic

return cors(json({my: 'data'}));
};

Anchor to graphql-apiUsing the GraphQL API

Once a request is authenticated, authenticate.admin will return an admin object that contains a GraphQL client that can interact with the GraphQL Admin API.

/app/routes/**/*.tsx

import {ActionFunction, json} from '@remix-run/node';

import {authenticate} from '../shopify.server';

export const action: ActionFunction = async ({request}) => {
const {admin} = await authenticate.admin(request);

const response = await admin.graphql(
`#graphql
mutation populateProduct($input: ProductInput!) {
productCreate(input: $input) {
product {
id
}
}
}`,
{
variables: {
input: {
title: 'New product',
variants: [{price: 100}],
},
},
},
);
const parsedResponse = await response.json();

return json({data: parsedResponse.data});
};

Anchor to rest-apiUsing the REST API

Once a request is authenticated, authenticate.admin will return an admin object that contains a REST client that can interact with the REST Admin API.

You can also import a set of resource classes from the @shopify/shopify-api package, which is included in @shopify/shopify-app-remix.

These classes map to the individual REST endpoints, and will be returned under admin.rest.resources.

Interacting with the REST API

import {shopifyApp} from '@shopify/shopify-app-remix/server';
import {restResources} from '@shopify/shopify-api/rest/admin/2023-07';

const shopify = shopifyApp({
restResources,
// ...etc
});

export const authenticate = shopify.authenticate;