Issue with URL Routing: http://localhost:3000/#!/login vs http://localhost:3000/login#!/login

Hi Webix Community,

I’m currently working on a Webix Jet application and encountering an issue with URL routing. I expected my app to work with the URL http://localhost:3000/#!/login, but it only seems to work with http://localhost:3000/login#!/login

Here are the details of my setup:

  1. Project Structure:
  • Webix Jet is set up using the Webix CLI.
  • The main app configuration is in sources/myapp.js.
  1. Routing Configuration:
  • I have set up the routing in sources/myapp.js as follows:
// sources/myapp.js
import { JetApp, HashRouter } from "webix-jet";

const modules = import.meta.glob("./views/**/*.js");
const views = name => modules[`./views/${name}.js`]().then(x => x.default);

export default class MyApp extends JetApp {
    constructor(config) {
        const defaults = {
            router: HashRouter,
            debug: true,
            start: "/login",
            id: "myapp",
            version: "0.1",
            views
        };

        super({ ...defaults, ...config });

        // Attach global error handler
        this.attachEvent("app:error:resolve", (name, error) => {
            window.console.error(`Error in ${name}:`, error);
        });
    } 
}

webix.ready(() => new MyApp().render());

  1. Server Configuration:
  • I am using Express to serve the application. Here is my server.mjs file:
import express from 'express';
import path from 'path';
import { createServer } from 'http';
import { fileURLToPath } from 'url';
import fs from 'fs';
import dotenv from 'dotenv';

// Load environment variables from .env file
dotenv.config();

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const app = express();
const port = process.env.PORT || 3000;

// Serve static files from the "public" directory
app.use(express.static(path.join(__dirname, 'public')));

// Serve the index.html file for all other routes to enable client-side routing
app.get('*', (req, res) => {
    const env = process.env.NODE_ENV || 'development';
    let html = fs.readFileSync(path.join(__dirname, 'public', 'index.html'), 'utf-8');
  
    if (env === 'production') {
        html = html.replace('<script type="module" src="/sources/myapp.js"></script>', '<script type="module" src="/assets/dist/codebase.js"></script>');
    }
    
    res.send(html);
});

// Create HTTP server
const server = createServer(app);

// Start the server
server.listen(port, () => {
    console.log(`Server is running on http://localhost:${port} in ${process.env.NODE_ENV || 'development'} mode`);
});

  1. Package Configuration:
  • Here is my package.json file:
{
  "name": "aps_development",
  "version": "1.0.0",
  "type": "module",
  "main": "index.js",
  "scripts": {
    "dev": "cross-env NODE_ENV=development node server.mjs",
    "build": "vite build",
    "start": "cross-env NODE_ENV=production node server.mjs"
  },
  "author": "",
  "keywords": [
    "webix",
    "jet"
  ],
  "license": "ISC",
  "description": "",
  "devDependencies": {
    "eslint": "^9.7.0",
    "vite": "^5.3.4"
  },
  "dependencies": {
    "cross-env": "^7.0.3",
    "dotenv": "^10.0.0",
    "express": "^4.19.2",
    "webix-jet": "^3.0.3"
  }
}

  1. Vite Configuration:
  • Here is my vite.config.js file:
// vite.config.js
import { defineConfig } from 'vite';
import path from 'path';

export default defineConfig({
  root: 'public',
  resolve: {
    alias: {
      '/sources': path.resolve(__dirname, 'sources'),
    },
  },
  build: {
    outDir: path.resolve(__dirname, 'public/assets/dist'),
    emptyOutDir: true,
    rollupOptions: {
      output: {
        entryFileNames: 'codebase.js',
        chunkFileNames: '[name].js',
        assetFileNames: '[name].[ext]'
      }
    }
  },
  server: {
    open: true,
  },
  optimizeDeps: {
    include: ['webix-jet']
  }
});

  1. Behavior:
  • When I navigate to http://localhost:3000/#!/login, the routing does not work as expected.
  • However, when I use http://localhost:3000/login#!/login, it works correctly.

I would prefer to use the http://localhost:3000/#!/login format for cleaner URLs. Could anyone help me understand why this is happening and how to configure my Webix Jet application to work with http://localhost:3000/#!/login?

Thank you for your assistance!

Hello Webix Developer and Community,

May I have the solution?

Hello Webix Developer and Community,

May I have the solution?

Hello @Than_Naing_Oo ,
Thank you for the provided code example however I’m afraid I didn’t managed to reproduce the issue with your code snippets.
Yet, please find the demo based on the jet-start and your code (with differences from your code like removing nesting in the outDir path in the vite.config.js and in the < script > src path in the server.mjs file): https://files.webix.com/30d/215854423ea464cead3a9d4bf6632a65/jet-start-master-nodeserver.zip
To run the demo use:

npm i
npm run build
npm run start

The demo will start at the http://localhost:3000/#!/login url.

If you still have issues with the routing, it would be helpful if you could provide us with more details about the steps to follow to reproduce the problem and/or a minimal working example where the problem can be seen.