Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,8 @@ B2B_API_HOST=https://api-b2b.bigcommerce.com
B2B_API_TOKEN=

# URL for the local buyer portal instance. Uncomment if developing locally.
# LOCAL_BUYER_PORTAL_HOST=http://localhost:3001
# LOCAL_BUYER_PORTAL_HOST=http://localhost:3001

# Base URL for a production build of Buyer Portal. Uncomment if connecting to a deployed custom Buyer Portal.
# Example URL format: ${PROD_BUYER_PORTAL_BASE_URL}/index.js
# PROD_BUYER_PORTAL_BASE_URL=https://my-b2b-catalyst.com/b2b/20260101
15 changes: 15 additions & 0 deletions core/b2b/loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import { auth } from '~/auth';

import { ScriptDev } from './script-dev';
import { ScriptProduction } from './script-production';
import { ScriptProductionCustom } from './script-production-custom';

const EnvironmentSchema = z.object({
BIGCOMMERCE_STORE_HASH: z.string({ message: 'BIGCOMMERCE_STORE_HASH is required' }),
BIGCOMMERCE_CHANNEL_ID: z.string({ message: 'BIGCOMMERCE_CHANNEL_ID is required' }),
LOCAL_BUYER_PORTAL_HOST: z.string().url().optional(),
PROD_BUYER_PORTAL_BASE_URL: z.string().url().optional(),
STAGING_B2B_CDN_ORIGIN: z.string().optional(),
});

Expand All @@ -17,6 +19,7 @@ export async function B2BLoader() {
BIGCOMMERCE_STORE_HASH,
BIGCOMMERCE_CHANNEL_ID,
LOCAL_BUYER_PORTAL_HOST,
PROD_BUYER_PORTAL_BASE_URL,
STAGING_B2B_CDN_ORIGIN,
} = EnvironmentSchema.parse(process.env);

Expand All @@ -33,6 +36,18 @@ export async function B2BLoader() {
/>
);
}

if (PROD_BUYER_PORTAL_BASE_URL) {
return (
<ScriptProductionCustom
cartId={session?.user?.cartId}
channelId={BIGCOMMERCE_CHANNEL_ID}
storeHash={BIGCOMMERCE_STORE_HASH}
token={session?.b2bToken}
prodUrl={PROD_BUYER_PORTAL_BASE_URL}
/>
);
}

const environment = STAGING_B2B_CDN_ORIGIN === 'true' ? 'staging' : 'production';

Expand Down
67 changes: 67 additions & 0 deletions core/b2b/script-production-custom.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
'use client';

import Script from 'next/script';

import { useB2BAuth } from './use-b2b-auth';
import { useB2BCart } from './use-b2b-cart';

/**
* Use these vars if using build hashes in B2B Buyer Portal files.
*/
const hashIndex = null;
const hashIndexLegacy = null;
const hashPolyfills = null;
Comment on lines +11 to +13

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the idea that the hashes are hard coded - so that they can be versioned through the code?

I guess that would make it easier if you open a PR - you can test out the custom build without having to change env vars for that branch alone.

Suggested change
const hashIndex = null;
const hashIndexLegacy = null;
const hashPolyfills = null;
const hashIndex: string | null = null;
const hashIndexLegacy: string | null = null;
const hashPolyfills: string | null = null;

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Matt and I had some discussion about this, and for now it didn't seem like it was worthwhile to represent these as environment vars. What we expect to be a common workflow is for devs to deploy their custom Buyer Portal build files with Catalyst (as static files in public), so a new code deployment is commonly needed anyway. (And having the hashes in env vars actually means a code re-deploy and then another re-deploy after updating vars.)

What I opted to do instead was just separate them out very conspicuously in this file.


interface Props {
storeHash: string;
channelId: string;
token?: string;
cartId?: string | null;
prodUrl: string;
}

export function ScriptProductionCustom({
cartId,
storeHash,
channelId,
token,
prodUrl,
}: Props) {
useB2BAuth(token);
useB2BCart(cartId);

return (
<>
<Script>
{`
window.b3CheckoutConfig = {
routes: {
dashboard: '/#/dashboard',
},
}
window.B3 = {
setting: {
store_hash: '${storeHash}',
channel_id: ${channelId},
},
}
`}
</Script>
<Script
type="module"
crossOrigin=""
src={`${prodUrl}/index${hashIndex ? `.${hashIndex}` : ''}.js`}
></Script>
<Script
noModule
crossOrigin=""
src={`${prodUrl}/polyfills-legacy${hashPolyfills ? `.${hashPolyfills}` : ''}.js`}
></Script>
<Script
noModule
crossOrigin=""
src={`${prodUrl}/index-legacy${hashIndexLegacy ? `.${hashIndexLegacy}` : ''}.js`}
></Script>
</>
);
}
Loading