Vue.js + 1C-Bitrix: favorites without page reload

The favorites list is lost on page reload — a familiar problem for Bitrix-based online stores. We develop and implement a turnkey Vue.js favorites feature: customers save products without delays, and you get a ready tool for growing repeat sales. Let's discuss your task — we'll come back with an estimate and a work plan.

Our competencies:

Frequently Asked Questions

Favorites on Bitrix with Vue.js: why the list is lost on reload

A classic picture: a user adds a product to favorites, refreshes the page — and the list is empty. The reason is that with Bitrix server-side templates, the favorites state lives only in the current server response.

The component rendered the list, returned the HTML — and that's it, the browser no longer manages anything after that. Any action that reloads the page (navigating to a product page, pagination, returning from the cart) wipes out that state.

With Vue.js the picture changes: favorites become reactive state on the client. The user clicked the heart — the interface updated instantly, without a request to the server and without a reload. But here a second, less obvious problem appears — desynchronization.

If the list is stored only in the tab's memory, it will disappear on refresh and won't appear in a second open tab. It is at this stage that data is most often lost, and it is here that a link between client-side state and server-side storage is needed.

The working scheme looks like this: Vue.js keeps the favorites state in a reactive store, while Bitrix server-side rendering provides the initial list on page load.

After that, every change goes to the backend and is recorded tied to the user — authorized or by an anonymous identifier.

On the next visit, server-side rendering again fills the store with up-to-date data, and the user sees their favorites right away, without flickering or lazy loading.

Synchronization between tabs is handled separately: a change in one tab is picked up in another, so the list does not diverge.

This way, favorites stop being a temporary effect of the page and become persistent state that survives reloads, navigation, and work in multiple windows.

Let's break down how this is handled on real projects.

What the Vue.js and 1C-Bitrix combination gives for favorites

The combination is built as follows: Vue.js keeps the favorites list in reactive state on the client, while 1C-Bitrix Bitrix24 is responsible for storage and synchronization with the user profile.

Clicking the "heart" changes the state instantly — without reloading the page and without waiting for a server response. The write goes out in the background, and the interface is not blocked, even if the connection channel has degraded.

The response stops depending on server-side rendering: the typical "added — saw" scenario fits into fractions of a second instead of the cycle of "request — render — page repaint." This is noticeable in catalogs where the user marks dozens of items in a row: the list does not "jitter," the counter in the header updates immediately, and the "favorites only" filter rebuilds on the client.

Local storage bridges the gap between sessions: while the user is not authorized, the list lives in the browser, and after login it synchronizes with their profile in Bitrix.

Cross-tab synchronization via a broadcast channel keeps two open windows from diverging — you add a product in one, and in the other the counter is already up to date.

The load on the server drops predictably: instead of a full page repaint for every action, one compact request goes out, and repeated openings of the catalog serve the list from local storage.

At peak traffic, this removes part of the database requests and reduces response time for everyone, not just for those who use favorites.

We separately cover the scenarios where this approach breaks down: clearing local storage, logging in from another device, a conflict of list versions.

We describe the conflict resolution logic and merge rules at the design stage — otherwise the user loses the list when switching browsers.

Ways to Store Favorites: Comparing Approaches

The choice of storage determines what happens to favorites when the device changes, the browser is cleared, and the catalog grows.

The server-side scheme on Bitrix information blocks ties the list to an account: a guest adds a product, logs in — and the selection is pulled up on any device. The price for this is a database query for every action and the need for synchronization at login.

Client-side options are faster: localStorage returns data instantly and survives a reload, but it is limited to a few megabytes, synchronously blocks the main thread, and is lost when storage is cleared.

IndexedDB lacks these limitations — it is asynchronous, holds large volumes, and stores not only identifiers but also snapshots of cards. The hybrid scheme combines both worlds: instant response from the browser plus restoring the list from the server after authorization.

Option When it fits Limitations
Bitrix information blocks Authorized users, synchronization between devices Database query for every action, requires binding to an account
localStorage Small lists, guests, simple scenarios Volume limit, synchronous operations, reset when the browser is cleared
IndexedDB Large catalogs, storing card snapshots, offline mode More complex to implement, requires asynchronous work with data
Hybrid storage Stores with guests and authorization, response speed matters Requires logic for merging lists at login and resolving conflicts

In practice, the choice rarely comes down to a single option. For the guest scenario, localStorage is enough; for the authorized one, information blocks; and large catalogs with offline access require IndexedDB.

