Overview
Composables follow the naming conventionuse* (e.g., useUser, useChannels) and provide reactive state and methods that can be shared across components.
Key Benefits:
- Reusability across components
- Easy to test in isolation
- No boilerplate compared to Vuex
- Type-safe and composable
Core Composables
useUser
Provides access to current user session state and authentication. Source:packages/kolibri/composables/useUser.js
State Properties
User Information:- currentUserId: Current user’s ID (computed)
- username: Current username (computed)
- full_name: User’s full name (computed)
- session: Complete session object (computed)
- sessionId: Session ID (computed)
- kind: Array of user kinds (computed)
- isUserLoggedIn: Whether user is authenticated (computed)
- userFacilityId: User’s facility ID (computed)
- isAdmin: Whether user is admin or superuser (computed)
- isSuperuser: Whether user is superuser (computed)
- isCoach: Whether user is a coach (computed)
- isFacilityCoach: Whether user is facility coach (computed)
- isClassCoach: Whether user is class coach (computed)
- isLearner: Whether user is a learner (computed)
- isFacilityAdmin: Whether user is facility admin (computed)
- canManageContent: Whether user can manage content (computed)
- userPermissions: Object of user permissions (computed)
- userHasPermissions: Whether user has any permissions (computed)
- isAppContext: Whether running in app context (computed)
- isLearnerOnlyImport: Whether facility is learner-only import (computed)
- userKind: Primary user kind (computed)
Methods
login(sessionPayload) Logs in a user.useChannels
Manages channels data with shared state across components. Source:packages/kolibri-common/composables/useChannels.js
State Properties
- channelsMap: Reactive object mapping channel IDs to channel data
- localChannelsCache: Reactive ref containing array of local channels
Methods
fetchChannels(params) Fetches channels from the API.- params: Optional query parameters
- Returns: Promise resolving to array of channels
useTaskPolling
Polls for tasks in a specific queue with automatic lifecycle management. Source:packages/kolibri-common/composables/useTaskPolling.js
State Properties
- tasks: Reactive ref containing array of tasks for the queue
- Polls every 5 seconds
- Automatically starts on component mount
- Automatically stops on component unmount
- Shared polling across multiple components using same queue
- Only one active poller per queue name
useSnackbar
Creates and displays snackbar notifications. Source:packages/kolibri/composables/useSnackbar.js
Methods
createSnackbar(options) Displays a snackbar notification.- text: Notification text (required)
- actionText: Text for action button
- actionCallback: Function to call when action clicked
- autoDismiss: Whether to auto-dismiss (default: true)
- duration: Duration before auto-dismiss in ms
- hideCallback: Function called when snackbar is hidden
Responsive Helpers
useKResponsiveWindow
Provides reactive window size information and breakpoint helpers. Source:kolibri-design-system/lib/composables/useKResponsiveWindow.js
State Properties
All properties are computed refs that update reactively:- windowIsSmall: Window width < 600px (boolean)
- windowIsMedium: Window width >= 600px and < 840px (boolean)
- windowIsLarge: Window width >= 840px (boolean)
- windowBreakpoint: Current breakpoint (0-7)
- windowWidth: Window width in pixels
- windowHeight: Window height in pixels
- 0: < 480px
- 1: < 600px
- 2: < 840px
- 3: < 960px
- 4: < 1280px
- 5: < 1440px
- 6: < 1920px
- 7: >= 1920px
useKResponsiveElement
Provides reactive element size information.Usage in Template
Utility Composables
useFacilities
Manages facilities data. Source:packages/kolibri-common/composables/useFacilities.js
usePreviousRoute
Tracks the previous route for navigation purposes. Source:packages/kolibri-common/composables/usePreviousRoute.js
useNow
Provides a reactive timestamp that updates periodically. Source:packages/kolibri/composables/useNow.js
Creating Custom Composables
Basic Structure
Shared State Pattern
For global state, define refs at module level:With Lifecycle Hooks
Best Practices
- Name consistently: Always use
use*prefix - Keep focused: Each composable should have a single, clear purpose
- Document with JSDoc: Include function and parameter documentation
- Return consistent interface: Return an object with clear, named properties
- Handle cleanup: Use
onUnmountedfor cleanup (event listeners, timers) - Module-level state sparingly: Use only when truly needed globally
- Test in isolation: Write unit tests separate from components
Testing Composables
Migration from Vuex
Vuex is deprecated. Use composables instead:| Vuex | Composables |
|---|---|
store.state.items | const items = ref([]) |
store.getters.itemCount | const itemCount = computed(() => items.value.length) |
store.commit('setItems', data) | items.value = data |
store.dispatch('fetchItems') | async function fetchItems() { ... } |