This package makes it easy to use Remix to build Shopify apps.
It builds on the @shopify/shopify-api
package and exposes a shopifyApp
function. You can use shopifyApp
to configure your app and then authenticate requests from Shopify.
Visit the shopify.dev
documentation for more details on the Remix app package.
To use this package, you will need to have:
- a Shopify Partner account and development store
- an app already set up on your partner account
- a JavaScript package manager such as yarn installed
The easiest way to get started with developing Shopify apps is using the Shopify CLI. It helps you set up your environment for developing and publishing your apps and extensions.
We strongly recommend using the CLI to create and manage your Remix apps and extensions! Refer to the getting started documentation to create your app using the Shopify CLI.
This package works with any Remix app. If you're starting an app from scratch, then you can create a brand new Remix app that uses the indie-stack:
npx create-remix@latest --template remix-run/indie-stack
cd ./name-of-your-app
Now let's install this package:
npm install @shopify/shopify-app-remix
Next, you'll need to set up some routes and headers so you can embed your app in the Shopify admin. You can find more details on all the steps described here in the package documentation.
Create app/shopify.server.js
. We will use this file to configure our Shopify app by calling the shopifyApp
function:
// app/shopify.server.js
// Note that you don't need to import the node adapter if you're running on a different runtime.
import '@shopify/shopify-app-remix/server/adapters/node';
// Memory storage makes it easy to set an app up, but should never be used in production.
import {MemorySessionStorage} from '@shopify/shopify-app-session-storage-memory';
import {LATEST_API_VERSION, shopifyApp} from '@shopify/shopify-app-remix';
const shopify = shopifyApp({
apiKey: process.env.SHOPIFY_API_KEY!,
apiSecretKey: process.env.SHOPIFY_API_SECRET!,
appUrl: process.env.SHOPIFY_APP_URL!,
scopes: ['read_products'],
apiVersion: LATEST_API_VERSION,
sessionStorage: new MemorySessionStorage(),
});
export default shopify;
This will require some environment variables. So let's create an .env
file:
SHOPIFY_API_KEY="[Copy from partners dashboard]"
SHOPIFY_API_SECRET="[Copy from partners dashboard]"
SHOPIFY_APP_URL="[The tunnel URL you are using to run your app]"
shopifyApp
needs to reserve a splat route for auth.
It should export a loader that uses shopifyApp
to authenticate:
// app/routes/auth/$.tsx
import {LoaderFunctionArgs} from '@remix-run/node';
import shopify from '~/shopify.server';
export async function loader({request}: LoaderFunctionArgs) {
await shopify.authenticate.admin(request);
return null;
}
Next, set up the AppProvider
component in your app's routes. To do this pass the process.env.SHOPIFY_API_KEY
to the frontend via the loader.
Here is an example:
// root.tsx
import {LoaderFunctionArgs} from '@remix-run/node';
import {AppProvider} from '@shopify/shopify-app-remix/react';
import shopify from '~/shopify.server';
export async function loader({request}: LoaderFunctionArgs) {
await shopify.authenticate.admin(request);
return json({
apiKey: process.env.SHOPIFY_API_KEY,
});
}
export default function App() {
const {apiKey} = useLoaderData<typeof loader>();
return (
<html>
<head>
<Meta />
<Links />
</head>
<body>
<AppProvider apiKey={apiKey} isEmbeddedApp>
<Outlet />
</AppProvider>
</body>
</html>
);
}
This component will set up Polaris and App Bridge. If your app isn't embedded, set the isEmbeddedApp
prop to false
.
Now that your app is ready to respond to requests, it will also need to add the required Content-Security-Policy
header directives, as per our documentation.
To do that, this package provides the shopify.addDocumentResponseHeaders
method.
You should return these headers from any endpoint that renders HTML in your app. Most likely you'll want to add this to every HTML response by updating the entry.server.tsx file:
// entry.server.tsx
import shopify from './shopify.server';
export default function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
) {
shopify.addDocumentResponseHeaders(request, responseHeaders);
/// ..etc
}
To run your app and load it within the Shopify Admin, you need to:
- Update your app's URL in your Partners Dashboard app setup page to
http://localhost:8080
- Update your app's callback URL to
http://localhost:8080/api/auth/callback
in that same page - Go to Test your app in Partners Dashboard and select your development store
Once your app is up and running, you can start using this package to interact with Shopify APIs, webhooks and more.
Here are some guides to help you set up your app:
You can also authenticate requests from surfaces other than the admin.
To see all supported methods, see the shopify.authenticate
object documentation.
If you're experiencing unexpected behaviors when using this package, check our app template's documentation for the solution to common issues.