npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@shopify/shopify-app-remix

v3.4.0

Published

Shopify Remix - to simplify the building of Shopify Apps with Remix

Downloads

92,210

Readme

@shopify/shopify-app-remix

License: MIT npm version

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.

Requirements

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

Getting started

Shopify CLI

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.

Using a plain Remix app

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
}

Running your app

To run your app and load it within the Shopify Admin, you need to:

  1. Update your app's URL in your Partners Dashboard app setup page to http://localhost:8080
  2. Update your app's callback URL to http://localhost:8080/api/auth/callback in that same page
  3. Go to Test your app in Partners Dashboard and select your development store

Next steps

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.

New embedded app authorization strategy

[!TIP] If you are building an embedded app, we strongly recommend using Shopify managed installation with token exchange instead of the legacy authorization code grant flow.

We've introduced a new installation and authorization strategy for embedded apps that eliminates the redirects that were previously necessary. It replaces the existing installation and authorization code grant flow.

This is achieved by using Shopify managed installation to handle automatic app installations and scope updates, while utilizing token exchange to retrieve an access token for authenticated API access.

Enabling this new strategy in your app

[!NOTE] Newly created Remix apps from the template after February 1st 2024 has this feature enabled by default.

  1. Enable Shopify managed installation by configuring your scopes through the Shopify CLI.

  2. Enable the future flag unstable_newEmbeddedAuthStrategy in your app's server configuration file.

    // my-app/app/shopify.server.ts
    const shopify = shopifyApp({
      ...
      isEmbeddedApp: true,
      future: {
        unstable_newEmbeddedAuthStrategy: true,
      }
    })
  3. Enjoy a smoother and faster app installation process.

Learn more about

Testing your app

This package exports a helper method through @shopify/shopify-app-remix/test-helpers to simplify testing: testConfig(). This method can be used to pass dummy configuration properties to shopifyApp().

If your testing framework supports setting environment variables, we recommend using an environment variable, for example "SHOPIFY_TESTING" to replace your default config with the config returned from testConfig().

// my-app/app/shopify.server.ts
import { testConfig } from "@shopify/shopify-app-remix/test-helpers";
...
const config = {
  ...
};

if (process.env.SHOPIFY_TESTING) {
  Object.assign(config, testConfig());
}

const shopify = shopifyApp(config);
...

testConfig() accepts a config object as an optional parameter. The config values provided override the default config values returned by testConfig(). This is especially useful for integration testing and end-to-end testing to ensure shopifyApp() reads the sessions from the development database.

// my-app/app/shopify.server.ts
import { testConfig } from "@shopify/shopify-app-remix/test-helpers";
...
const sessionStorage = new PrismaSessionStorage(prisma);
const config = {
  ...
  sessionStorage,
  ...
};

if (process.env.SHOPIFY_TESTING) {
  Object.assign(config, testConfig());
}

if (process.env.SHOPIFY_TESTING === "e2e") {
  Object.assign(config, testConfig({ sessionStorage }));
}
...

Gotchas / Troubleshooting

If you're experiencing unexpected behaviors when using this package, check our app template's documentation for the solution to common issues.