Getting Started
To start using our SDK you must first construct a client. The client is the main entry point for working with Bundles and the Workflow Experiences inside them. This object acts as a factory for building bundles & workflows, and validates your access to the products and workflows you want to use.
Constructing a Client
The process for building a client is simple. First you'll need to pull the core SDK into your package. Check out the NPM package here
yarn add @spiffcommerce/core@latest
You can then construct a client and create a bundle. You'll need an application key to do this. You can get one by by creating an account on Spiff Commerce Hub and creating a new integration to represent your new application.
import { SpiffCommerceClient } from "@spiffcommerce/core";
// This constructs a new client with the given API Key
const client = new SpiffCommerceClient({ applicationKey: "0123456789" });
Once built the client should be stored for the lifetime of the users current visit. The client will manage authentication, initialization of product details and workflows.
Activations
An Activation represents a single deployment of a theme, linking it to one or more product collections and its configuration. Every bundle you create should be created within an activation. When your theme is launched by Spiff Commerce, the active activation is provided on the theme context. See Themes for details.
Creating a Bundle
Everything a customer designs lives in a Bundle. Create one by calling getNewBundle on the client, passing the product collection and the activation it belongs to. Be sure to await the call.
const bundle = await client.getNewBundle(
productCollectionId, // Optional: The product collection the customer will choose products from.
{ "my-key": "my-value" }, // Optional: Initial metadata for the bundle.
{}, // Optional: GetBundleOptions
activationId, // Optional: The activation this bundle belongs to.
);
To return to a bundle later, save its ID and reload it with getExistingBundle:
const bundleId = bundle.getId();
const existingBundle = await client.getExistingBundle(bundleId);
See Bundles for more.
Creating Workflow Experiences
Before requesting an experience it's important to begin familiarizing yourself with the terminology we use. Workflows represent a core concept of our platform, make sure you understand their purpose before continuing. Other important concepts include scenes, steps and conditions.
Use the client to get Workflow Experiences, then add them to your bundle. Always use the list-based getWorkflowExperiences and addWorkflowExperiences, even for a single product. They behave identically for one item, and fewer requests are made when you pass several at once. Be sure to await both calls. Failing to do so may mean that interactions with the design will error or cause issues with correctly displaying the initial state.
Be sure to have your product associated with your integration, and that the workflow you want to use is associated with that product. You'll need the product's integration ID, as well as the workflow's to request an experience. You can find the product's integration ID on the integration page, under the "Products" section. See the API reference for more details.
Pass an array of GetWorkflowOptions objects. The function returns an array of workflow experiences in the same order as the options you passed in. All options that request a new transaction are batched together. If any of these fail, no transactions will be created.
const experiences = await client.getWorkflowExperiences(
[
{
type: "integration",
integrationProductId: "0123456789",
workflowId: "0123456789",
},
{
type: "integration",
integrationProductId: "9876543210",
workflowId: "9876543210",
},
],
{
assets: {
metadata: true, // Optional: Whether to include metadata in the response. Defaults to false.
},
},
);
await bundle.addWorkflowExperiences(experiences);
Getting Active Steps
Once you have a workflow experience you can get the steps that are available to the user. These steps represent the individual customizations a user can make to the product.
As the user makes selections the list of available steps can change. This is due to a system we call conditions. To know when the list of steps has changed due to a condition you can attach a listener to the experience. You should only render steps that are listed here to ensure the user can't interact with steps that are conditionally inactive.
// This listener will be called each time a change occurs to the list of steps that are active.
const onScenesChange = (scenes: RenderableScene[]) => {
const renderableSteps = scenes.flatMap((s) => s.renderableSteps);
const steps = workflowExperience.getSteps().filter((s) => renderableSteps.includes(s.getId()));
this.steps = steps;
};
// Attach the listener right after the experience is constructed.
workflowExperience.attachRenderableSceneListener(onScenesChange);
// Later on...
// Detach when you no longer want to be updated or before disposing of a function.
workflowExperience.detachRenderableSceneListener(onScenesChange);
Rendering Steps
Each step should map to a UI component in your frontend system. Typically you will loop over the list of renderable steps in fashion similar to below. An example is included of how this may look in react. Step handles contain a number of functions that can be used to interact with the step. Each type of step also has specific functionality as well.
See here for more information on handles and what kind of functionality you can use.
const steps = this.steps.map((step) => {
return <StepComponent step={step} />;
});
Most steps have variants that the user may choose from. You can get the list of variants for a step by calling getAvailableVariants on the step. You can also get the currently selected variant by calling getCurrentVariant on the step.
// To list the currently available variants for a step.
const variants = step.getAvailableVariants();
// To select a variant, this will update the user selection for that step and change the design.
step.selectVariant(variant);
Often you will want to display a configured thumbnail for each variant on the step in some form of list or gallery. You can get the thumbnail for a variant by calling getThumbnail on the step handle.
const thumbnail = variant.getThumbnail();
// What you get is a href value similar to this "https://assets.us.spiffcommerce.com/my-cool-asset.png" You may use it like this.
<img href={thumbnail} />;
To learn more about the step interface see the step handles documentation.
Finishing a Bundle
When the customer is ready to submit their designs, call finish on the bundle. You may pass a callback that is called with a progress string as the designs are submitted, which is useful for updating a progress bar.
const message = await bundle.finish((progressText: string) => {
console.log(progressText);
});
The returned BundleDesignCreationMessage contains the bundle ID and one line item per design in items, each including its transaction ID. When you place an order into your store you need to annotate the line items with these IDs. When your e-commerce platform calls us about an order being placed we'll look for them and use them to associate the order with the designs in our back end. Inside a theme, pass the message to SpiffThemeLoader.addToEcommerceCart() and it will be handled for you. See Order Submission for more.
Placing an Order
If you are not using one of our e-commerce integrations, you can place an order for every item in the bundle by calling placeOrder:
const order = await bundle.placeOrder();
You can also place an order manually using the GraphQL API.