The hybrid scheme covers both scenarios at once, but adds work on merging data at login — we design this stage separately so that favorites are neither duplicated nor lost.

How we implement favorites on Bitrix with Vue.js: stages of work

We start with an audit of the template: we look at how the catalog output is currently structured, where the cart state is stored, and whether the project has component caching.

At this stage, it is important to find the places where adding favorites will affect the existing logic — otherwise the new functionality breaks what already works.

  1. Audit of the current template. We analyze the page structure, the connected scripts, and the points where product cards are output. We record which blocks are reused and where a separate component will be needed.
  2. Designing the data schema. We determine where the favorites list is stored: in the user profile for authorized users and in the browser's local storage for guests. We think through the scenario for merging the lists when logging into an account so that nothing is lost.
  3. Setting up API exchange. We prepare server-side methods for reading, adding, and removing items. We build the exchange so that the interface does not wait for a full page reload and receives only the changed data.
  4. Integrating the component. We connect the frontend part to the catalog and product card markup, and link it to the server-side methods. The favorites counter and the state of the buttons update immediately, without reloading the page.
  5. Testing. We check the behavior for a guest and an authorized user, the login scenario, and how it works on mobile and on a slow connection. We separately look at what happens when the browser storage is cleared.
  6. Handover and documentation. We provide a description of the data schema, a list of server-side methods, and maintenance instructions so that the client's team can develop the functionality further.

This order makes it possible not to rewrite the entire catalog: the changes affect only the necessary blocks, while the other pages continue to work as before. At the end of each stage, we show the result on a test environment — the client sees progress before the final handover.

What the client receives upon completion

After implementing favorites on Vue.js on top of 1C-Bitrix, the client receives not just a "working block on the site" but a complete set that allows the system to be developed further and handed over to another team without reverse engineering.

  • Component configuration — selection parameters, binding to information blocks, caching settings, and data delivery mode so that favorites do not pull unnecessary database queries.
  • Data exchange schema — a map of routes between the interface and the server: what data goes to the client, what is stored locally, and at what point it syncs with the user account.
  • Data access policies — rules under which the list is visible only to its owner, behavior for guests and authenticated users, and separation by roles and user groups.
  • Documentation — a description of the component structure, extension points, and dependencies so that further development can proceed without the original implementer.
  • Support regulations — the procedure for updating dependencies, checking compatibility with new core versions, and rollback rules in case of regression.
  • Content manager instructions — how to manage the composition and display of favorites without editing code.
  • Acceptance checklist — scenarios for verifying correct operation: adding, removing, syncing between devices, and behavior when a session is lost.

Each artifact addresses its own class of risks: configuration and the exchange schema resolve performance concerns, access policies prevent leaks of other users' lists, and documentation and regulations reduce dependence on a single contractor. Describe your task — we will come back with an estimate and a plan for your project.

Case study: making favorites 4x faster on a high-load portal

The client's portal is a catalog with personal selections: a user would add products to favorites, but the list lived only in the current tab.

After a reload or a repeat login it was reset to zero, and every click on the "heart" went out as a synchronous request to the server — at peak traffic this produced queues, noticeable response delays, and an avalanche of repeated database calls.

Let's break down exactly what was breaking and how it is fixed on the frontend and backend sides.

What it was like before the changes

Favorites were stored in the tab's memory with no link to the profile. Any page refresh wiped the selection, and the server side accepted a separate request for every action — with no batching and no cache.

On a high-load portal this translated into growth in server calls, a performance dip during peak hours, and user complaints about "missing" products.

What was changed

The favorites list was moved to client-side state with persistence between sessions: the selection is tied to the user and restored on the next login, including the guest scenario with subsequent synchronization after authorization.

User actions are accumulated and sent as a batch rather than one by one — the server side receives a single consolidated update instead of a stream of small requests.

For repeat calls, caching was added on the service side so that identical queries are not recalculated from scratch.

Metrics before and after

Metric Before After
Interface response when adding noticeable delay instant, without a reload
Preserving the list between sessions no yes, tied to the profile
Server calls per favorites action baseline level reduced by 60%
Behavior during peak hours request queues stable operation

The project was led by our engineer, who worked with the 1С-Битрикс and Vue.js stack. After implementation, the client's team recorded a 60% reduction in server calls and eliminated the list reset — support stopped receiving complaints about "disappearing" favorites.

