LogoLogo
CommunitySupport PortalYouTubeStart a free trial
  • Welcome
  • Commerce Engine
  • Orchestration Engine
  • API Documentation
  • Release Notes
  • Changelog
  • Commerce Engine
  • Getting Started
    • General Concepts of Emporix
    • Creating your first tenant
    • Developer Portal
      • Manage Users
      • Manage API Keys
      • Tenant List
      • My Account
      • Manage Showcase and Sample Data
  • Customer Use Cases
    • Commerce Use Cases
      • Quote Process
      • Orders
      • Coupons and Redeeming Rewards
      • Returns
      • Payments
      • User Management and Approvals
      • Customer Social Login
      • Personalized Commerce - Customer Segments
      • Company Shared Orders and Customer Groups
    • Automated Use Cases
      • First Registration Coupon
      • Availability and Warehouse Assignment
      • Quote and Order Entry Automation
  • System Management
    • Introduction
    • Authentication and Authorization
      • Identity and Access Management (IAM)
      • Auth0
      • Emporix Single Sign-On (SSO)
    • Webhook Event Publishing
      • HTTP Webhook Strategy - HMAC Configuration
      • HTTP Webhook Strategy - Integration with Azure Service Bus
      • HTTP Webhook Strategy - Integration with Amazon Simple Queue Service (SQS)
    • Search
      • Universal Search Connector
      • Search Configuration
      • Indexing Service
    • Optimistic Locking
  • Extensibility and Integrations
    • Extensibility Cases
      • External Products, Pricing and Fees
      • Enabling Custom Extensions
    • Integrations
      • SAP Integration
    • Payment Systems
      • PayPal
      • Saferpay
      • Spreedly Gateway
      • Unzer
    • Third Party Add-Ons
      • Emporix Contentful App
      • Emporix Builder.io Plugin
      • Magnolia Emporix Connector
      • Zendesk Emporix Connect
    • Powered by AI
      • AI Smart Config
      • AI Smart Import
  • Core Commerce
    • Introduction
    • AI Assistance
    • Carts
    • Catalogs
    • Categories
    • Coupons
    • Customer Management
      • Approvals
      • Assisted Buying
      • Customer Groups
      • Customer Segments
    • Data Localization
    • Delivery Cycle Management
    • Mixin Schemas
    • Media Management
    • Orders
      • Shared Orders
    • Pricing
      • Pricing (Legacy)
    • Products
      • Availability, location, and stock levels
      • Brands
      • Labels
    • Quotes
    • Returns
    • Reward Points Management
    • Sites
    • Tax Classes
      • Tax classes (Legacy)
    • Measurement Units
  • Management Dashboard
    • Introduction
    • Customer Management
      • Companies
      • Customers
      • Groups
      • Segments
      • Coupons
    • Quotes
      • Quotes
      • Status Codes
    • Orders
      • Orders
      • SEPA
      • Returns
    • Catalogs
      • Catalogs
      • Categories
    • Products
      • Products
      • Product Templates
      • Labels
      • Suppliers
      • Brands
      • AI for a Product Description
    • Pricing
      • Price Models
      • Price Lists
    • Settings
      • Sites
      • Shipping Zones and Methods
      • Delivery Times
      • Units
      • Tax
      • Countries
      • Currencies
      • Languages
      • System Preferences
      • Custom Entities
      • Mixin Schemas
    • Administration
      • Users and Groups
      • Extensions
      • API Statistics
      • Webhooks
    • Extensions
    • Custom Instances
  • Additional Resources
    • Glossary
    • Videos
    • Emporix Community
Powered by GitBook
On this page
  • Custom extension
  • Create own extension
  • Install and initialize md-ext library
  • Add the extension to the Management Dashboard
  • Register context changes callback
  • Remove state change callback
  • Add deeplinking
  • Example use case

Was this helpful?

Export as PDF
  1. Extensibility and Integrations
  2. Extensibility Cases

Enabling Custom Extensions

You can introduce your custom logic and functionality you need easily with custom extensions.

PreviousExternal Products, Pricing and FeesNextIntegrations

Last updated 23 days ago

Was this helpful?

LogoLogo

Resources

  • Emporix.com
  • Developer Policy
  • Terms of Use

Find us

  • LinkedIn

© 2025 Emporix. All Rights Reserved.

You can extend Management Dashboard with your custom extension, which can be embedded directly in Management Dashboard to make it easier for your employees to work with integrated systems. Learn how to prepare your custom extension to make it work smoothly within Emporix platform.

We recommend using the following:

  • the latest version of , version v20 or higher

  • frontend build tooling

  • The Synonyms extension we build in this tutorial as an is available for public reuse under . The repository contains also other example extensions. Check it out to get inspired and build your own extension.

  • To learn how to add extensions to Management Dashboard, see the guide and to check how they are displayed in Management Dashboard after the installation, see the documentation.

Custom extension

Create own extension

  1. Create an extension using Vite. In your console, run the following command:

npm create vite@latest my-md-ext

where my-md-ext is the name of the extension.

  1. When prompted by Vite, select the framework you want to use. In this example, we use React.

  2. When prompted by Vite, select the variant. In this example, we use TypeScript.

  3. When the project is created, go to the new project directory my-md-ext and run:

yarn install
  1. When the build completes, run:

yarn dev

As a successful output, you see the localhost running details:

To test it, open the URL in a browser to see the vanilla state of Vite and React project:

Install and initialize md-ext library

