Skip to main content

Plugin Configuration Strategies

Vendure plugins unlock campaign orchestration, search, packaging logic, and more. This guide shows how to manage plugins as first-class features inside Haus Storefront apps using the configuration system described in Vendure Plugin Configs.

1. Centralize Plugin Instantiation

Create a single module that exports configured plugin instances. This keeps feature toggles, settings, and query updates close to source control and lets both the frontend and backend teams reason about the live feature set.

// commerce/plugins.ts
import { VendureBadgePlugin } from '@haus-storefront-react/vendure-plugin-configs/badge'
import { VendureCampaignPlugin } from '@haus-storefront-react/vendure-plugin-configs/campaign'
import { VendureElasticSearchPlugin } from '@haus-storefront-react/vendure-plugin-configs/elastic'

import { FeatureFlagClient } from './feature-flags'

const flags = new FeatureFlagClient()

export const badgePlugin = VendureBadgePlugin.init({
enableFeatures: {
imageBadges: true,
textBadges: flags.isEnabled('badge:text'),
},
})

export const elasticPlugin = VendureElasticSearchPlugin.init({
settings: {
defaultFacetValues: ['size', 'color'],
},
})

export const campaignPlugin = VendureCampaignPlugin.init({
settings: {
previewChannels: ['staging', 'nightly'],
},
})

export const pluginConfigs = [badgePlugin, elasticPlugin, campaignPlugin]

Use the export everywhere you bootstrap the app:

import { DataProvider } from '@haus-storefront-react/core'
import { pluginConfigs } from '@/commerce/plugins'

export function AppProviders({ children }) {
return (
<DataProvider
provider='vendure'
platform='web'
options={{
apiUrl: process.env.NEXT_PUBLIC_VENDURE_SHOP_API!,
vendureToken: process.env.NEXT_PUBLIC_VENDURE_CHANNEL_TOKEN!,
pluginConfigs,
}}
>
{children}
</DataProvider>
)
}

2. Work with Query Updates

Plugins can append fields to generated GraphQL operations through queryUpdates. This keeps UI components typed even when backend entities gain new attributes.

import { VendurePluginConfig } from '@haus-storefront-react/vendure-plugin-configs'

export const loyaltyPlugin = new VendurePluginConfig({
name: 'loyalty',
queryUpdates: {
Product: {
fields: {
loyaltyTier: {
selection: 'id name threshold',
},
},
},
Order: {
fields: {
loyaltyPointsEarned: {
selection: 'totalPoints',
},
},
},
},
})

Because the plugin feeds into the SDK builder, all downstream calls to sdk.product({ id }) include the extended selection set once the plugin is registered.

Check your fragments. When you rely on shared GraphQL fragments, update them in tandem with the queryUpdates to avoid runtime errors caused by mismatched fields.

3. Surface Plugin Data in Components

Many UI packages already ship headless components ready to consume plugin data. For example, the product badge component returns null when the plugin is not enabled, which makes progressive enhancement simple.

import { ProductBadge } from '@haus-storefront-react/vendure-plugin-configs/badge'

export function ProductTile({ product }) {
return (
<article>
<header>
<ProductBadge.Root product={product}>
{({ groupedBadges }) => (
<ul aria-label='Product badges'>
{Object.entries(groupedBadges).map(([position, badges]) => (
<li key={position}>
{badges.map((badge) => (
<ProductBadge.Item key={badge.id} badge={badge} />
))}
</li>
))}
</ul>
)}
</ProductBadge.Root>
</header>
<h3>{product.name}</h3>
</article>
)
}

Use the plugin instance to fetch additional data on demand:

import { badgePlugin } from '@/commerce/plugins'

const { fetchBadgeAnalytics } = badgePlugin.getRequests()
const analytics = await fetchBadgeAnalytics(product.id)

If a plugin is disabled, getRequests() falls back to the default no-op implementation, so you can safely call it without additional guards.

4. Manage Environments and Channels

  • Environment toggles: Read from LaunchDarkly, ConfigCat, or simple .env switches inside the plugin factory. Because init accepts feature maps (enableFeatures), you can flip features without redeploying the entire app.
  • Channel awareness: Inject the current Vendure channel ID into plugin settings to scope queries (settings: { channelId }).
  • Preview safety: Provide a dedicated plugin array for preview deployments (e.g., omit expensive search providers) while keeping production configuration untouched.

5. Instrument and Observe

  • setProviders allows you to attach custom event providers for logging or observability.
  • Combine enableFeatures with the SDK EventBus (see Core) to emit events whenever a plugin-controlled feature activates.
  • Record plugin settings as part of your deployment metadata so storefront teams can audit which features are live at any point in time.

When the plugin system is treated as an application boundary—not just a bundle of utilities—you unlock repeatable, governed feature delivery for every storefront powered by Haus Tech.