How does storing favorites on the client differ from storing them on the server?

Client-side storage is data in the user's browser: localStorage, sessionStorage, or IndexedDB. Favorites are read and written instantly, without contacting the server, so the interface responds to a click immediately, and the load on the backend remains zero.

Vue.js is convenient here thanks to reactivity: a Pinia or Vuex store keeps the list in memory, and a plugin synchronizes it with the browser storage.

The limitations are also honest — the data is tied to a specific device and browser, clearing the cache or incognito mode wipes it, and on another device the user will see an empty list.

Server-side storage moves the list into a database and ties it to an account. This enables device synchronization: you add an item from your phone — you see it on your work computer after logging in.

Data reliability is higher: the record survives clearing the browser, changing devices, and reinstalling the system. The price for this is a network request for every action, response latency, and the need to decide what to do with a guest without authorization.

In practice, the compromise looks like this. For a guest, the list lives in the browser — fast and without unnecessary writes to the database.

On login or registration, the local list merges with the server one: we combine by product identifier, resolve conflicts by modification time, and remove duplicates. After that, the server becomes the source of truth, and client-side storage works as a cache for instant display.

This approach removes the main risk — losing the list when changing devices — and preserves interface speed.

Separately, it is worth thinking through behavior when the server is unavailable: optimistic interface updates with a queue of deferred requests and resending when the connection is restored.

Otherwise, the user either loses the action or sees a desync between what is on the screen and what is in the database.

The choice between client and server is not an "either/or" but a question of where the boundary lies between response speed and the guarantee of data preservation.

Common technical concerns when integrating Vue.js into Bitrix

Vue.js in a Bitrix project almost always lives alongside an existing frontend: jQuery plugins, third-party widgets, counters, legacy custom code in the template.

Conflicts here are not uncommon, but they are predictable and are resolved at the design stage rather than after launch. Below are the points most often raised in technical discussions.

Will Vue.js break the existing scripts on the page?

No, as long as responsibilities are clearly separated. Vue mounts into a specific container and manages only its own section of the markup, without interfering with the DOM outside it. Global libraries continue to work as before.

A conflict is possible in one case — when a third-party plugin and Vue simultaneously modify the same node; we identify such places during template analysis and separate them into different containers.

How does dynamic content coexist with Bitrix caching?

The component cache serves ready-made markup, while the data for Vue is loaded via a separate request after the page has rendered. The cache continues to work, and invalidation is not broken.

For favorites and the cart this is fundamental: the server side is cached, while the client side is updated without a page reload.

Are dynamic blocks indexed by search engines?

Yes, with proper rendering. The first render is served by the server, so the crawler sees the content immediately rather than an empty container. If a block is loaded only on the client, server-side rendering or prerendering is configured for it. We verify the result using crawling tools — not by eye.

What about old browsers and debugging?

The build is transpiled for an agreed-upon list of browsers, so the syntax does not break on older engines. For debugging we enable source maps: an error in the compiled file reads like ordinary component code. This saves hours when investigating incidents in production.

Let's discuss your Bitrix favorites task

To come back with an estimate rather than generalities, we need to understand your current implementation: where the favorites list is stored — in localStorage, in cookies, in a user property, or in a separate table; how it gets into the markup — via a component, a template, or an AJAX handler; and what has already been done with Vue.js if the frontend is partially migrated.

This determines whether we rewrite the existing mechanism or integrate into it without breaking other scenarios.

On the requirements side, it's important to pin down: authorization and guests, synchronization across devices, a limit on the number of items, behavior when a product is removed from the catalog, caching, and how favorites relate to the cart and comparison.

These details define the architecture — whether we serve state via an API or assemble it on the client, and exactly where the boundary between Bitrix and Vue lies.

Describe the task in free form — what exists now, what isn't working, which scenarios should work. We'll come back with an estimate of the work and an implementation plan: phases, timelines, and what will be required from your side.

  • Analysis of the current favorites implementation and integration points with Vue.js
  • Requirements for behavior for guests and authorized users
  • Storage and synchronization scheme for the list across devices
  • Implementation plan with phases and rollout order
  • Estimate of work for each phase
  • List of risks: cache, conflicts with the cart, data migration
  • What we need from your team: access, staging environment, contacts of responsible people

Let's discuss the task — send a description of the current implementation and requirements, and we'll come back with an estimate and a work plan.