Installation
npm install @shopify/shopify-app-react-router
shopifyApp()
Creates an object your app will use to interact with Shopify in a React Router application.
Function Signature
function shopifyApp <
Config extends AppConfigArg < Storage , Future >,
Storage extends SessionStorage ,
Future extends FutureFlagOptions = Config [ 'future' ]
>( appConfig : Readonly < Config >) : ShopifyApp < Config >
Configuration
Configuration options for your Shopify app Your app’s API key from the Shopify Partner Dashboard
Your app’s API secret key from the Shopify Partner Dashboard
The access scopes your app needs
The URL your app is running on. For development, this is typically a tunnel URL. For production, this is your production URL.
The version of Shopify’s Admin API to use
An adapter for storing sessions in your database of choice. Optional for apps created in the Shopify Admin.
Whether your app uses online or offline tokens. If true, both online and offline tokens will be saved.
distribution
AppDistribution
default: "AppDistribution.AppStore"
How your app is distributed:
AppDistribution.AppStore - Public apps in the Shopify App Store
AppDistribution.SingleMerchant - Custom apps in Partner Dashboard
AppDistribution.ShopifyAdmin - Apps managed in merchant’s Shopify Admin
A path that Shopify can reserve for auth-related endpoints. Must match a $ route in your React Router app.
Shop-specific webhook configuration. For most cases, define app-specific webhooks in shopify.app.toml instead.
Lifecycle hooks for your app afterAuth
(options: AfterAuthOptions) => void | Promise<void>
Function called after a merchant installs your app
billing
BillingConfigWithLineItems
Billing configuration using line items format for complex billing structures
Opt-in flags for upcoming breaking changes and new features
Return Value
Returns a ShopifyApp object with the following properties:
The SessionStorage instance you passed in as a config option
Adds required Content Security Policy headers for Shopify apps to the given Headers object
registerWebhooks
(options: RegisterWebhooksOptions) => Promise<RegisterReturn | void>
Register shop-specific webhook subscriptions using the Admin GraphQL API
Methods for authenticating requests from different Shopify surfaces admin
(request: Request) => Promise<AdminContext>
Authenticate admin requests from your app’s UI or admin extensions Returns: AdminContext with:
session: Session - The session for the user who made the request
admin: AdminApiContext - Methods for interacting with the GraphQL Admin API
billing: BillingContext - Billing methods based on your config
cors: EnsureCORSFunction - Helper to set CORS headers
sessionToken: JwtPayload - Decoded session token (embedded apps only)
redirect: RedirectFunction - Redirect helper for embedded apps
scopes: ScopesApiContext - Methods to manage scopes
flow
(request: Request) => Promise<FlowContext>
Authenticate Flow extension requests Returns: FlowContext with:
admin: AdminApiContext - Admin API access
session: Session - The session
payload: object - The Flow request payload
fulfillmentService
(request: Request) => Promise<FulfillmentServiceContext>
Authenticate fulfillment service requests Returns: FulfillmentServiceContext with:
admin: AdminApiContext - Admin API access
session: Session - The session
pos
(request: Request) => Promise<POSContext>
Authenticate POS UI extension requests Returns: POSContext with:
sessionToken: JwtPayload - The decoded session token
cors: EnsureCORSFunction - Helper to set CORS headers
Authenticate public requests from various surfaces Methods:
checkout(request: Request) - Authenticate checkout extension requests
customerAccount(request: Request) - Authenticate customer account requests
appProxy(request: Request) - Authenticate app proxy requests
webhook
(request: Request) => Promise<WebhookContext>
Authenticate Shopify webhook requests Returns: WebhookContext with:
topic: string - The webhook topic
shop: string - The shop domain
session: Session | undefined - The session (may be undefined if app is uninstalled)
payload: object - The webhook payload
Methods for creating contexts from non-Shopify requests admin
(shop: string) => Promise<UnauthenticatedAdminContext>
Create an admin context for a specific shop without authentication Returns: UnauthenticatedAdminContext with:
admin: AdminApiContext - Admin API access
storefront
(shop: string) => Promise<UnauthenticatedStorefrontContext>
Create a storefront context for a specific shop Returns: UnauthenticatedStorefrontContext with:
storefront: StorefrontApiContext - Storefront API access
login
(request: Request) => Promise<LoginError | never>
Log a merchant in and redirect them to the app root. Not available when distribution is AppDistribution.ShopifyAdmin. Returns: LoginError object with validation errors, or redirects on success
Example Usage
Basic Setup
Loader Authentication
Webhook Handler
POS Extension
AfterAuth Hook with Billing
// app/shopify.server.ts
import { shopifyApp } from "@shopify/shopify-app-react-router/server" ;
import { PrismaSessionStorage } from "@shopify/shopify-app-session-storage-prisma" ;
import { ApiVersion } from "@shopify/shopify-api" ;
import prisma from "~/db.server" ;
const shopify = shopifyApp ({
apiKey: process . env . SHOPIFY_API_KEY ! ,
apiSecretKey: process . env . SHOPIFY_API_SECRET ! ,
scopes: process . env . SCOPES ?. split ( "," ) ! ,
appUrl: process . env . SHOPIFY_APP_URL ! ,
apiVersion: ApiVersion . October24 ,
sessionStorage: new PrismaSessionStorage ( prisma ),
});
export default shopify ;
export const authenticate = shopify . authenticate ;
Key Differences from Remix Adapter
The React Router adapter is optimized for React Router v7+ and includes:
Token Exchange by Default : Uses the token exchange authentication strategy by default (vs. auth code flow in Remix)
POS Authentication : Includes authenticate.pos() for POS UI extension support
Line Item Billing : Supports the newer line item billing format for complex billing structures
React Router Integration : Built for React Router v7+ with appropriate type imports from react-router
Exported Types
export {
LogSeverity ,
DeliveryMethod ,
BillingInterval ,
BillingReplacementBehavior ,
ApiVersion ,
Session ,
AppDistribution ,
LoginErrorType ,
} from "@shopify/shopify-app-react-router/server" ;
export type {
JwtPayload ,
ShopifyApp ,
LoginError ,
} from "@shopify/shopify-app-react-router/server" ;
See Also