Scopesobject
Contains functions used to manage scopes for your app.
This object is returned on authenticated Admin requests.
Anchor to scopesscopes
Provides utilities that apps can use to manage scopes for the app using the Admin API.
- Anchor to queryquery() => Promise<>required
Queries Shopify for the scopes for this app on this shop
- Anchor to requestrequest(scopes: string[]) => Promise<void>required
Requests the merchant to grant the provided scopes for this app on this shop
Warning: This method performs a server-side redirect.
- Anchor to revokerevoke(scopes: string[]) => Promise<>required
Revokes the provided scopes from this app on this shop
Warning: This method throws an error if the provided optional scopes contains a required scope.
ScopesApiContext
The Scopes API enables embedded apps and extensions to request merchant consent for access scopes.
- query
Queries Shopify for the scopes for this app on this shop
() => Promise<ScopesDetail>
- request
Requests the merchant to grant the provided scopes for this app on this shop Warning: This method performs a server-side redirect.
(scopes: string[]) => Promise<void>
- revoke
Revokes the provided scopes from this app on this shop Warning: This method throws an [error](https://shopify.dev/docs/api/admin-graphql/unstable/objects/AppRevokeAccessScopesAppRevokeScopeError) if the provided optional scopes contains a required scope.
(scopes: string[]) => Promise<ScopesRevokeResponse>
export interface ScopesApiContext {
/**
* Queries Shopify for the scopes for this app on this shop
*
* @returns {ScopesDetail} The scope details.
*
* @example
* <caption>Query for granted scopes.</caption>
* <description>Call `scopes.query` to get scope details.</description>
* ```ts
* // /app._index.tsx
* import type { LoaderFunctionArgs } from "react-router";
* import { useLoaderData } from "react-router";
* import { authenticate } from "../shopify.server";
* import { json } from "react-router";
*
* export const loader = async ({ request }: LoaderFunctionArgs) => {
* const { scopes } = await authenticate.admin(request);
*
* const scopesDetail = await scopes.query();
*
* return ({
* hasWriteProducts: scopesDetail.granted.includes('write_products'),
* });
* };
*
* export default function Index() {
* const {hasWriteProducts} = useLoaderData<typeof loader>();
*
* ...
* }
* ```
*/
query: () => Promise<ScopesDetail>;
/**
* Requests the merchant to grant the provided scopes for this app on this shop
*
* Warning: This method performs a server-side redirect.
*
* @example
* <caption>Request consent from the merchant to grant the provided scopes for this app.</caption>
* <description>Call `scopes.request` to request optional scopes.</description>
* ```ts
* // /app/routes/app.request.tsx
* import type { ActionFunctionArgs } from "react-router";
* import { useFetcher } from "react-router";
* import { authenticate } from "../shopify.server";
* import { json } from "react-router";
*
* // Example of an action to POST a request to for optional scopes
* export const action = async ({ request }: ActionFunctionArgs) => {
* const { scopes } = await authenticate.admin(request);
*
* const body = await request.formData();
* const scopesToRequest = body.getAll("scopes") as string[];
*
* // If the scopes are not already granted, a full page redirect to the request URL occurs
* await scopes.request(scopesToRequest);
* // otherwise return an empty response
* return ({});
* };
*
* export default function Index() {
* const fetcher = useFetcher<typeof action>();
*
* const handleRequest = () => {
* fetcher.submit({scopes: ["write_products"]}, {
* method: "POST",
* });
* };
*
* ...
* }
* ```
*/
request: (scopes: Scope[]) => Promise<void>;
/**
* Revokes the provided scopes from this app on this shop
*
* Warning: This method throws an [error](https://shopify.dev/docs/api/admin-graphql/unstable/objects/AppRevokeAccessScopesAppRevokeScopeError) if the provided optional scopes contains a required scope.
*
* @example
* <caption>Revoke optional scopes.</caption>
* <description>Call `scopes.revoke` to revoke optional scopes.</description>
* ```ts
* // /app._index.tsx
* import type { ActionFunctionArgs } from "react-router";
* import { useFetcher } from "react-router";
* import { authenticate } from "../shopify.server";
* import { json } from "react-router";
*
* // Example of an action to POST optional scopes to revoke
* export const action = async ({ request }: ActionFunctionArgs) => {
* const { scopes } = await authenticate.admin(request);
*
* const body = await request.formData();
* const scopesToRevoke = body.getAll("scopes") as string[];
*
* const revokedResponse = await scopes.revoke(scopesToRevoke);
*
* return (revokedResponse);
* };
*
* export default function Index() {
* const fetcher = useFetcher<typeof action>();
*
* const handleRevoke = () => {
* fetcher.submit({scopes: ["write_products"]}, {
* method: "POST",
* });
* };
*
* ...
* }
* ```
*/
revoke: (scopes: Scope[]) => Promise<ScopesRevokeResponse>;
}
ScopesDetail
- granted
The scopes that have been granted on the shop for this app
string[]
- optional
The optional scopes that the app has declared in its configuration
string[]
- required
The required scopes that the app has declared in its configuration
string[]
export interface ScopesDetail {
/**
* The scopes that have been granted on the shop for this app
*/
granted: Scope[];
/**
* The required scopes that the app has declared in its configuration
*/
required: Scope[];
/**
* The optional scopes that the app has declared in its configuration
*/
optional: Scope[];
}
ScopesRevokeResponse
- revoked
The scopes that have been revoked on the shop for this app
string[]
export interface ScopesRevokeResponse {
/**
* The scopes that have been revoked on the shop for this app
*/
revoked: Scope[];
}
Anchor to examplesExamples
Anchor to example-query-for-granted-scopesQuery for granted scopes
Call scopes.query
to get scope details.
Query for granted scopes
/app._index.tsx
examples
Query for granted scopes
description
Call `scopes.query` to get scope details.
/app._index.tsx
import type { LoaderFunctionArgs } from "react-router"; import { useLoaderData } from "react-router"; import { authenticate } from "../shopify.server"; import { json } from "react-router"; export const loader = async ({ request }: LoaderFunctionArgs) => { const { scopes } = await authenticate.admin(request); const scopesDetail = await scopes.query(); return ({ hasWriteProducts: scopesDetail.granted.includes('write_products'), }); }; export default function Index() { const {hasWriteProducts} = useLoaderData<typeof loader>(); ... }
Anchor to example-requestrequest
Anchor to example-request-consent-from-the-merchant-to-grant-the-provided-scopes-for-this-appRequest consent from the merchant to grant the provided scopes for this app
Call scopes.request
to request optional scopes.
Request consent from the merchant to grant the provided scopes for this app
/app/routes/app.request.tsx
examples
Request consent from the merchant to grant the provided scopes for this app
description
Call `scopes.request` to request optional scopes.
/app/routes/app.request.tsx
import type { ActionFunctionArgs } from "react-router"; import { useFetcher } from "react-router"; import { authenticate } from "../shopify.server"; import { json } from "react-router"; // Example of an action to POST a request to for optional scopes export const action = async ({ request }: ActionFunctionArgs) => { const { scopes } = await authenticate.admin(request); const body = await request.formData(); const scopesToRequest = body.getAll("scopes") as string[]; // If the scopes are not already granted, a full page redirect to the request URL occurs await scopes.request(scopesToRequest); // otherwise return an empty response return ({}); }; export default function Index() { const fetcher = useFetcher<typeof action>(); const handleRequest = () => { fetcher.submit({scopes: ["write_products"]}, { method: "POST", }); }; ... }
Anchor to example-revokerevoke
Anchor to example-revoke-optional-scopesRevoke optional scopes
Call scopes.revoke
to revoke optional scopes.
Revoke optional scopes
/app._index.tsx
examples
Revoke optional scopes
description
Call `scopes.revoke` to revoke optional scopes.
/app._index.tsx
import type { ActionFunctionArgs } from "react-router"; import { useFetcher } from "react-router"; import { authenticate } from "../shopify.server"; import { json } from "react-router"; // Example of an action to POST optional scopes to revoke export const action = async ({ request }: ActionFunctionArgs) => { const { scopes } = await authenticate.admin(request); const body = await request.formData(); const scopesToRevoke = body.getAll("scopes") as string[]; const revokedResponse = await scopes.revoke(scopesToRevoke); return (revokedResponse); }; export default function Index() { const fetcher = useFetcher<typeof action>(); const handleRevoke = () => { fetcher.submit({scopes: ["write_products"]}, { method: "POST", }); }; ... }