User Account Development with Vue.js for 1C-Bitrix
The user account is a section where SEO does not matter, but speed and usability do. It is an ideal candidate for a Vue SPA migration: navigation without page reloads, instant feedback on actions, and the ability to use push notifications.
User Account Structure
Typical account sections in a Bitrix online store:
-
Order history — list from
b_sale_order+ detail fromb_sale_order_props,b_sale_basket -
Profile — data from
b_user, extra fields fromb_uts_useror user properties -
Address book — locations from
b_sale_location, custom addresses -
Wishlist — custom table or
b_iblock_element_propertywith user type -
Loyalty program — data from the
loyaltymodule or custom tables
Initialization: Passing User Data
The Bitrix server passes the authenticated user's data when the account page loads:
// In the /personal/ section template
if (!$USER->IsAuthorized()) {
LocalRedirect('/auth/?backurl=/personal/');
}
$currentUser = [
'id' => $USER->GetID(),
'name' => $USER->GetFullName(),
'email' => $USER->GetEmail(),
'groups' => $USER->GetUserGroupArray(),
];
echo '<div id="lk-app" data-user="' . htmlspecialchars(json_encode($currentUser)) . '"></div>';
Vue reads from dataset.user and initializes the auth store without an additional request.
API for Account Sections
Each section has its own controller:
// Orders controller
class OrderController extends \Bitrix\Main\Engine\Controller
{
public function listAction(int $page = 1): array
{
$userId = $this->getCurrentUser()->getId();
// Query from b_sale_order WHERE USER_ID = $userId
// LIMIT 10 OFFSET ($page-1)*10
}
public function detailAction(int $orderId): array
{
// Verify the order belongs to the current user — mandatory
$order = \Bitrix\Sale\Order::load($orderId);
if ($order->getUserId() !== $this->getCurrentUser()->getId()) {
throw new \Bitrix\Main\AccessDeniedException();
}
}
}
Ownership verification is critical — without it, an IDOR vulnerability exists.
Navigation via Vue Router
const routes = [
{ path: '/personal/', component: Dashboard },
{ path: '/personal/orders/', component: OrderList },
{ path: '/personal/orders/:id/', component: OrderDetail },
{ path: '/personal/profile/', component: ProfileEdit },
{ path: '/personal/wishlist/', component: Wishlist },
];
Bitrix is configured to serve a single template for all /personal/* URLs.
Real-World Case
An industrial equipment distributor: an account with 6 sections, including sub-account management (a manager sees orders of their clients) and document management (downloading invoices and certificates as PDF). The standard Bitrix account on server-side components: each navigation — a new page load taking 1.5–3 seconds. Vue SPA: transitions between sections are instant, data is cached in Pinia for 5 minutes, PDF generation via background job with polling-based notifications.
Delivery Timelines
| Scale | Timeline |
|---|---|
| Basic account (orders, profile, addresses) | 8 to 12 business days |
| With loyalty program and wishlist | 12 to 18 business days |
| B2B account with sub-accounts and document management | 25 to 40 business days |







