https://makeswift-examples-bigcommerce.vercel.app
In this example, you will learn how to integrate BigCommerce with Makeswift to create a visually editable ecommerce store.
This example includes a home page for listing products by category and a product template page for showing product details.
- BigCommerce StoreFrontAPI: to pull data related to a store in BigCommerce and provide it via React context.
- Makeswift SDK: to register components into Makeswift's visual builder.
To quickly try this example either deploy to Vercel or use our CLI.
If you have already created a BigCommerce store and know you want to use this example, scroll down to "Using your own BigCommerce store."
The deploy link below includes integrations with BigCommerce and Makeswift.
Note During the Makeswift integration we recommend using the the "Ecommerce - BigCommerce" template. It comes prefilled with ecommerce components.
With your deployment completed, take a tour of your ecommerce store
-
Run the Makeswift CLI command
npx makeswift@latest init --template=ecommerce-bigcommerce
Note: the
--template=ecommerce-bigcommerce
above will auto-select the "Ecommerce - Bigcommerce" template in Makeswift and download this example Next.js store to your local machine. -
Log in or sign up for Makeswift
-
Confirm the default env vars provided
Once completed, the CLI runs yarn dev
and opens Makeswift for you. From there you can use provided custom ecommerce components.
After integration, you will be redirected to app.makeswift.com.
-
Navigate to the "Home" page on the left to test out the custom "Header" and "Product list" components
- The "Header" is a functional cart integrated with the BigCommerce API
- The "Product list" is a list of products from BigCommerce. To customize the category or number of visible products, select the "Product list" and update the panels to the right labeled 'Category' and 'Count' respectively.
-
Then, go to the "__product__" page and test out the product-specific components
- This page is also called the product template page because it is the template structure for all product pages.
- The "Add to cart" is a functional button integrated with the BigCommerce API
- All the other components — Product price, Product name, Product images, Product description, and Product breadcrumbs — are composable for creating a custom product page.
Once you have given the example a try it's time to use your own BigCommerce store. Here is a guide on how to set one up.
Note: the env for this example corresponds to the Vercel Commerce BigCommerce example.
-
BIGCOMMERCE_ACCESS_TOKEN
requires an API account- This token needs modify rights on Cart, Checkout, and storefront API Tokens, and read rights on Products and Content.
- The "Access Token" created is the value that is used as
BIGCOMMERCE_ACCESS_TOKEN
-
BIGCOMMERCE_CHANNEL_ID
-
BIGCOMMERCE_STORE_HASH
-
BIGCOMMERCE_CUSTOMER_IMPERSONATION_TOKEN
- This is a JWT. It gives your app access to the storefront API. Use this endpoint to create it. More details can be found here
The example store token was created like so:
curl -H "X-Auth-Token: ipupahkny78rhnuodygnrpvtl8tv0qz" -H "Content-Type: application/json" -X POST -d '{"channel_id":1,"expires_at":1982692202}' https://api.bigcommerce.com/stores/5yjdhtv55p/v3/storefront/api-token
BigCommerce doesn't support localization as a first-class feature.
This example uses the metafields
api to store translations for each locale.
Metafields
are only accessible via API.
This section will show you how to use the management API to add product translations.
Managing metafields
with the Management API requires an API account with product "modify" permissions. This API account should be different than the one used to deploy your site.
Once you have created the new API account you can use it with the curl commands below.
Note Don't forget to replace the PRODUCT_MODIFY_BIGCOMMERCE_ACCESS_TOKEN with the "Access Token" from creating your API account above. This token must have product "modify" permissions.
To create a metafield
you will need a permission_set
, a namespace
, a key
, and a value
.
permission_set
- This determines what APIs have access to this
metafield
. Since we query product data from the storefront API, we will need theread_and_sf_access
permission_set
.
- This determines what APIs have access to this
namespace
- This indicates the locale that this
metafield
belongs to. In our situation, it should match the identifier this translation belongs to. - A translation to Spanish would go under the
es
namespace.
- This indicates the locale that this
key
- The property in our product that this translation corresponds to.
value
- The translated text itself.
Here is an example of how we translated the values in our plant store. Blue Lily is Lirio Azul in Spanish.
To add the metafield
for this translation I used the namespace
of "es", the key
of "name", and the value
of "Lirio Azul".
curl -X POST https://api.bigcommerce.com/stores/5yjdhtv55p/v3/catalog/products/114/metafields \
-H 'Content-Type: application/json' \
-H 'X-Auth-Token: PRODUCT_MODIFY_BIGCOMMERCE_ACCESS_TOKEN'\
-d '{"permission_set":"read_and_sf_access","namespace":"es","key":"name","value":"Lirio Azul"}'
If you make a mistake when adding a metafield
, this curl command can be used to delete the mistaken metafield
. Note the different HTTP method and metafield
id at the end of the URL.
curl -X DELETE https://api.bigcommerce.com/stores/5yjdhtv55p/v3/catalog/products/114/metafields/24 \
-H 'X-Auth-Token: PRODUCT_MODIFY_BIGCOMMERCE_ACCESS_TOKEN'
If you clicked the "Deploy" button earlier you can change the environment variable in vercel.com
If you started out with the CLI you can update the generated .env.local
with any new values from your BigCommerce store.
The example store .env.local
looks like:
MAKESWIFT_SITE_API_KEY=XXX-XXX-XXX
BIGCOMMERCE_ACCESS_TOKEN=ipupahkny78rhnuodygnrpvtl8tv0qz
BIGCOMMERCE_STORE_HASH="5yjdhtv55p"
BIGCOMMERCE_CUSTOMER_IMPERSONATION_TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJjaWQiOjEsImNvcnMiOltdLCJlYXQiOjE5ODI2OTIyMDIsImlhdCI6MTcwNTQzMTAwNSwiaXNzIjoiQkMiLCJzaWQiOjEwMDMwMzgxMzQsInN1YiI6ImVqYnR2d3c3ZzhlejB4MXVuMXhzN2tpaGNnaTRjaTUiLCJzdWJfdHlwZSI6MiwidG9rZW5fdHlwZSI6MX0.uGUbU9ccUlKin4zKYEMkBfqXhRwXbrY6qB8wxCj95Ct0YjUfhcQYO-ppnjc_PW4i00nX4hfu0onQqO2vXTfHTQ"
BIGCOMMERCE_CHANNEL_ID=1536289
If you are struggling to configure these env vars feel free to reach out in our Discord and we will be happy to help!
It's probably a good time to explain what's going on. Here is a point of reference for the technical terms below:
- "dynamic product route"
- This is the Next.js page that creates product pages based on BigCommerce products and our Makeswift template layout
- It can be found here:
/pages/product/[slug].tsx
- Here is more info on dynamic routes
- "optional catch all route"
- This is the Next.js page that creates pages based on pages in your Makeswift site
- It can be found here :
/pages/[[...path]].tsx
- Here is more info on optional catch all routes
The "optional catch all route" uses Next.js' getStaticProps
to get a page snapshot from Makeswift.
const makeswift = new Makeswift(config.makeswift.siteApiKey)
const path = '/' + (ctx.params?.path ?? []).join('/')
const snapshot = await makeswift.getPageSnapshot(path, {
siteVersion: Makeswift.getSiteVersion(ctx.previewData),
})
It also uses getStaticProps
to get product data from BigCommerce.
const products = await getProducts()
Both Makeswift and BigCommerce data is then passed into the Page component via props.
return { props: { snapshot, products } }
And we wrap the MakeswiftPage
with a context provider for our BigCommerce data
export default function Page({ products, snapshot }: Props) {
return (
<ProductsContext.Provider value={products}>
<MakeswiftPage snapshot={snapshot} />
</ProductsContext.Provider>
)
}
The "dynamic product route" uses Next.js' getStaticPaths
API to generate page slugs from BigCommerce products.
export async function getStaticPaths(): Promise<GetStaticPathsResult> {
const products = await getProducts()
return {
paths: products.map(product => ({ params: { slug: product.entityId.toString() } })),
fallback: 'blocking',
}
}
The resulting pages use the same makeswift data from the template (/__product__
) makeswift page.
const makeswift = new Makeswift(config.makeswift.siteApiKey)
const snapshot = await makeswift.getPageSnapshot(config.makeswift.productTemplatePathname, {
siteVersion: Makeswift.getSiteVersion(ctx.previewData),
})
While dynamically pulling different products from BigCommerce based on the slug.
const slug = ctx.params?.slug
/* ... */
const product = await getProduct(Number.parseInt(slug.toString(), 10))
Why is the "dynamic product route" using a low revalidation period when the "optional catch all route" is using on-demand revalidation?
Pages are created in the "optional catch all route" based on pages in a Makeswift site. Since Makeswift is aware of what pages are published it can use on-demand revalidation with an api route in /pages/api/makeswift/[...makeswift].ts
to rebuild pages on publish
Unlike the "optional catch all route", the "dynamic product route" creates pages based on BigCommerce products. These routes are unknown to Makeswift and thus it doesn't revalidate them on-demand. Instead, we use a low revalidation period to update them.
At the time of making this example the BigCommerce Storefront API is readonly and doesn't include cart mutations. In order to keep the BIGCOMMERCE_ACCESS_TOKEN
private we are proxying all BigCommerce Management requests through /page/api/[checkout|cart]
More details on managing carts on a custom storefront can be found here.
With Makeswift, you can give your marketing team hand-crafted, ecommerce building blocks to create a custom store.
To learn more about Makeswift, take a look at the following resources:
You can check out the Makeswift GitHub repository - your feedback and contributions are welcome!