diff --git a/framework/bigcommerce/index.tsx b/framework/bigcommerce/index.tsx
index a4271226e..4f6c9316b 100644
--- a/framework/bigcommerce/index.tsx
+++ b/framework/bigcommerce/index.tsx
@@ -5,10 +5,10 @@ import {
   CommerceConfig,
   CommerceProvider as CoreCommerceProvider,
   useCommerce as useCoreCommerce,
-  HookHandler,
 } from '@commerce'
 import { FetcherError } from '@commerce/utils/errors'
-import type { CartInput } from '@commerce/cart/use-cart'
+import type { HookHandler } from '@commerce/utils/types'
+import type { FetchCartInput } from '@commerce/cart/use-cart'
 import { normalizeCart } from './lib/normalize'
 import { Cart } from './types'
 
@@ -51,7 +51,8 @@ const fetcher: Fetcher<any> = async ({
 
 const useCart: HookHandler<
   Cart | null,
-  CartInput,
+  [],
+  FetchCartInput,
   any,
   any,
   { isEmpty?: boolean }
@@ -63,9 +64,6 @@ const useCart: HookHandler<
   swrOptions: {
     revalidateOnFocus: false,
   },
-  // fetcher(context) {
-  //   return undefined as any
-  // },
   normalizer: normalizeCart,
   onResponse(response) {
     return Object.create(response, {
diff --git a/framework/commerce/cart/use-cart.tsx b/framework/commerce/cart/use-cart.tsx
index 77271b593..7c6730497 100644
--- a/framework/commerce/cart/use-cart.tsx
+++ b/framework/commerce/cart/use-cart.tsx
@@ -6,7 +6,7 @@ import useData from '../utils/use-data-2'
 import { Provider, useCommerce } from '..'
 
 // Input expected by the `useCart` hook
-export type CartInput = {
+export type FetchCartInput = {
   cartId?: Cart['id']
 }
 
@@ -14,9 +14,15 @@ export type CartResponse<P extends Provider> = ReturnType<
   NonNullable<NonNullable<NonNullable<P['cart']>['useCart']>['onResponse']>
 >
 
-export type UseCart<P extends Provider> = () => CartResponse<P>
+export type UseCart<P extends Provider> = (
+  ...input: UseCartInput<P>
+) => CartResponse<P>
 
-export const fetcher: HookFetcherFn<Cart | null, CartInput> = async ({
+export type UseCartInput<P extends Provider> = NonNullable<
+  NonNullable<NonNullable<NonNullable<P['cart']>['useCart']>>['input']
+>
+
+export const fetcher: HookFetcherFn<Cart | null, FetchCartInput> = async ({
   options,
   input: { cartId },
   fetch,
@@ -26,7 +32,7 @@ export const fetcher: HookFetcherFn<Cart | null, CartInput> = async ({
   return data && normalize ? normalize(data) : data
 }
 
-export default function useCart<P extends Provider>() {
+export default function useCart<P extends Provider>(...input: UseCartInput<P>) {
   const { providerRef, cartCookie } = useCommerce<P>()
 
   const provider = providerRef.current
@@ -36,7 +42,7 @@ export default function useCart<P extends Provider>() {
     context.input.cartId = Cookies.get(cartCookie)
     return fetcherFn(context)
   }
-  const response = useData(opts!, [], wrapper, opts?.swrOptions)
+  const response = useData(opts!, input, wrapper, opts?.swrOptions)
   const memoizedResponse = useMemo(
     () => (opts?.onResponse ? opts.onResponse(response) : response),
     [response]
diff --git a/framework/commerce/index.tsx b/framework/commerce/index.tsx
index bc660b1df..f329c8054 100644
--- a/framework/commerce/index.tsx
+++ b/framework/commerce/index.tsx
@@ -7,27 +7,16 @@ import {
   useRef,
 } from 'react'
 import * as React from 'react'
-import { Fetcher, HookFetcherFn, HookFetcherOptions } from './utils/types'
+import { Fetcher, HookHandler } from './utils/types'
 import { Cart } from './types'
-import type { ResponseState, SwrOptions } from './utils/use-data'
-import type { CartInput } from './cart/use-cart'
+import type { FetchCartInput } from './cart/use-cart'
 
 const Commerce = createContext<CommerceContextValue<any> | {}>({})
 
 export type Provider = CommerceConfig & {
   cart?: {
-    useCart?: HookHandler<Cart | null, CartInput>
+    useCart?: HookHandler<Cart | null, [...any], FetchCartInput>
   }
-  cartNormalizer(data: any): Cart
-}
-
-export type HookHandler<Data, Input, Result = any, Body = any, State = {}> = {
-  swrOptions?: SwrOptions<Data, Input, Result>
-  onResponse?(response: ResponseState<Data>): ResponseState<Data> & State
-  onMutation?: any
-  fetchOptions?: HookFetcherOptions
-  fetcher?: HookFetcherFn<Data, Input, Result, Body>
-  normalizer?(data: Result): Data
 }
 
 export type CommerceProps<P extends Provider> = {
diff --git a/framework/commerce/utils/types.ts b/framework/commerce/utils/types.ts
index 3428b5194..bef1f2d8b 100644
--- a/framework/commerce/utils/types.ts
+++ b/framework/commerce/utils/types.ts
@@ -1,3 +1,7 @@
+import type { ResponseState, SwrOptions } from './use-data'
+
+export type Override<T, K> = Omit<T, keyof K> & K
+
 // Core fetcher added by CommerceProvider
 export type Fetcher<T> = (options: FetcherOptions) => T | Promise<T>
 
@@ -15,7 +19,12 @@ export type HookFetcher<Data, Input = null, Result = any> = (
   fetch: <T = Result, Body = any>(options: FetcherOptions<Body>) => Promise<T>
 ) => Data | Promise<Data>
 
-export type HookFetcherFn<Data, Input, Result = any, Body = any> = (context: {
+export type HookFetcherFn<
+  Data,
+  Input = unknown,
+  Result = any,
+  Body = any
+> = (context: {
   options: HookFetcherOptions | null
   input: Input
   fetch: <T = Result, B = Body>(options: FetcherOptions<B>) => Promise<T>
@@ -30,4 +39,25 @@ export type HookFetcherOptions = {
 
 export type HookInput = [string, string | number | boolean | undefined][]
 
-export type Override<T, K> = Omit<T, keyof K> & K
+export type HookHandler<
+  // Data obj returned by the hook and fetch operation
+  Data,
+  // Input expected by the hook
+  Input = [...any],
+  // Input expected before doing a fetch operation
+  FetchInput = unknown,
+  // Data returned by the API after a fetch operation
+  Result = any,
+  // Body expected by the API endpoint
+  Body = any,
+  // Custom state added to the response object of SWR
+  State = {}
+> = {
+  input?: Input
+  swrOptions?: SwrOptions<Data, FetchInput, Result>
+  onResponse?(response: ResponseState<Data>): ResponseState<Data> & State
+  onMutation?: any
+  fetchOptions?: HookFetcherOptions
+  fetcher?: HookFetcherFn<Data, FetchInput, Result, Body>
+  normalizer?(data: Result): Data
+}
diff --git a/framework/commerce/utils/use-data-2.ts b/framework/commerce/utils/use-data-2.ts
index 76fce8960..840251409 100644
--- a/framework/commerce/utils/use-data-2.ts
+++ b/framework/commerce/utils/use-data-2.ts
@@ -1,8 +1,13 @@
 import useSWR, { ConfigInterface, responseInterface } from 'swr'
-import type { HookInput, HookFetcher, HookFetcherFn } from './types'
+import type {
+  HookHandler,
+  HookInput,
+  HookFetcher,
+  HookFetcherFn,
+} from './types'
 import defineProperty from './define-property'
 import { CommerceError } from './errors'
-import { HookHandler, useCommerce } from '..'
+import { useCommerce } from '..'
 
 export type SwrOptions<Data, Input = null, Result = any> = ConfigInterface<
   Data,
@@ -14,11 +19,17 @@ export type ResponseState<Result> = responseInterface<Result, CommerceError> & {
   isLoading: boolean
 }
 
-export type UseData = <Data = any, Input = null, Result = any>(
-  options: HookHandler<Data, Input, Result>,
+export type UseData = <
+  Data = any,
+  Input = [...any],
+  FetchInput = unknown,
+  Result = any,
+  Body = any
+>(
+  options: HookHandler<Data, Input, FetchInput, Result, Body>,
   input: HookInput,
-  fetcherFn: HookFetcherFn<Data, Input, Result>,
-  swrOptions?: SwrOptions<Data, Input, Result>
+  fetcherFn: HookFetcherFn<Data, FetchInput, Result, Body>,
+  swrOptions?: SwrOptions<Data, FetchInput, Result>
 ) => ResponseState<Data>
 
 const useData: UseData = (options, input, fetcherFn, swrOptions) => {