


Create a Shopify App for Product Vendors & Admin options using ReactJS & Polaris
0
3
0
🧱 Requirements
Shopify Partner Account
Development store
Shopify CLI
Frontend: React.js with App Bridge + Polaris
App Hosted externally (e.g., Vercel/Netlify)
Authenticated using Shopify App Bridge + JWT token
✅ Step-by-Step Guide: Shopify Embedded App in React Only
🧩 Step 1: Create React App
npx create-react-app vendor-app
cd vendor-app
📦 Step 2: Install Dependencies
npm install @shopify/app-bridge-react @shopify/polaris @shopify/app-bridge @shopify/app-bridge-utils
Also install @shopify/polaris CSS:
npm install @shopify/polaris-tokens
⚙️ Step 3: Setup App Bridge Provider
In src/index.js:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import {
AppBridgeProvider
} from "@shopify/app-bridge-react";
import {
Provider as PolarisProvider
} from "@shopify/polaris";
import "@shopify/polaris/build/esm/styles.css";
const config = {
apiKey: process.env.REACT_APP_SHOPIFY_API_KEY, // from Shopify Partner dashboard
host: new URLSearchParams(window.location.search).get("host"),
forceRedirect: true,
};
ReactDOM.render(
<PolarisProvider>
<AppBridgeProvider config={config}>
<App />
</AppBridgeProvider>
</PolarisProvider>,
document.getElementById("root")
);
🗂️ Step 4: Add Navigation (Admin Menu)
In src/App.js:
import {
NavigationMenu
} from "@shopify/app-bridge-react";
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import Vendors from "./pages/Vendors";
import VendorDetail from "./pages/VendorDetail";
function App() {
return (
<>
<NavigationMenu
navigationLinks={[
{
label: "Vendors",
destination: "/vendors",
},
]}
/>
<Router>
<Routes>
<Route path="/vendors" element={<Vendors />} />
<Route path="/vendors/:name" element={<VendorDetail />} />
</Routes>
</Router>
</>
);
}
export default App;
🗂️ Step 5:
/vendors
Page
src/pages/Vendors.js
import { Page, Card, ResourceList, Text } from "@shopify/polaris";
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
const Vendors = () => {
const [vendors, setVendors] = useState([]);
useEffect(() => {
const fetchProducts = async () => {
const token = window.sessionToken; // get from App Bridge utils
const res = await fetch("/admin/api/2024-01/products.json", {
headers: {
"X-Shopify-Access-Token": token,
},
});
const data = await res.json();
const vendorMap = {};
data.products.forEach((p) => {
const vendor = p?.vendor || p?.metafields?.find(mf => mf.key === "vendor_name")?.value;
if (vendor) vendorMap[vendor] = true;
});
setVendors(Object.keys(vendorMap).map((v) => ({ name: v })));
};
fetchProducts();
}, []);
return (
<Page title="Vendors">
<Card>
<ResourceList
items={vendors}
renderItem={(vendor) => (
<ResourceList.Item
id={vendor.name}
accessibilityLabel={`View ${vendor.name}`}
>
<Link to={`/vendors/${vendor.name}`}>{vendor.name}</Link>
</ResourceList.Item>
)}
/>
</Card>
</Page>
);
};
export default Vendors;
📄 Step 6:
/vendors/:name
Page
src/pages/VendorDetail.js
import { useParams } from "react-router-dom";
import { Page, Card, ResourceList, Text } from "@shopify/polaris";
import { useEffect, useState } from "react";
const VendorDetail = () => {
const { name } = useParams();
const [products, setProducts] = useState([]);
const [orders, setOrders] = useState([]);
useEffect(() => {
const token = window.sessionToken;
const fetchProducts = async () => {
const res = await fetch("/admin/api/2024-01/products.json", {
headers: {
"X-Shopify-Access-Token": token,
},
});
const data = await res.json();
const filtered = data.products.filter(p => p.vendor === name);
setProducts(filtered);
};
const fetchOrders = async () => {
const res = await fetch("/admin/api/2024-01/orders.json", {
headers: {
"X-Shopify-Access-Token": token,
},
});
const data = await res.json();
const vendorOrders = data.orders.filter(order =>
order.line_items.some(li => li.vendor === name)
);
setOrders(vendorOrders);
};
fetchProducts();
fetchOrders();
}, [name]);
return (
<Page title={`Vendor: ${name}`}>
<Card title="Products">
<ResourceList
items={products}
renderItem={(p) => (
<ResourceList.Item id={p.id}>
<Text>{p.title}</Text>
</ResourceList.Item>
)}
/>
</Card>
<Card title="Orders">
<ResourceList
items={orders}
renderItem={(o) => (
<ResourceList.Item id={o.id}>
<Text>Order #{o.name}</Text>
</ResourceList.Item>
)}
/>
</Card>
</Page>
);
};
export default VendorDetail;
🔐 Step 7: Handle Access Token (JWT)
You need to use App Bridge Utils to get the JWT session token to call Admin API:
import { getSessionToken } from "@shopify/app-bridge-utils";
getSessionToken(app).then(token => {
window.sessionToken = token;
});
Call this on app load (App.js) inside useEffect.
🚀 Final Hosting (Vercel/Netlify)
Push your React app to GitHub.
Deploy using Vercel or Netlify.
Use the deployed URL to register the app in Shopify Partner → App Setup > App URL.
Add /auth/callback, /auth, / to whitelist.
🧩 Notes
You must register your app from Partner dashboard.
Use Admin API scopes like:
read_products
read_orders
read_customers (optional)
All calls must pass JWT session token obtained via App Bridge.
Related Posts

READ OUR LATEST ARTICLES
Post
Welcome to the Intertoons Blog! Discover expert insights, the latest trends, and valuable tips on eCommerce, web development, and digital solutions. Stay informed and ahead in the digital world with our in-depth articles and guides!
5/5 based on 63 reviews | GDPR Compliant