The extension doesn't have any connection to Management Dashboard yet. To prepare the custom extension to be embedded in Management Dashboard, install the md-ext library so that it takes care of the required dependencies for you.

  1. Stop the server, and in the custom extension directory, run:

yarn add md-ext
  1. Open the custom extension project in the IDE of your preference. In the App.tsx file, add the following import:

import {registerClient} from 'md-ext/lib'
  1. Add the client registration code:

registerClient();
Check the App.tsx file after the changes
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
import {registerClient} from 'md-ext/lib'

function App() {
  const [count, setCount] = useState(0)
  registerClient();

  return (
    <>
      <div>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://react.dev" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
        <p>
          Edit <code>src/App.tsx</code> and save to test HMR
        </p>
      </div>
      <p className="read-the-docs">
        Click on the Vite and React logos to learn more
      </p>
    </>
  )
}

export default App
  1. To start the extension, run:

yarn dev

Add the extension to the Management Dashboard

Register context changes callback

Depending on what you are going to use your extension for, you might need to allow the extension to read the Management Dashboard Context. Thanks to the callback function, the context information is passed to the custom extension each time the extension is launched in the Management Dashboard, and you might process the data further from there.

  1. To enable callback function, import the registerCallback function in the App.tsx file:

import {
  registerCallback,
} from 'md-ext/lib'
  1. And define the callback:

registerCallback('callbackId', (ctx) => {
  console.log('context update', ctx)
})

The following Context information is passed every time a user opens the custom extension in Management Dashboard:

  • accessToken - the token you can use for API communication

  • user - the object containing user information like first and last name, email, and userId

  • tenant - the currently selected tenant

  • currentSite - the currently selected site

  • scopes - all scopes that are valid for the logged in user

  • contentLanguage - the language to display any text in the extension

  • currency - the selected currency

    • id - the currency ID

    • label - the displayed label

    • default - information if the currency is a default one

    • required - information if the currency is required

  • sites - available sites for the tenant

    • active - information whether the site is active

    • code - the site code

    • currency - the default currency used on the site

    • default - information whether the site is a default one

    • defaultLanguage - the default site's language

    • languages - available languages on the site

    • name - the site's name

  • windowLocationHref - URL of the extensions

  • configuration - configuration settings

    • currencies - available currencies

    • languages - available languages

    • theme - the main theme

  • language - the selected language information

    • id - the language ID

    • label - the language label

    • default - information whether the language is a default one

    • required - information whether the language is required

  • clients - the selected client information

    • tenant - the selected tenant

    • clientId - the client ID

Remove state change callback

You can revert submission to Context updates by unregistering from the callback changes.

  1. Call the unregisterCallback with the callbackId:

import {
  unregisterCallback,
} from ''md-ext/lib''
unregisterCallback('callbackId')
  1. Rebuild the extension:

yarn build

Add deeplinking

Implementing deeplinking allows you to direct users to specific pages within the application. With deeplinking, the URL address contains #/, so for example, you can display a specific item directly in the extension by calling it from the URL. Sync the current path with the Management Dashboard path by the adding following code:

  1. Import syncUrl:

import { syncUrl } from 'md-ext/lib'
  1. Import useEffect:

import { useEffect, useState } from 'react'
  1. Declare the syncURL path:

useEffect(() => {
    syncUrl('/' + location.pathname);
  }, [location]);
Check the App.tsx file after the changes
import { useEffect, useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'

import {registerClient, registerCallback, syncUrl } from 'md-ext/lib'

function App() {
  const [count, setCount] = useState(0)
  registerClient();

  registerCallback('callbackId', (ctx) => {
    console.log('context update', ctx)
  })

  useEffect(() => {
    syncUrl('/' + location.pathname);
  }, [location]);
  
  return (
    <>
      <div>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://react.dev" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
        <p>
          Edit <code>src/App.tsx</code> and save to test HMR
        </p>
      </div>
      <p className="read-the-docs">
        Click on the Vite and React logos to learn more
      </p>
    </>
  )
}

export default App

Example use case

Custom extensions can serve different purposes and can organize your work more efficiently in many ways. Let's take a look at the example of a custom extension that serves optimizing the search on your storefront by extending the synonyms library in your search index provider. We've built the Synonyms extension that communicates with an index provider and we've embedded it in the Management Dashboard. The example is based on Algolia, but could be any other provider.

You can already add your extension to the Management Dashboard. Follow the steps described in . As a result, your extension is visible under Extensions module:

The Synonyms extension is an example use case of custom extensions. If you want to try it out, as a prerequisite for the extension to work, you need to activate and configure your own index provider. You can achieve that by using the Emporix API. To learn more, see the .

We've built the Synonyms extension in this example using , just as described in the section above, and have deployed in the Emporix Algolia instance. Then, we've enabled it in the Management Dashboard following instructions in documentation. The extension logic allows you to manage the synonyms of your industry or product-related terms. This way, the search index can be optimized to bring more accurate results for the customers queries on the storefront. Customers tend to use specific wording when they search for a product, and with synonyms in place you can improve the search results. The extension makes it easier for your employees to add, edit or remove synonyms directly from the Emporix UI whenever they see the need for that, without the necessity of switching to Algolia (or another search index provider) configuration UI.

Extensions
Indexing Service
Node.js
Vite
MD Extensions
Administration - Extensions
Management Dashboard - Extensions
example use case
Vite
Custom Extension
Adding an extension