Mobile Web Setup and Vue.js Dynamic Route & Vuex State Hydration

Configuring the Mobile Viewport

When developing web applications for mobile devices, it is crucial to prevent unintended user scaling to maintain a consistent UI. This is achieved by configuring the viewport meta tag in the HTML head.

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>

Additional, setting up a responsive foundation using rem units requires defining a base font size on the root element. By setting the root font size to 100px, component styling becomes straightforward (e.g., 0.16rem equals 16px).

html {
    font-size: 100px;
    height: 100%;
}
body {
    height: 100%;
    margin: 0;
    font-size: 0.16rem;
}

Injecting Dynamic Routes

In Vue Router, routes fetched asynchronously must be injected into the router instance both after a successful login and when the application reloads to persist navigation state.

Route Injection on Authentication

After validating user credentials, parse the asynchronous route configuration to resolve component paths, persist the authentication token, and append the routes dynamically.

const asyncNavConfig = await fetchRouteDefinitions();

asyncNavConfig.forEach(routeDef => {
  const componentPath = routeDef.componentPath;
  routeDef.component = (resolve) => require([`@/views/${componentPath}`], resolve);
});

window.sessionStorage.setItem('authToken', 'user_token_value');
this.$router.addRoutes(asyncNavConfig);

Route Restoration on Page Refresh

To ansure dynamically added routes survive a browser refresh, the router configuraton file must check for an existing token and re-inject the routes before the application mounts.

if (window.sessionStorage.getItem('authToken')) {
  const dynamicRoutes = await fetchRouteDefinitions();

  dynamicRoutes.forEach(routeDef => {
    const componentPath = routeDef.componentPath;
    routeDef.component = (resolve) => require([`@/views/${componentPath}`], resolve);
  });

  router.addRoutes(dynamicRoutes);
}

Hydrating Vuex State on Refresh

Vuex state resets when the page reloads. To hydrate the store with necessary data, use the beforeEach navigation guard to await state restoration before resolving the route.

import Vue from 'vue';
import Router from 'vue-router';
import HomeView from '@/views/HomeView';
import store from '@/store';

Vue.use(Router);

const router = new Router({
  routes: [
    { path: '/', redirect: '/home' },
    { name: 'HomeView', path: '/home', component: HomeView }
  ]
});

if (window.sessionStorage.getItem('authToken')) {
  setTimeout(() => { // Simulating asynchronous route fetch
    const fetchedRoutes = getAsyncRoutes();
    fetchedRoutes.forEach(r => {
      r.component = (resolve) => require([`@/views/${r.componentPath}`], resolve);
    });
    router.addRoutes(fetchedRoutes);
  }, 1000);
}

router.beforeEach(async (to, from, next) => {
  if (window.sessionStorage.getItem('authToken')) {
    await new Promise(resolve => {
      setTimeout(() => { // Simulating asynchronous state fetch
        const statePayload = retrieveStorePayload();
        store.commit('hydrateState', statePayload);
        resolve();
      }, 500);
    });
  }
  next();
});

export default router;

Handling Unauthorized API Responses

Configure Axios interceptors to monitor API responses. If an authentication failure or session expiration is detected, automatically redirect the user back to the login interface.

import Vue from "vue";
import Axios from "axios";
import router from "@/router";

Axios.interceptors.request.use(
  config => config,
  error => Promise.reject(error)
);

Axios.interceptors.response.use(
  response => {
    if (response.data.authError) {
      if (router.currentRoute.path !== "/auth/login") {
        router.push({ name: "LoginView" });
      }
    }
    return response;
  },
  error => {
    if (router.currentRoute.path !== "/auth/login") {
      router.push({ name: "LoginView" });
    }
    return Promise.reject(error);
  }
);

Vue.prototype.$axios = Axios;

Tags: Vue.js Vue Router Vuex axios Responsive Design

Posted on Sun, 07 Jun 2026 17:57:53 +0000 by Vinsanity