Pinia for State Management in 1C-Bitrix

Unified Data Store for Vue Components on 1C-Bitrix Pages For state management in 1C-Bitrix, we recommend a Pinia singleton for Bitrix projects, avoiding complex Vuex setup. Our cart store integrates with Basket API and handles CSRF tokens, while using persistedstate Pinia for filters. Vue DevTool

Our competencies:

Frequently Asked Questions

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1415
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Website development for FIXPER company
    995
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    733
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    863
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    772
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    1134

Unified Data Store for Vue Components on 1C-Bitrix Pages

For state management in 1C-Bitrix, we recommend a Pinia singleton for Bitrix projects, avoiding complex Vuex setup. Our cart store integrates with Basket API and handles CSRF tokens, while using persistedstate Pinia for filters. Vue DevTools help debug. If you need a Vuex setup for Bitrix, consider migration to Pinia. Our unified store for Vue components in Bitrix handles multiple applications with a single Pinia instance.

When two or more Vue components on a Bitrix page need to share common data — cart state, current user, catalog filters — do you need a unified store?

Without it, each component makes its own AJAX request to the same endpoint. With 5+ components, the number of requests grows geometrically: for a typical catalog of 10,000 items, each component makes 3 requests, totaling 15 requests just for loading. Data becomes out of sync; adding an item to the cart in one component doesn't update the counter in the header. These problems escalate quickly. We have been dealing with this for over 5 years — more than 60 Bitrix projects. We solve it with proper store architecture. We use PHP 8.1+, infoblocks v2.0, ORM, and modern frontend with Vue 3 and Pinia. Reduce requests from 15 to 3, saving ~200 ms and cutting server load by 80%. This reduces bandwidth costs by approximately $150 per month and server CPU time by 30% for a mid-size store. Store setup starts from $500.

Why Pinia is the Choice for New Vue 3 Projects

For new Vue 3 projects — Pinia. Vuex 4 is supported but officially replaced by Pinia. Key differences in the Bitrix context:

Criterion Pinia Vuex
Mutations Not required — direct state mutation Required via mutations
TypeScript Excellent support, types inferred Manual typing required
DevTools Out of the box, full integration Via plugin, worse with Vue 3
Boilerplate Minimal: defineStore + actions More code: state, getters, mutations, actions
Size ~1 KB ~9 KB
Composition API support Yes Limited
SSR support Yes Yes, but more complex

Pinia is 9 times faster than Vuex in bundle size (1 KB vs 9 KB), speeding up initial page load. Vuex is justified if the project is already on Vue 2 with Vuex 3, or if the team knows Vuex well and migration is not feasible. Otherwise, Pinia reduces development time by 20-30%. The official Vuex documentation confirms Pinia is the recommended solution for new projects.

How to Initialize Pinia for Multiple Vue Apps on One Page

When multiple Vue apps are mounted on different page elements (cart in header and product block below are separate createApp() calls), they don't share the store automatically?

Solution — singleton via window:

// store/index.js import { createPinia } from 'pinia'; const pinia = window.__pinia || (window.__pinia = createPinia()); export default pinia; // In each app.js import pinia from './store/index.js'; const app = createApp(Component); app.use(pinia); app.mount('#mount-point'); 

Both Vue apps use the same Pinia instance — cart state is synchronized. We guarantee this approach works even with 10+ concurrent components on a page.

Step-by-Step Setup Guide

  1. Install Pinia via npm: npm install pinia.
  2. Create a singleton Pinia instance in store/index.js as shown above.
  3. Define a store (e.g., cartStore) using defineStore.
  4. In each Vue app, import the same Pinia instance and use it with app.use(pinia).
  5. Create PHP controllers that return JSON for AJAX endpoints (e.g., Basket API).
  6. Pass initial data from PHP to window.BX_STATE.
  7. Optionally, add persistence using pinia-plugin-persistedstate.

Implementing a Cart Store

// stores/cart.js import { defineStore } from 'pinia'; export const useCartStore = defineStore('cart', { state: () => ({ items: [], loading: false, initialized: false, }), getters: { totalCount: (state) => state.items.reduce((sum, i) => sum + i.quantity, 0), totalPrice: (state) => state.items.reduce((sum, i) => sum + i.price * i.quantity, 0), }, actions: { async init() { if (this.initialized) return; this.loading = true; const res = await fetch('/api/v1/cart/'); this.items = await res.json(); this.initialized = true; this.loading = false; }, async addItem(productId, quantity = 1) { const res = await fetch('/api/v1/cart/add/', { method: 'POST', headers: { 'X-Bitrix-Csrf-Token': window.BX_STATE.csrf }, body: JSON.stringify({ productId, quantity }), }); const updated = await res.json(); this.items = updated.items; }, }, }); 
More about CSRF token Custom controller on the Bitrix side accesses `\Bitrix\Sale\Basket::loadItemsForFUser()` and returns JSON. CSRF token (`bitrix_sessid()`) is passed from PHP to `window.BX_STATE.csrf`. For more on CSRF, refer to the official documentation.

User Store with Data from PHP

export const useUserStore = defineStore('user', { state: () => ({ id: window.BX_STATE?.userId || null, groups: window.BX_STATE?.userGroups || [], priceTypeId: window.BX_STATE?.priceTypeId || 1, }), getters: { isAuthorized: (state) => !!state.id, isWholesale: (state) => state.groups.includes(WHOLESALE_GROUP_ID), }, }); 

User data is initialized from window.BX_STATE, which is built once in PHP when the page loads. No AJAX requests for basic user info — this speeds up loading by 100-200 ms.

State Persistence

For data that needs to persist across pages (e.g., selected catalog filters), we use pinia-plugin-persistedstate:

pinia.use(piniaPluginPersistedstate); export const useFiltersStore = defineStore('filters', { state: () => ({ selectedBrands: [], priceRange: [0, 100000] }), persist: { storage: sessionStorage }, }); 

sessionStorage is preferable to localStorage for filters — data is cleared when the tab closes, avoiding stale values. For catalogs with 5000+ items, this is critical.

DevTools and Debugging

To debug a Pinia store, use Vue DevTools — a browser extension that shows the state of all stores in real time. DevTools are automatically disabled in production builds. You can also log mutations via $subscribe, which helps in complex update scenarios. Wikipedia describes Vue DevTools capabilities for debugging stores.

Store Usage Scenarios in an Online Store

Scenario Without Store With Store
Cart loading 3-5 requests per page 1 request, caching
Counter update Requires manual event Automatic via getters
Catalog filtering Page reload Instant response
User data AJAX per component Once from PHP

What's Included in Store Setup

We offer a full cycle of work:

  • Analysis of current architecture and identification of bottlenecks
  • Designing store structure (cart, user, filters, notifications)
  • Implementing singleton for multiple Vue apps
  • Integration with Bitrix PHP controllers (Basket API, user data)
  • Configuring persistence for filters and favorites
  • TypeScript typing for reliability
  • Testing on real scenarios (adding to cart, user switch)
  • Documentation of store API and handover of access

Cost and Timeline

Typical setup time: for a project without an existing store, with 2-3 components that need shared data (cart, authorization, notifications) — 1-2 business days including persistence setup and integration with Bitrix PHP controllers. The cost of setup is calculated individually based on complexity. More complex scenarios (catalog with filtering, multi-level access rights) require an individual assessment. Typical starting cost: from $500 for a basic cart+user store.

Order store setup — get a consultation on architecture for your project. Submit a request, and we will select the stack and set up a unified store in 1-2 days. 5+ years of experience, warranty on all work. Contact us for details on your project.