Documentation Index
Fetch the complete documentation index at: https://docs.rmz.gg/llms.txt
Use this file to discover all available pages before exploring further.
The SDK provides a built-in React hook and works seamlessly with Next.js for both client-side rendering and server-side rendering.
Next.js Starter Template
Full example storefront built with Next.js, TypeScript, and the Storefront SDK.
React Hook
The SDK exports a useStorefrontSDK hook that memoizes the SDK instance:
import { useStorefrontSDK } from 'rmz-storefront-sdk';
import { useEffect, useState } from 'react';
function ProductList() {
const sdk = useStorefrontSDK({
apiUrl: process.env.NEXT_PUBLIC_RMZ_API_URL!,
publicKey: process.env.NEXT_PUBLIC_RMZ_PUBLIC_KEY!,
});
const [products, setProducts] = useState([]);
useEffect(() => {
async function loadProducts() {
const { data } = await sdk.products.getAll({ per_page: 12 });
setProducts(data);
}
loadProducts();
}, [sdk]);
return (
<div className="grid grid-cols-3 gap-4">
{products.map(product => (
<div key={product.id}>
<h3>{product.name}</h3>
<p>{product.price} {product.currency}</p>
</div>
))}
</div>
);
}
Next.js Server-side Rendering
Use the SDK in getServerSideProps or server components with HMAC authentication:
// lib/sdk.ts
import { createStorefrontSDK } from 'rmz-storefront-sdk';
// Client-side SDK (no secret key)
export const clientSDK = createStorefrontSDK({
apiUrl: process.env.NEXT_PUBLIC_RMZ_API_URL || 'https://front.rmz.gg/api',
publicKey: process.env.NEXT_PUBLIC_RMZ_PUBLIC_KEY!,
});
// Server-side SDK (with HMAC)
export const serverSDK = createStorefrontSDK({
apiUrl: process.env.RMZ_API_URL || 'https://front.rmz.gg/api',
publicKey: process.env.RMZ_PUBLIC_KEY!,
secretKey: process.env.RMZ_SECRET_KEY!,
environment: 'production',
});
Pages Router (getServerSideProps)
// pages/index.tsx
import { serverSDK } from '@/lib/sdk';
export async function getServerSideProps() {
const [store, { data: products }] = await Promise.all([
serverSDK.store.get(),
serverSDK.products.getFeatured(8),
]);
return {
props: { store, products },
};
}
export default function Home({ store, products }) {
return (
<div>
<h1>{store.name}</h1>
{products.map(p => <ProductCard key={p.id} product={p} />)}
</div>
);
}
App Router (Server Components)
// app/page.tsx
import { serverSDK } from '@/lib/sdk';
export default async function HomePage() {
const store = await serverSDK.store.get();
const featured = await serverSDK.products.getFeatured(8);
return (
<div>
<h1>{store.name}</h1>
{featured.map(p => <ProductCard key={p.id} product={p} />)}
</div>
);
}
API Routes
// app/api/cart/route.ts
import { serverSDK } from '@/lib/sdk';
import { NextRequest } from 'next/server';
export async function POST(request: NextRequest) {
const { productId, quantity } = await request.json();
const cart = await serverSDK.cart.addItem(productId, quantity);
return Response.json(cart);
}
Cart Context Example
A common pattern is to wrap cart state in a React context:
// contexts/CartContext.tsx
import { createContext, useContext, useState, useCallback } from 'react';
import { clientSDK } from '@/lib/sdk';
const CartContext = createContext(null);
export function CartProvider({ children }) {
const [cart, setCart] = useState(null);
const [count, setCount] = useState(0);
const addItem = useCallback(async (productId, quantity = 1) => {
const updated = await clientSDK.cart.addItem(productId, quantity);
setCart(updated);
setCount(updated.count);
return updated;
}, []);
const refresh = useCallback(async () => {
const current = await clientSDK.cart.get();
setCart(current);
setCount(current.count);
}, []);
return (
<CartContext.Provider value={{ cart, count, addItem, refresh }}>
{children}
</CartContext.Provider>
);
}
export const useCart = () => useContext(CartContext);
Environment Variables
# .env.local
NEXT_PUBLIC_RMZ_API_URL=https://front.rmz.gg/api
NEXT_PUBLIC_RMZ_PUBLIC_KEY=pk_your_public_key
RMZ_API_URL=https://front.rmz.gg/api
RMZ_PUBLIC_KEY=pk_your_public_key
RMZ_SECRET_KEY=sk_your_secret_key