Lab - Create a Mini App

Plan: B2B Developer

Lesson 5 of 25 · 30 min

Introduction

This lab will walk you through setting up a local environment running a lean, single-page React app to integrate with a Stencil storefront and the Buyer Portal app. You’ll use this app to enhance your storefront using data provided by the Buyer Portal.

In this lab, you will:

  • Copy a mini app starting repository
  • Run a local dev server
  • Use storefront scripts to load the app

Prerequisites

  • A BigCommerce sandbox store or trial store
  • B2B Edition enabled in your store
  • A Stencil storefront channel, enabled for B2B
  • A command-line interface on your local machine
  • Node.js 20 or later
  • Git CLI

For following along in the code in future lessons, it’s also helpful to make sure you have a code editor, like VS Code, to open your project once installed.

Node Version Manager (nvm) is the recommended way to install Node.js and allows you to install and use different versions.

With nvm installed, you can install a specific version:

nvm install 20

… and switch to the Node.js runtime of any version you have installed:

nvm use 20

Whether you use nvm or install Node.js via another method, make sure you are running a compatible version:

node -v

The Single-Page App

The application you’ll be setting up is a small, single-page React app. There are multiple frameworks available for building single-page apps. For our use case, we only need to be able to inject React components into an existing page, so we’re using one of the simplest options. The app is bootstrapped using Vite, a popular build tool for modern web projects.

The setup for a similar app of your own is simple, as described in React documentation. Our mini-app was created with npm create vite@latest -- --template react-ts.

The app’s starting state has been stripped back further from the Vite starter template, including removing the default HTML page and App component, as well as tweaking Vite config to make main.tsx an explicit entry point and allow cross-origin requests to the dev server.

See the initial modifications here.

Step 1: Copy the Project

  1. Install degit.
npm install -g degit

degit is a tool for making copies of Git repositories.

  1. Copy the starter project, replacing the path to the working directory with your own path.
degit https://github.com/bigcommerce-edu/lab-b2b-mini-app.git#e-start <directory-name>
  1. Navigate to the new project working directory.
cd <directory-name>
  1. Initialize a Git repository for your project.
git init
git add .
git commit -m "Initial project files"

From here on, we’ll leave managing your project’s source control to you.

Step 2: Run the Dev Server

  1. Install the project dependencies.
npm install
  1. Start the dev server.
npm run dev

Take note of the localhost port displayed in your terminal output. (e.g., http://localhost:5173) Port 5173 is typical, but your port might be different if this port is already taken.

Step 3: Update Storefront Settings

In order to load and initialize the app in your storefront, we’ll take the same strategy as the Buyer Portal itself, using Script Manager.

  1. Log into your BigCommerce control panel.
  2. Navigate to Script Manager.
  3. Create a script with the following settings.
SettingValue
Script nameB2B Mini App
PlacementFooter
LocationAll pages
Script typeScript
  1. Enter the following script content, replacing the port number with the one displayed in your terminal output, if necessary.
<script type="module" src="http://localhost:5173/src/main.tsx"></script>
  1. Save the new script.
  2. Navigate to your Stencil storefront. If your app is loading correctly, you should see the message “B2B custom app initialized” in the console of your browser developer tools.

Console log for app initialization

Troubleshooting

If you don’t see the right message in the console:

  • Make sure you copied the correct project boilerplate. src/main.tsx should contain console.log('B2B custom app initialized');
  • Make sure the dev server process is running in your terminal.
  • Make sure the port number indicated in the terminal output matches your script in Script Manager.
  • Try browsing directly to the script URL (e.g., http://localhost:5173/src/main.tsx) in your browser to verify it is served correctly.
  • Check for any errors in the browser developer tools console.

Step 4: Implement a useB2B Hook

Our mini-app will need to access the window.b2b object but can only do so after the Buyer Portal has initialized. The cleanest way to handle this is to centralize the logic into a custom React hook.

  1. Open src/hooks/useB2B.ts and implement the logic in the existing useB2B hook.
useB2B.ts
const useB2B = () => {
const [b2bSdk, setB2bSdk] = useState<B2BSdk | null>(null);
useEffect(() => {
const interval = setInterval(() => {
if (window.b2b?.utils) {
console.log('B2B utils are available');
setB2bSdk(window.b2b);
clearInterval(interval);
}
}, 100);
return () => {
clearInterval(interval);
};
}, []);
return b2bSdk;
};

useB2B.ts contains some simple type definitions to let TypeScript know what window.b2b looks like. The hook we’ve implemented simply uses a check on a short interval to set a piece of React state as soon as window.b2b.utils is available.

With this hook in place, any component in the app simply needs to invoke it to access b2b and all its methods. By virtue of standard React patterns, any such components will re-render as necessary as soon as the state value in the hook is updated. These componens won’t need to concern themselves with the details of waiting for the Buyer Portal to initialize.

  1. Open src/main.tsx and remove the console.log statement.
main.tsx
/* Remove this
console.log('B2B custom app initialized');
*/
  1. Import the hook and initialize a temporary React component in order to test the hook.
main.tsx
import useB2B from './hooks/useB2B';
// TODO: Remove this once the components are implemented
const TestApp = () => {
const b2b = useB2B();
return null;
}
const body = document.querySelector('body');
if (body) {
const b2bRoot = document.createElement('div');
body.appendChild(b2bRoot);
createRoot(b2bRoot).render(
<StrictMode>
<TestApp />
</StrictMode>,
);
}

The above code creates a root element and appends it to the bottom of the page, then uses a standard pattern to render React into that element.

With this in place, the messsage logged to your browser console should now be “B2B utils are available”, indicating that the Buyer Portal is initialized and the app is ready to use.

Resources