⚡ Single Page Application

SPA QuickStart

Build an app-like experience with client-side routing and instant transitions. Perfect for dashboards, tools, and interactive web apps.

Instant Transitions Client Routing Shared State

Setup Your SPA in 3 Steps

1

Create & Initialize Project

$ mkdir my-spa-app && cd my-spa-app
$ npm init -y

Creates a new project folder and initializes package.json

2

Install Domma

$ npm install domma-js

Downloads Domma from npm (~260KB minified)

3

Generate SPA Structure

$ npx domma init --spa

Creates a single page application with client-side routing

✓ Generated File Structure:

frontend/index.html (single entry)
frontend/js/app.js (router init)
frontend/js/views/
home.js
about.js
contact.js
404.js
frontend/css/custom.css
frontend/domma.config.json
✓ Ready! Open frontend/index.html in your browser or run:
$ npx live-server frontend

Live SPA Router Demo

Click the navigation links below to switch between views without page reload. This is how your SPA will work!

Notice: The content changes instantly without reloading the page. That's the power of client-side routing!

Code Structure

frontend/domma.config.json

{
  "project": {
    "name": "My SPA App",
    "version": "1.0.0"
  },
  "spa": {
    "enabled": true,
    "container": "#app",
    "defaultRoute": "/",
    "notFoundView": "404"
  },
  "routes": [
    { "path": "/", "view": "home" },
    { "path": "/about", "view": "about" },
    { "path": "/contact", "view": "contact" }
  ],
  "navbar": {
    "brand": { "text": "My App", "url": "#/" },
    "items": [
      { "text": "Home", "url": "#/" },
      { "text": "About", "url": "#/about" },
      { "text": "Contact", "url": "#/contact" }
    ]
  }
}

frontend/js/views/home.js

export const homeView = {
  template: `
    <div class="hero hero-gradient-primary hero-center" style="padding: 3rem 2rem;">
      <div class="hero-content">
        <h1>Welcome to My SPA</h1>
        <p class="lead">Built with Domma's powerful router</p>
      </div>
    </div>

    <div class="container py-6">
      <h2>This is the Home View</h2>
      <p>Click the navigation links to switch views without page reload!</p>
    </div>
  `,

  onMount($container) {
    // Scan for icons when view mounts
    Domma.icons.scan($container[0]);
    console.log('Home view mounted');
  },

  onLeave() {
    console.log('Home view unmounted');
  }
};

frontend/js/app.js

import { views } from './views/index.js';

$(() => {
  // Load config
  Domma.http.get('domma.config.json').then(config => {
    // Initialize router
    R.init({
      container: config.spa.container || '#app',
      routes: config.routes || [],
      views: views,
      default: config.spa.defaultRoute || '/',
      notFound: config.spa.notFoundView || '404'
    });

    // Subscribe to route changes
    M.subscribe('router:afterChange', ({ to, from }) => {
      console.log(`Route changed: ${from?.path} → ${to.path}`);
      window.scrollTo({ top: 0, behavior: 'smooth' });
    });

    console.log('Router initialized');
  });
});

You're Ready to Build! 🎉

Your SPA is set up and ready. Start editing views in frontend/js/views/ folder.