Contains functions used to manage scopes for your app. This object is returned on authenticated Admin requests.
Provides utilities that apps can use to [manage scopes](https://shopify.dev/docs/apps/build/authentication-authorization/app-installation/manage-access-scopes) for the app using the Admin API.
The Scopes API enables embedded apps and extensions to request merchant consent for access scopes.
Queries Shopify for the scopes for this app on this shop
Requests the merchant to grant the provided scopes for this app on this shop Warning: This method performs a server-side redirect.
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.
The scopes that have been granted on the shop for this app
The optional scopes that the app has declared in its configuration
The required scopes that the app has declared in its configuration
The scopes that have been revoked on the shop for this app
Contains functions used to manage scopes for your app. This object is returned on authenticated Admin requests.
import type { LoaderFunctionArgs } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { authenticate } from "../shopify.server";
import { json } from "@remix-run/node";
export const loader = async ({ request }: LoaderFunctionArgs) => {
const { scopes } = await authenticate.admin(request);
const scopesDetail = await scopes.query();
return json({
hasWriteProducts: scopesDetail.granted.includes('write_products'),
});
};
export default function Index() {
const {hasWriteProducts} = useLoaderData<typeof loader>();
...
}
import type { ActionFunctionArgs } from "@remix-run/node";
import { useFetcher } from "@remix-run/react";
import { authenticate } from "../shopify.server";
import { json } from "@remix-run/node";
// 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 json({});
};
export default function Index() {
const fetcher = useFetcher<typeof action>();
const handleRequest = () => {
fetcher.submit({scopes: ["write_products"]}, {
method: "POST",
});
};
...
}
import type { ActionFunctionArgs } from "@remix-run/node";
import { useFetcher } from "@remix-run/react";
import { authenticate } from "../shopify.server";
import { json } from "@remix-run/node";
// 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 json(revokedResponse);
};
export default function Index() {
const fetcher = useFetcher<typeof action>();
const handleRevoke = () => {
fetcher.submit({scopes: ["write_products"]}, {
method: "POST",
});
};
...
}