For anyone who comes across this.. It looks like there are multiple ways to authenticate your service with Shopify and fulfill the required authentication URLs.. (I wish Shopify would simplify their dev tools and docs to open this up to more devs! Make the APIs, libraries, and docs simple.. You have session tokens, required callbacks, query parameters, component library, and an iframe bridge, how complex does it need to be?)
Here is a straightforward code block for an Express with Next.js server using the @Shopify_77 /shopify-app-express as best as I canunderstand it right now.. I can make this into a template if anyone is interested
src/server/index.ts
import express, { Request, Response } from "express";
import next from "next";
import { ShopifyApp } from "../app";
import { isProdEnvironment, getPort, getHostname } from "../config";
import { webhookHandlers } from "../gdpr";
import { initApiRoutes } from "../api";
async function init() {
const nextApp = next({
dev: !isProdEnvironment(),
hostname: getHostname(),
port: getPort(),
});
const expressApp = express();
expressApp.use(express.json());
expressApp.get(ShopifyApp.config.auth.path, ShopifyApp.auth.begin());
expressApp.get(
ShopifyApp.config.auth.callbackPath,
ShopifyApp.auth.callback(),
ShopifyApp.redirectToShopifyOrAppRoot()
);
expressApp.post(
ShopifyApp.config.webhooks.path,
ShopifyApp.processWebhooks({ webhookHandlers })
);
expressApp.use(
"/api",
ShopifyApp.validateAuthenticatedSession(),
initApiRoutes(express.Router())
);
await nextApp.prepare();
const handler = nextApp.getRequestHandler();
expressApp.get("*", (request: Request, response: Response :disappointed_face: Promise<void> => {
return handler(request, response);
});
const server = expressApp.listen(getPort(), async () => {
console.log(" :rocket: Server ready!");
});
}
init();
src/app/index.ts
import { shopifyApp } from "@shopify/shopify-app-express";
import { restResources } from "@shopify/shopify-api/rest/admin/2023-01";
import {
getHostname,
getPort,
getShopifyApiKey,
getShopifyApiSecretKey,
} from "../config";
import { sessionStorage } from "../db";
import { LATEST_API_VERSION } from "@shopify/shopify-api";
const SHOPIFY_SCOPES = ["read_script_tags", "write_script_tags"];
const SHOPIFY_PROTOCOL = "http";
export const ShopifyApp = shopifyApp({
api: {
apiKey: getShopifyApiKey(),
apiSecretKey: getShopifyApiSecretKey(),
apiVersion: LATEST_API_VERSION,
hostName: `${getHostname()}:${getPort()}`,
hostScheme: SHOPIFY_PROTOCOL,
isEmbeddedApp: true,
restResources,
scopes: SHOPIFY_SCOPES,
},
auth: {
path: "/api/auth",
callbackPath: "/api/auth/callback",
},
webhooks: {
path: "/api/webhooks",
},
sessionStorage,
});