Unauthenticated adminobject
Allows interacting with the Admin API when working outside of Shopify requests. This enables apps to integrate with 3rd party services and perform background tasks.
This function doesn't perform any validation and shouldn't rely on raw user input.
When using this function, consider the following:
Background tasks
Apps should ensure that the shop domain is authenticated when enqueueing jobs.
3rd party service requests
Apps must obtain the shop domain from the 3rd party service in a secure way.
Creates an unauthenticated Admin context.
- Anchor to shopshopstringrequired
GetUnauthenticatedAdminContext
- shop
string
Promise<UnauthenticatedAdminContext>
(
shop: string,
) => Promise<UnauthenticatedAdminContext>
UnauthenticatedAdminContext
- admin
Methods for interacting with the GraphQL Admin API for the given store.
AdminApiContext
- session
The session for the given shop. This comes from the session storage which `shopifyApp` uses to store sessions in your database of choice. This will always be an offline session. You can use to get shop-specific data.
Session
export interface UnauthenticatedAdminContext {
/**
* The session for the given shop.
*
* This comes from the session storage which `shopifyApp` uses to store sessions in your database of choice.
*
* This will always be an offline session. You can use to get shop-specific data.
*
* @example
* <caption>Using the offline session.</caption>
* <description>Get your app's shop-specific data using the returned offline `session` object.</description>
* ```ts
* // /app/routes/**\/*.ts
* import { LoaderFunctionArgs, json } from "react-router";
* import { unauthenticated } from "../shopify.server";
* import { getMyAppData } from "~/db/model.server";
*
* export const loader = async ({ request }: LoaderFunctionArgs) => {
* const shop = getShopFromExternalRequest(request);
* const { session } = await unauthenticated.admin(shop);
* return (await getMyAppData({shop: session.shop}));
* };
* ```
*/
session: Session;
/**
* Methods for interacting with the GraphQL Admin API for the given store.
*
* @example
* <caption>Querying the GraphQL API.</caption>
* <description>Use `admin.graphql` to make query / mutation requests.</description>
* ```ts
* // /app/routes/**\/*.ts
* import { ActionFunctionArgs } from "react-router";
* import { unauthenticated } from "../shopify.server";
*
* export async function action({ request }: ActionFunctionArgs) {
* const shop = getShopFromExternalRequest(request);
* const { admin } = await unauthenticated.admin(shop);
*
* const response = await admin.graphql(
* `#graphql
* mutation populateProduct($input: ProductInput!) {
* productCreate(input: $input) {
* product {
* id
* }
* }
* }`,
* { variables: { input: { title: "Product Name" } } }
* );
*
* const productData = await response.json();
* return ({ data: productData.data });
* }
* ```
*
* ```ts
* // /app/shopify.server.ts
* import { shopifyApp } from "@shopify/shopify-app-react-router/server";
*
* const shopify = shopifyApp({
* // ...etc
* });
* export default shopify;
* export const unauthenticated = shopify.unauthenticated;
* ```
*/
admin: AdminApiContext;
}
AdminApiContext
- graphql
Methods for interacting with the Shopify Admin GraphQL API
GraphQLClient<AdminOperations>
export interface AdminApiContext {
/**
* Methods for interacting with the Shopify Admin GraphQL API
*
* {@link https://shopify.dev/docs/api/admin-graphql}
* {@link https://github.com/Shopify/shopify-app-js/blob/main/packages/apps/shopify-api/docs/reference/clients/Graphql.md}
*
* @example
* <caption>Querying the GraphQL API.</caption>
* <description>Use `admin.graphql` to make query / mutation requests.</description>
* ```ts
* // /app/routes/**\/*.ts
* import { ActionFunctionArgs } from "react-router";
* import { authenticate } from "../shopify.server";
*
* export const action = async ({ request }: ActionFunctionArgs) => {
* const { admin } = await authenticate.admin(request);
*
* const response = await admin.graphql(
* `#graphql
* mutation populateProduct($input: ProductInput!) {
* productCreate(input: $input) {
* product {
* id
* }
* }
* }`,
* {
* variables: {
* input: { title: "Product Name" },
* },
* },
* );
*
* const productData = await response.json();
* return ({
* productId: productData.data?.productCreate?.product?.id,
* });
* }
* ```
*
* ```ts
* // /app/shopify.server.ts
* import { shopifyApp } from "@shopify/shopify-app-react-router/server";
*
* const shopify = shopifyApp({
* // ...
* });
* export default shopify;
* export const authenticate = shopify.authenticate;
* ```
*
* @example
* <caption>Handling GraphQL errors.</caption>
* <description>Catch `GraphqlQueryError` errors to see error messages from the API.</description>
* ```ts
* // /app/routes/**\/*.ts
* import { ActionFunctionArgs } from "react-router";
* import { authenticate } from "../shopify.server";
*
* export const action = async ({ request }: ActionFunctionArgs) => {
* const { admin } = await authenticate.admin(request);
*
* try {
* const response = await admin.graphql(
* `#graphql
* query incorrectQuery {
* products(first: 10) {
* nodes {
* not_a_field
* }
* }
* }`,
* );
*
* return ({ data: await response.json() });
* } catch (error) {
* if (error instanceof GraphqlQueryError) {
* // error.body.errors:
* // { graphQLErrors: [
* // { message: "Field 'not_a_field' doesn't exist on type 'Product'" }
* // ] }
* return ({ errors: error.body?.errors }, { status: 500 });
* }
* return ({ message: "An error occurred" }, { status: 500 });
* }
* }
* ```
*
* ```ts
* // /app/shopify.server.ts
* import { shopifyApp } from "@shopify/shopify-app-react-router/server";
*
* const shopify = shopifyApp({
* // ...
* });
* export default shopify;
* export const authenticate = shopify.authenticate;
* ```
*/
graphql: GraphQLClient<AdminOperations>;
}
GraphQLClient
- query
Operation extends keyof Operations
- options
GraphQLQueryOptions<Operation, Operations>
interface Promise<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
/**
* Attaches a callback for only the rejection of the Promise.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of the callback.
*/
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;
}, interface Promise<T> {}, Promise: PromiseConstructor, interface Promise<T> {
readonly [Symbol.toStringTag]: string;
}, interface Promise<T> {
/**
* Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The
* resolved value cannot be modified from the callback.
* @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected).
* @returns A Promise for the completion of the callback.
*/
finally(onfinally?: (() => void) | undefined | null): Promise<T>;
}
<
Operation extends keyof Operations,
>(
query: Operation,
options?: GraphQLQueryOptions<Operation, Operations>,
) => Promise<GraphQLResponse<Operation, Operations>>
GraphQLQueryOptions
- apiVersion
The version of the API to use for the request.
ApiVersion
- headers
Additional headers to include in the request.
Record<string, any>
- signal
An optional AbortSignal to cancel the request.
AbortSignal
- tries
The total number of times to try the request if it fails.
number
- variables
The variables to pass to the operation.
ApiClientRequestOptions<Operation, Operations>["variables"]
export interface GraphQLQueryOptions<
Operation extends keyof Operations,
Operations extends AllOperations,
> {
/**
* The variables to pass to the operation.
*/
variables?: ApiClientRequestOptions<Operation, Operations>['variables'];
/**
* The version of the API to use for the request.
*/
apiVersion?: ApiVersion;
/**
* Additional headers to include in the request.
*/
headers?: Record<string, any>;
/**
* The total number of times to try the request if it fails.
*/
tries?: number;
/**
* An optional AbortSignal to cancel the request.
*/
signal?: AbortSignal;
}
Anchor to examplesExamples
Anchor to example-querying-the-graphql-apiQuerying the GraphQL API
Use admin.graphql
to make query / mutation requests.
Querying the GraphQL API
examples
Querying the GraphQL API
description
Use `admin.graphql` to make query / mutation requests.
/app/routes/**\/*.ts
import { ActionFunctionArgs } from "react-router"; import { unauthenticated } from "../shopify.server"; export async function action({ request }: ActionFunctionArgs) { const shop = getShopFromExternalRequest(request); const { admin } = await unauthenticated.admin(shop); const response = await admin.graphql( `#graphql mutation populateProduct($input: ProductInput!) { productCreate(input: $input) { product { id } } }`, { variables: { input: { title: "Product Name" } } } ); const productData = await response.json(); return ({ data: productData.data }); }
/app/shopify.server.ts
import { shopifyApp } from "@shopify/shopify-app-react-router/server"; const shopify = shopifyApp({ // ...etc }); export default shopify; export const unauthenticated = shopify.unauthenticated;
Anchor to example-sessionsession
Anchor to example-using-the-offline-sessionUsing the offline session
Get your app's shop-specific data using the returned offline session
object.
Using the offline session
/app/routes/**\/*.ts
examples
Using the offline session
description
Get your app's shop-specific data using the returned offline `session` object.
/app/routes/**\/*.ts
import { LoaderFunctionArgs, json } from "react-router"; import { unauthenticated } from "../shopify.server"; import { getMyAppData } from "~/db/model.server"; export const loader = async ({ request }: LoaderFunctionArgs) => { const shop = getShopFromExternalRequest(request); const { session } = await unauthenticated.admin(shop); return (await getMyAppData({shop: session.shop})); };