// Vendure e-commerce framework for Node.js. Use for headless commerce, GraphQL APIs, order management, product catalogs, payment integration, and TypeScript e-commerce development.
| name | vendure |
| description | Vendure e-commerce framework for Node.js. Use for headless commerce, GraphQL APIs, order management, product catalogs, payment integration, and TypeScript e-commerce development. |
Comprehensive assistance with Vendure development, generated from official documentation.
Trigger this skill when:
Pattern 1: Create a New Vendure Project
The fastest way to get started with Vendure:
npx @vendure/create my-shop
This launches an interactive wizard:
โ Let's create a Vendure App โจ
โ
โโ How should we proceed?
โ โ Quick Start (Get up and running in a single step)
โ โ Manual Configuration
โ
โ
Pattern 2: Format Currency Values
Vendure stores monetary values as integers (e.g., 100 = $1.00). Use this function to display them:
export function formatCurrency(value: number, currencyCode: string, locale?: string) {
const majorUnits = value / 100;
try {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency: currencyCode,
}).format(majorUnits);
} catch (e: any) {
return majorUnits.toFixed(2);
}
}
Usage:
formatCurrency(2399, 'USD'); // "$23.99"
Pattern 3: Create a Custom Payment Handler
Integrate a payment provider with a PaymentMethodHandler:
import { PaymentMethodHandler, CreatePaymentResult, SettlePaymentResult } from '@vendure/core';
const myPaymentHandler = new PaymentMethodHandler({
code: 'my-payment-method',
description: [{
languageCode: LanguageCode.en,
value: 'My Payment Provider',
}],
args: {
apiKey: { type: 'string', label: 'API Key' },
},
createPayment: async (ctx, order, amount, args, metadata): Promise<CreatePaymentResult> => {
// Integrate with payment provider SDK
const result = await paymentProvider.authorize({
amount,
token: metadata.paymentToken,
apiKey: args.apiKey,
});
return {
amount,
state: 'Authorized',
transactionId: result.transactionId,
metadata: result,
};
},
settlePayment: async (ctx, order, payment, args): Promise<SettlePaymentResult> => {
const result = await paymentProvider.capture(payment.transactionId);
return { success: true };
},
});
Pattern 4: Email Event Handler
Send emails when events occur (e.g., order confirmation):
import { EmailEventListener } from '@vendure/email-plugin';
import { OrderStateTransitionEvent } from '@vendure/core';
const confirmationHandler = new EmailEventListener('order-confirmation')
.on(OrderStateTransitionEvent)
.filter(event => event.toState === 'PaymentSettled')
.setRecipient(event => event.order.customer.emailAddress)
.setFrom('{{ fromAddress }}')
.setSubject(`Order confirmation for #{{ order.code }}`)
.setTemplateVars(event => ({ order: event.order }));
Place template at: <app root>/static/email/templates/order-confirmation/body.hbs
Pattern 5: Define a Custom Strategy Interface
Create pluggable, extensible plugin behavior with strategies:
import { InjectableStrategy, RequestContext } from '@vendure/core';
export interface MyCustomStrategy extends InjectableStrategy {
/**
* Process some data and return a result
*/
processData(ctx: RequestContext, data: any): Promise<string>;
/**
* Validate the input data
*/
validateInput(data: any): boolean;
}
Default Implementation:
import { Injector, Logger } from '@vendure/core';
export class DefaultMyCustomStrategy implements MyCustomStrategy {
private someService: SomeService;
async init(injector: Injector): Promise<void> {
this.someService = injector.get(SomeService);
Logger.info('Strategy initialized');
}
async destroy(): Promise<void> {
// Clean up resources
}
async processData(ctx: RequestContext, data: any): Promise<string> {
if (!this.validateInput(data)) {
throw new Error('Invalid input data');
}
return this.someService.process(data);
}
validateInput(data: any): boolean {
return data != null && typeof data === 'object';
}
}
Pattern 6: Upload Files with Custom Mutation
Allow customers to upload avatar images:
import gql from 'graphql-tag';
// 1. Schema definition
export const shopApiExtensions = gql`
extend type Mutation {
setCustomerAvatar(file: Upload!): Asset
}
`;
// 2. Resolver implementation
import { Args, Mutation, Resolver } from '@nestjs/graphql';
import { Allow, AssetService, Ctx, Permission, RequestContext, Transaction } from '@vendure/core';
@Resolver()
export class CustomerAvatarResolver {
constructor(private assetService: AssetService) {}
@Transaction()
@Mutation()
@Allow(Permission.Authenticated)
async setCustomerAvatar(
@Ctx() ctx: RequestContext,
@Args() args: { file: any },
): Promise<Asset | undefined> {
const asset = await this.assetService.create(ctx, {
file: args.file,
tags: ['customer-avatar'],
});
return asset;
}
}
Pattern 7: OrderInterceptor - Enforce Min/Max Quantity
Prevent order operations based on custom validation logic:
import { OrderInterceptor, WillAddItemToOrderInput, RequestContext, Order } from '@vendure/core';
export class MinMaxOrderInterceptor implements OrderInterceptor {
willAddItemToOrder(
ctx: RequestContext,
order: Order,
input: WillAddItemToOrderInput,
): Promise<void | string> | void | string {
const { productVariant, quantity } = input;
const min = productVariant.customFields?.minOrderQuantity;
const max = productVariant.customFields?.maxOrderQuantity;
if (min && quantity < min) {
return `Minimum order quantity for "${productVariant.name}" is ${min}`;
}
if (max && quantity > max) {
return `Maximum order quantity for "${productVariant.name}" is ${max}`;
}
}
}
Pattern 8: GraphQL Query - Search Products
Search for products with faceted filtering:
import gql from 'graphql-tag';
const SEARCH_PRODUCTS = gql`
query SearchProducts($input: SearchInput!) {
search(input: $input) {
totalItems
facetValues {
count
facetValue {
id
name
facet {
id
name
}
}
}
items {
productId
productName
productAsset {
id
preview
}
slug
featuredAsset {
preview
}
variants {
id
name
currencyCode
price
priceWithTax
}
}
}
}
`;
Pattern 9: Money & Currency - Store Custom Entity Prices
Use the @Money() decorator for monetary values:
import { VendureEntity, Money, CurrencyCode, EntityId, ID } from '@vendure/core';
import { Column, Entity } from 'typeorm';
@Entity()
class Quote extends VendureEntity {
@Column()
text: string;
@Money()
value: number; // Stored as integer (cents)
@Column('varchar')
currencyCode: CurrencyCode;
@EntityId()
orderId: ID;
}
Pattern 10: Install Vendure Dashboard
Add the Admin UI to the project:
npm install @vendure/dashboard
Configure in vendure-config.ts:
import { VendureConfig } from '@vendure/core';
import { DashboardPlugin } from '@vendure/dashboard';
export const config: VendureConfig = {
plugins: [
DashboardPlugin.init({
route: 'admin',
port: 3002,
}),
],
};
Core Vendure architecture concepts (see references/core_concepts.md and references/developer_guide.md for detailed explanations):
This skill includes comprehensive documentation in references/:
api.md - 800 pages)Complete TypeScript API reference covering:
Finding API components: Use grep to locate specific classes:
grep -n "^## PaymentMethodHandler" references/api.md
grep -n "^## DashboardPlugin" references/api.md
grep -n "useLocalFormat" references/api.md
core_concepts.md - 16 pages)Foundational architecture and patterns:
developer_guide.md - 48 pages)Building and extending Vendure:
getting_started.md)Quick start guides and initial setup:
@vendure/createhow_to.md)Task-specific tutorials:
other.md)Miscellaneous topics:
user_guide.md)Admin UI usage and merchant workflows:
Use the Read tool to access specific reference files when detailed information is needed.
references/getting_started.md for foundational setupreferences/core_concepts.md for Money, Orders, Payment flowsreferences/developer_guide.md for real-world implementationsreferences/api.md to find services and strategiesreferences/developer_guide.mdreferences/other.mdreferences/developer_guide.mdreferences/api.md for specific class/interface names| Task | Quick Reference Pattern | Reference File |
|---|---|---|
| Start new project | Pattern 1 | getting_started.md |
| Display prices | Pattern 2 | core_concepts.md (Money & Currency) |
| Accept payments | Pattern 3 | core_concepts.md (Payment) |
| Send emails | Pattern 4 | api.md (EmailPlugin) |
| Create plugin | Pattern 5 | developer_guide.md (Custom Strategies) |
| Upload files | Pattern 6 | developer_guide.md (Uploading Files) |
| Validate orders | Pattern 7 | api.md (OrderInterceptor) |
| Query products | Pattern 8 | api.md (GraphQL) |
| Store prices | Pattern 9 | core_concepts.md (Money) |
| Install Admin UI | Pattern 10 | getting_started.md |
| Dashboard widgets | - | other.md (Insights Widgets) |
Organized documentation extracted from official Vendure docs (https://docs.vendure.io). These files contain:
Add helper scripts here for common Vendure automation tasks:
Add templates, boilerplate, or example projects here:
To refresh this skill with updated documentation: