Overview
The Recommendations module provides personalized product recommendations based on user behavior, product affinity, and business rules. It manages fetching, storing, and displaying recommended items.
State
The Recommendations module maintains the following state:
Array of recommended items
status
'initial' | 'loading' | 'success' | 'error'
Current request status
Origin identifier for tracking (defaults to ‘recommendations’)
Additional request parameters
Module configuration options
Configuration
Maximum number of recommendations to request from the API
Getters
Computed recommendations request object built from current state
Mutations
setRecommendations
(state, recommendations: Result[]) => void
Update the recommendations list
updateRecommendation
(state, recommendation: Result) => void
Update a specific recommendation in the list (e.g., for wishlisting)
setStatus
(state, status: Status) => void
Update request status
setParams
(state, params: Record<string, unknown>) => void
Update request parameters
setConfig
(state, config: Partial<RecommendationsConfig>) => void
Update configuration
mergeConfig
(state, config: Partial<RecommendationsConfig>) => void
Merge configuration with existing config
Actions
fetchRecommendations
(context) => Promise<RecommendationsResponse>
Fetch recommendations from the API without updating state
fetchAndSaveRecommendations
(context) => Promise<RecommendationsResponse>
Fetch recommendations and update module state
cancelFetchAndSaveRecommendations
(context) => Promise<void>
Cancel any in-progress recommendations request
Events Emitted
UserClickedARecommendation
{ recommendation: Result }
Emitted when user clicks a recommendation
RecommendationsChanged
{ recommendations: Result[] }
Emitted when recommendations are updated
Usage Examples
Basic Recommendations
import { useStore } from 'vuex'
const store = useStore ()
// Configure recommendations
store . commit ( 'x/recommendations/setConfig' , {
maxItemsToRequest: 12
})
// Fetch recommendations
await store . dispatch ( 'x/recommendations/fetchAndSaveRecommendations' )
// Access recommendations
const recommendations = store . state . x . recommendations . recommendations
Product Detail Page Recommendations
// Set product ID as parameter
store . commit ( 'x/recommendations/setParams' , {
productId: 'product-123'
})
await store . dispatch ( 'x/recommendations/fetchAndSaveRecommendations' )
Update Recommendation State
import type { Result } from '@empathyco/x-types'
// Update a recommendation (e.g., after wishlisting)
const recommendation : Result = store . state . x . recommendations . recommendations [ 0 ]
store . commit ( 'x/recommendations/updateRecommendation' , {
... recommendation ,
isWishlisted: true
})
Component Integration
< template >
< div class = "recommendations" >
< h2 > Recommended for You </ h2 >
< div v-if = " isLoading " class = "loading" >
Loading recommendations...
</ div >
< div v-else-if = " hasRecommendations " class = "recommendations-grid" >
< ProductCard
v-for = " item in recommendations "
: key = " item . id "
: product = " item "
@ click = " onRecommendationClick ( item ) "
@ wishlist = " onWishlistToggle ( item ) "
/>
</ div >
< div v-else class = "no-recommendations" >
No recommendations available
</ div >
</ div >
</ template >
< script setup lang = "ts" >
import { computed , onMounted } from 'vue'
import { useStore } from 'vuex'
import type { Result } from '@empathyco/x-types'
import ProductCard from './ProductCard.vue'
const store = useStore ()
const recommendations = computed (() =>
store . state . x . recommendations . recommendations
)
const isLoading = computed (() =>
store . state . x . recommendations . status === 'loading'
)
const hasRecommendations = computed (() =>
recommendations . value . length > 0
)
onMounted ( async () => {
// Configure and fetch recommendations
store . commit ( 'x/recommendations/setConfig' , {
maxItemsToRequest: 8
})
await store . dispatch ( 'x/recommendations/fetchAndSaveRecommendations' )
})
const onRecommendationClick = ( item : Result ) => {
// Track click event
store . dispatch ( 'x/tagging/track' , {
event: 'UserClickedARecommendation' ,
recommendation: item
})
// Navigate to product page
window . location . href = item . url
}
const onWishlistToggle = ( item : Result ) => {
// Update local state
store . commit ( 'x/recommendations/updateRecommendation' , {
... item ,
isWishlisted: ! item . isWishlisted
})
// Update on backend
// ... API call to toggle wishlist
}
</ script >
Multiple Recommendation Types
< template >
< div >
< RecommendationSection
title = "Similar Products"
: params = " { type: 'similar' , productId: currentProductId } "
/>
< RecommendationSection
title = "Frequently Bought Together"
: params = " { type: 'bundle' , productId: currentProductId } "
/>
< RecommendationSection
title = "Trending Now"
: params = " { type: 'trending' } "
/>
</ div >
</ template >
< script setup lang = "ts" >
import { ref } from 'vue'
import RecommendationSection from './RecommendationSection.vue'
const currentProductId = ref ( 'product-123' )
</ script >
Carousel Integration
< template >
< div class = "recommendations-carousel" >
< h2 > You May Also Like </ h2 >
< div class = "carousel" >
< button
class = "carousel-prev"
@ click = " scrollPrev "
: disabled = " ! canScrollPrev "
>
←
</ button >
< div class = "carousel-track" ref = "trackRef" >
< div
v-for = " item in recommendations "
: key = " item . id "
class = "carousel-item"
>
< ProductCard : product = " item " />
</ div >
</ div >
< button
class = "carousel-next"
@ click = " scrollNext "
: disabled = " ! canScrollNext "
>
→
</ button >
</ div >
</ div >
</ template >
< script setup lang = "ts" >
import { ref , computed , onMounted } from 'vue'
import { useStore } from 'vuex'
import ProductCard from './ProductCard.vue'
const store = useStore ()
const trackRef = ref < HTMLElement >()
const scrollPosition = ref ( 0 )
const recommendations = computed (() =>
store . state . x . recommendations . recommendations
)
const canScrollPrev = computed (() => scrollPosition . value > 0 )
const canScrollNext = computed (() => {
if ( ! trackRef . value ) return false
const maxScroll = trackRef . value . scrollWidth - trackRef . value . clientWidth
return scrollPosition . value < maxScroll
})
const scrollPrev = () => {
if ( trackRef . value ) {
const scrollAmount = trackRef . value . clientWidth
trackRef . value . scrollBy ({ left: - scrollAmount , behavior: 'smooth' })
}
}
const scrollNext = () => {
if ( trackRef . value ) {
const scrollAmount = trackRef . value . clientWidth
trackRef . value . scrollBy ({ left: scrollAmount , behavior: 'smooth' })
}
}
onMounted ( async () => {
await store . dispatch ( 'x/recommendations/fetchAndSaveRecommendations' )
trackRef . value ?. addEventListener ( 'scroll' , () => {
scrollPosition . value = trackRef . value ?. scrollLeft ?? 0
})
})
</ script >
Context-Aware Recommendations
import { computed , watch } from 'vue'
import { useStore } from 'vuex'
import { useRoute } from 'vue-router'
const store = useStore ()
const route = useRoute ()
// Update recommendations based on context
watch (
() => route . params . productId ,
async ( productId ) => {
if ( productId ) {
// Product detail page - show related products
store . commit ( 'x/recommendations/setParams' , {
productId ,
type: 'related'
})
} else if ( route . path === '/cart' ) {
// Cart page - show complementary products
const cartItems = store . state . cart . items
store . commit ( 'x/recommendations/setParams' , {
cartItemIds: cartItems . map ( item => item . id ),
type: 'complementary'
})
} else {
// Home page - show personalized recommendations
store . commit ( 'x/recommendations/setParams' , {
type: 'personalized'
})
}
await store . dispatch ( 'x/recommendations/fetchAndSaveRecommendations' )
},
{ immediate: true }
)
Recommendation Types
Common recommendation types you can request:
Products related to a specific item
Products similar to a specific item
Frequently bought together
Personalized based on user behavior
Currently trending products
Products that complement cart items
Type Reference
Source: /home/daytona/workspace/source/packages/x-components/src/x-modules/recommendations/store/module.ts:1
Resources
x-types Type definitions for recommendations
x-components Component library