Loading...
Loading...
Guide for developing Shopify apps using the official Shopify Remix Template. Covers structure, authentication, API usage, and deployment.
npx skill4agent add toilahuongg/shopify-agents-kit shopify-remix-templategit clone https://github.com/Shopify/shopify-app-template-remix.gitapp/routes/app._index.tsxapp.tsxwebhooks.tsxshopify.server.tsdb.server.tsmodels/Session.tsShop.tsroot.tsxshopify.app.toml@shopify/shopify-app-remixshopify.server.tsauthenticateimport { shopifyApp } from "@shopify/shopify-app-remix/server";
import { RedisSessionStorage } from "@shopify/shopify-app-session-storage-redis";
const sessionDb = new RedisSessionStorage(
new URL(process.env.REDIS_URL!)
);
const shopify = shopifyApp({
apiKey: process.env.SHOPIFY_API_KEY,
apiSecretKey: process.env.SHOPIFY_API_SECRET,
appUrl: process.env.SHOPIFY_APP_URL,
scopes: process.env.SCOPES?.split(","),
apiVersion: "2025-10",
sessionStorage: sessionDb,
isEmbeddedApp: true,
});
export const authenticate = shopify.authenticate;
export const apiVersion = "2025-10";
export const addDocumentResponseHeaders = shopify.addDocumentResponseHeaders;import { json } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export const loader = async ({ request }) => {
const { admin, session } = await authenticate.admin(request);
// Use admin API
const response = await admin.graphql(`...`);
return json({ data: response });
};app/routes/webhooks.tsxshopify.server.tsshopify.server.tsactionapp/routes/webhooks.tsxapp/db.server.tsimport mongoose from "mongoose";
let isConnected = false;
export const connectDb = async () => {
if (isConnected) return;
try {
await mongoose.connect(process.env.MONGODB_URI!);
isConnected = true;
console.log("🚀 Connected to MongoDB");
} catch (error) {
console.error("❌ MongoDB connection error:", error);
}
};app/models/Shop.tsimport mongoose from "mongoose";
const ShopSchema = new mongoose.Schema({
shop: { type: String, required: true, unique: true },
accessToken: { type: String, required: true },
isInstalled: { type: Boolean, default: true },
});
export const Shop = mongoose.models.Shop || mongoose.model("Shop", ShopSchema);import { connectDb } from "../db.server";
import { Shop } from "../models/Shop";
export const loader = async ({ request }) => {
await connectDb();
// ...
const shopData = await Shop.findOne({ shop: session.shop });
// ...
};<Page><Layout><Card>app.tsxapp/routes/app.tsx<ui-nav-menu>
<Link to="/app">Home</Link>
<Link to="/app/settings">Settings</Link>
</ui-nav-menu>adminauthenticate.admin(request)SHOPIFY_API_KEYSHOPIFY_API_SECRETSCOPESSHOPIFY_APP_URL