Cart
This section provides a guide to using the @archibald/cart package, which provides a universal system for managing shopping carts.
Sections
- Architecture: An overview of the headless and event-driven cart system.
- Setup: How to configure the cart module and client.
- Advanced Flows: Understanding the anonymous-to-registered cart merge process.
- Cart Factory: How to use the
CartFactoryto create aCartClient. useCart: Access the current cart state.useCartMutation: Add, update, or remove items.useCartId: Manage the cart ID.useCheckoutMutation: Handle the checkout process.useCartClient(Events): Subscribe to real-time cart events.
Installation
Run following to install @archibald/cart package:
npm install @archibald/cart
High-level Architecture
The @archibald/cart package is a headless library that provides the logic for cart management. It uses a CartFactory to create a CartClient that can be used in both web and native applications.
@archibald/cart
The @archibald/cart package provides:
- Universal Cart Client: A single API for interacting with cart data.
- Isomorphic Cart Logic: Consistent handling of cart lifecycle events.
- Event-Driven Architecture: Allows for real-time UI updates.
- Server-Side Integration: Provides a
CartModulefor connecting to backend providers.
Minimum Setup
Application Side
When setting up the cart package you will need to use the CartFactory to create the client as well as the server module.
For this you may use your own module definition or you can use a predefined one from an integration package (e.g. for commerce).
A) Use an existing definition
Check if any of the existing integration packages for the cart serve your needs and use these as a baseline.
import { CartFactory } from '@archibald/cart';
import { CommerceCart } from '@archibald/commerce/cart';
const Cart = new CartFactory(commerceDefinition);
B) Create your own definition according to the CartDefinition type
In this case you will need to create a zod schema that describes your Cart object, a CartProvider handling the server side logic, as well as a CartAdapter which handles client requests to the provider.
import { CartFactory, type CartDefinition } from '@archibald/cart';
const definition: CartDefinition<typeof yourCartSchema> = {
schema: yourCartSchema,
Adapter: YourCartAdapter,
Provider: process.env.APP_CODE === 'server' ? YourCartProvider : (null as any)
};
const Cart = new CartFactory(definition);
Then you can access the client as well as the server module from the factory. To initialize the CartProvider on the server, a ProductMapper class must be passed.
const CartClient = Cart.createClient({
client: {},
api: api
});
Cart.createModule({ config: () => this.configService.get('hybris.api'), mappers: [CommerceProductMapper] })
To access the CartClient in your application you will also need to pass it to a Data Provider. For the commerce integration this is predefined, however if you are using your own definition you need to create the context provider in accordance to your own schemas and types. Please look at the structure of the commerce CartClientProvider as guidance in that case.
// shop/src/shop/client/components/App.tsx
import { CartClientProvider } from '@archibald/commerce/cart';
function App() {
return (
<ProviderComposer
providers={[
provider(CartClientProvider, { client: CartClient }),
]}
>
<AppLayout>
<AppRoutes />
<DataClientDevtools />
</AppLayout>
</ProviderComposer>
);
}
NodeJS (Server Side)
On the NodeJS we initialize the server module through the Cart factory function that was defined earlier.
Your server logic will run inside your definitions of the CartProvider. In case of using an integration package you just need to load it here.
Pass the ProductMapper and define which fields you want to pass to the getCart requests.
// shop/src/shop/server/module/server.tsx
class Server extends CoreServer {
public async initModules() {
await this.registerModules([
Cart.createModule({
config: () => this.configService.get('hybris.api'),
mappers: [CommerceProductMapper],
fields: 'DEFAULT,' +
'potentialProductPromotions,' +
'appliedProductPromotions,' +
...
}),
]);
}
}