> This page is for Developer.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.bigcommerce.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.bigcommerce.com/_mcp/server.

# 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](/developer/docs/overview/sandboxes) or [trial store](https://www.bigcommerce.com/essentials/)
* B2B Edition enabled in your store
* A Stencil storefront channel, enabled for B2B
* A command-line interface on your local machine
* Node.js 20.19+ or 22.12+
* [Git CLI](https://git-scm.com/)

For following along in the code in future lessons, it's also helpful to make sure you have a code editor, like [VS Code](https://code.visualstudio.com/), to open your project once installed.

> **Info**
>
> [Node Version Manager](https://github.com/nvm-sh/nvm) (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 22`
>
> ... and switch to the Node.js runtime of any version you have installed:
>
> `nvm use 22`
>
> 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](https://vite.dev/), a popular build tool for modern web projects.

The setup for a similar app of your own is simple, as described in [React documentation](https://react.dev/learn/build-a-react-app-from-scratch). 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](https://github.com/bigcommerce-edu/lab-b2b-mini-app/compare/e-cleanup-pre...e-cleanup-post?diff=split).

## Step 1: Copy the Project

1. **Install** `degit`.

```shell showLineNumbers={false}
npm install -g degit
```

> **Info**
>
> [`degit`](https://github.com/Rich-Harris/degit) is a tool for making copies of Git repositories.

2. **Copy** the starter project, replacing the path to the working directory with your own path.

```shell showLineNumbers={false}
degit https://github.com/bigcommerce-edu/lab-b2b-mini-app.git#e-start <directory-name>
```

3. **Navigate** to the new project working directory.

```shell showLineNumbers={false}
cd <directory-name>
```

4. **Initialize** a Git repository for your project.

```shell showLineNumbers={false}
git init
git add .
git commit -m "Initial project files"
```

> **Info**
>
> 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.

```shell showLineNumbers={false}
npm install
```

2. **Start** the dev server.

```shell showLineNumbers={false}
npm run dev
```

> **Info**
>
> 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.

| Setting     | Value        |
| ----------- | ------------ |
| Script name | B2B Mini App |
| Placement   | Footer       |
| Location    | All pages    |
| Script type | Script       |

4. **Enter** the following script content, replacing the port number with the one displayed in your terminal output, if necessary.

```html showLineNumbers={false}
<script type="module" src="http://localhost:5173/src/main.tsx"></script>
```

5. **Save** the new script.
6. **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](/_fern-img/b819f47ebc447f2e08806fc8ec370de394a98f85a63d56d96b98734949f96dda.webp)

> **Info**
>
> **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`**

```ts {2-18} title="useB2B.ts" showLineNumbers={false}
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.

2. **Open** `src/main.tsx` and **remove** the `console.log` statement.

**`main.tsx`**

```tsx showLineNumbers={false} title="main.tsx"
/* Remove this
console.log('B2B custom app initialized');
*/
```

3. **Import** the hook and **initialize** a temporary React component in order to test the hook.

**`main.tsx`**

```tsx showLineNumbers={false} title="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.**

> **Info**
>
> [**View the Code**](https://github.com/bigcommerce-edu/lab-b2b-mini-app/compare/e-hook-pre...e-hook-post?diff=split)

## Resources

* [Vite](https://vite.dev/)
* [Create a React App](https://react.dev/learn/build-a-react-app-from-scratch)
* [`degit`](https://github.com/Rich-Harris/degit)