Vendure GraphQL API Frontend Integration
Vendure provides two separate GraphQL endpoints: Shop API (/shop-api) for customers and Admin API (/admin-api) for administrators. Frontend uses only Shop API. Authentication via cookie-based sessions or Bearer token, choice made at server config level.
Client Setup (urql)
urql is lighter than Apollo and better for Vendure — less boilerplate with cookie sessions:
// lib/vendureClient.ts
import { createClient, fetchExchange, dedupExchange, cacheExchange } from "urql";
export const shopClient = createClient({
url: `${process.env.NEXT_PUBLIC_VENDURE_API_URL}/shop-api`,
exchanges: [dedupExchange, cacheExchange, fetchExchange],
fetchOptions: {
credentials: "include", // cookie-based auth
headers: { "vendure-token": process.env.NEXT_PUBLIC_CHANNEL_TOKEN! },
},
});
Type Generation
# codegen.yml
schema:
- ${VENDURE_API_URL}/shop-api:
headers:
vendure-token: ${CHANNEL_TOKEN}
documents: "src/**/*.graphql"
generates:
src/generated/shop-types.ts:
plugins:
- typescript
- typescript-operations
- typescript-urql
config:
withHooks: true
VENDURE_API_URL=http://localhost:3000 CHANNEL_TOKEN=my-token npx graphql-codegen
Catalog Queries
query GetProductList($options: ProductListOptions) {
products(options: $options) {
totalItems
items {
id
name
slug
variants {
id
priceWithTax
stockLevel
}
}
}
}
Checkout Flow
// hooks/useCheckout.ts
export function useCheckout() {
const [, setAddress] = useMutation(SetShippingAddressDocument);
const [, setShipping] = useMutation(SetShippingMethodDocument);
const [, addPayment] = useMutation(AddPaymentToOrderDocument);
async function completeCheckout(params: CheckoutParams) {
// 1. Address
const addr = await setAddress({ input: params.address });
// 2. Shipping method
await setShipping({ id: [params.shippingMethodId] });
// 3. Add payment
const payment = await addPayment({
input: { method: "yookassa", metadata: { returnUrl: window.location.origin } },
});
return payment.data?.addPaymentToOrder;
}
return { completeCheckout };
}
SSR with Next.js
// app/shop/page.tsx
import { createServerClient } from "@/lib/vendureServerClient";
export default async function ShopPage() {
const client = createServerClient();
const result = await client.query(GetProductListDocument, {
options: { take: 24 },
}).toPromise();
return <ProductGrid initialData={result.data} />;
}
Timelines: Setup Vendure client, schema generation, catalog integration, checkout — 3–5 business days. Payment integration, shipping, admin panel — +3–4 days.







