Setting up Vue Router for SPA on 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1175
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • 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
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Vue Router Setup for SPA on 1C-Bitrix

A user account area, multi-step checkout, filterable catalog — situations where navigation within an interface should not reload the page. Vue Router integrated with Bitrix requires careful configuration: Vue routes must not conflict with Bitrix's URL structure, and the server side must correctly handle direct navigation to SPA links.

History Modes: hash vs history

Hash mode (createWebHashHistory) — URL looks like /lk/#/orders. Advantage: no server configuration required; Bitrix receives a request to /lk/ and never sees the hash. Disadvantage: ugly URLs, bad for SEO (though an account area isn't indexed anyway).

History mode (createWebHistory) — URL like /lk/orders/. Clean URLs, but the server must return the same HTML for all SPA routes. In Bitrix this is solved via urlrewrite.php or .htaccess:

# .htaccess for SPA section /lk/
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /lk/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^ /lk/ [L]
</IfModule>

A rule is added to Bitrix's urlrewrite.php to direct all requests inside /lk/ to a single PHP file — the SPA entry point. That file mounts the Vue application.

Route Structure for an Account Area

const routes = [
    {
        path: '/',
        component: LkLayout,
        children: [
            { path: '', redirect: 'orders' },
            { path: 'orders', component: OrdersList,
              meta: { title: 'My Orders' } },
            { path: 'orders/:id', component: OrderDetail,
              meta: { title: 'Order' } },
            { path: 'profile', component: ProfileEdit,
              meta: { title: 'Profile' } },
            { path: 'addresses', component: AddressList,
              meta: { title: 'Delivery Addresses' } },
        ]
    },
    { path: '/:pathMatch(.*)*', component: NotFound }
];

const router = createRouter({
    history: createWebHistory('/lk/'),
    routes
});

base: '/lk/' in createWebHistory — so Vue Router doesn't get confused with Bitrix URLs higher in the tree.

Guards: Authorization Check

router.beforeEach((to, from, next) => {
    const userStore = useUserStore();
    if (!userStore.isAuthorized) {
        // Redirect to the Bitrix authentication page
        window.location.href = '/auth/?backurl=' + encodeURIComponent(to.fullPath);
        return;
    }
    next();
});

Bitrix manages authentication at the PHP level — if the session has expired, the controller returns 401, the Vue application catches this in an axios interceptor and performs the redirect.

Lazy Route Loading

const OrderDetail = () => import('./pages/OrderDetail.vue');

Each route is a separate chunk. Vite splits the build; the order detail page loads only on first navigation. For an account area with 5–8 pages this reduces the initial load.

Preserving State Between Routes

keep-alive for components that shouldn't be recreated on return — for example, filters in the order list:

<RouterView v-slot="{ Component }">
    <KeepAlive include="OrdersList">
        <component :is="Component" />
    </KeepAlive>
</RouterView>

When returning to the order list — filter state and scroll position are preserved. Data is refreshed via the onActivated hook.

Integration with Bitrix SEO Tools

For SPA pages that need to be indexed (catalog with filters), Vue Router runs in hash mode or Prerender.io / server-side pre-rendering is used. For closed sections (account area) — indexing is not needed, history mode with no restrictions.

Page meta tags on Vue Router navigation — via vue-meta or natively:

router.afterEach((to) => {
    document.title = to.meta.title + ' — My Account';
});

Typical timeline: setting up Vue Router for an account area with 5–7 routes, including guards, lazy loading, and server configuration — 2–3 business days. For complex SPAs with nested routes and multiple authorization levels — 4–6 days.