# Build a replacement module Build a Module Federation external module that plugs into the InStore State module and replaces a built-in component of the InStore POS. This page covers the setup that every replacement module needs. For the contract of the component you replace, see [Implement the Cart module](/instore/customization/pos-cart-module.md). ## Prerequisites Before you build a replacement module, make sure you have the following: - A webpack build that uses `@module-federation/enhanced`. - React 18 and React Router 6. - A host that serves your built files over HTTP or HTTPS, reachable from the browser that runs the POS. - Administration rights on the tenant, so that you can register the module. See [Run POS API requests](/instore/customization/pos-api-access.md). ## Configure Module Federation Configure your module as an external module that the POS loads at runtime and as a host that consumes the InStore State module. Configure both roles in one `ModuleFederationPlugin` block: ```js title="webpack.config.js" const { ModuleFederationPlugin, } = require('@module-federation/enhanced/webpack'); const deps = require('./package.json').dependencies; new ModuleFederationPlugin({ name: 'instoreCart', filename: 'remoteEntry.js', remotes: { instoreState: 'instoreState@https://{staticModulesHost}/InStore_State/remoteEntry.js', }, exposes: { './CartApp': './src/App', }, shared: { react: { singleton: true, requiredVersion: deps.react }, 'react-dom': { singleton: true, requiredVersion: deps['react-dom'] }, 'react-redux': { singleton: true, requiredVersion: false }, '@reduxjs/toolkit': { singleton: true, requiredVersion: false }, 'react-router-dom': { singleton: true, requiredVersion: deps['react-router-dom'], }, }, }); ``` Replace `{staticModulesHost}` with the static modules host for your environment. The sample uses the values for a Cart replacement, whose contract is described in [Implement the Cart module](/instore/customization/pos-cart-module.md). The `name` and the `exposes` key are yours to choose, and you register them as `scope` and `module`. Every entry in `shared` must be a singleton. The InStore State module runs on React hooks and Redux, so a second copy of any of these libraries breaks it. Three of these options become values that you register for the module: | Plugin option | External module field | | --- | --- | | `exposes` key | `module` | | `filename`, as served by your host | `url` | | `name` | `scope` | ## Resolve types The InStore State module publishes TypeScript types for everything it exposes. To resolve them, choose one of the following: - Map `instoreState/*` to the state module source in the `paths` section of your `tsconfig.json`. - Consume the types that the state module generates, through the `dts.consumeTypes.remoteTypeUrls` option of `ModuleFederationPlugin`. ## Read shared POS state The POS mounts its context providers around every route. Your module reads those contexts directly, and doesn't mount its own provider. Every replacement module can read the following: - `instoreState/locale` provides `useLocalizationContext`, which returns the translation function `t`. - `instoreState/configuration/context` provides `useConfigurationContext`, which returns `navigate`. Your module renders inside the routes of the POS, so define your own routes as relative paths. ## Register the module Build your module and serve the generated `remoteEntry.js` at a URL that the POS browser can reach. Register it for your tenant, then assign it to a location or to a workstation. For the record fields and for the way InStore chooses between assignments, see [Replace POS UI modules](/instore/customization/pos-ui-modules.md). ## Next steps Use the following resources to continue developing your module: - [Implement the Cart module](/instore/customization/pos-cart-module.md) to read Cart state and render a replacement Cart. - [Replace POS UI modules](/instore/customization/pos-ui-modules.md) to review the external module fields and the resolution model. - [Run POS API requests](/instore/customization/pos-api-access.md) to set the API host, Project, and tenant, and to get an access token. - [Use Modules overview](/instore/implement-instore/modules/working-with-instore-modules.md) to review the InStore modules and the customization each one supports. - [Customize styles and behavior](/instore/customization/pos-theming.md) to review the tenant theme that the rest of the POS applies. ## Related pages - [Area overview page with navigation](/instore.md) - [Search documentation and API specs](/search.md)