Multi root
Strategy
Setting up
// src/main.ts
import { Aurelia, StandardConfiguration, AppTask } from '@aurelia/runtime-html';
import { IEventAggregator, resolve } from '@aurelia/kernel';
import { LoginWall } from './login-wall';
import { MyApp } from './my-app';
export const AUTHENTICATED_EVENT = 'user:authenticated';
export interface AuthenticatedPayload {
username: string;
timestamp: Date;
token?: string;
}
const loginHost = document.querySelector<HTMLElement>('#login-root')!;
const appHost = document.querySelector<HTMLElement>('#main-root')!;
let loginApp: Aurelia | null = null;
let mainApp: Aurelia | null = null;
async function startLoginApp() {
loginHost.hidden = false;
loginApp = new Aurelia();
loginApp.register(
StandardConfiguration,
AppTask.hydrated(() => {
const ea = resolve(IEventAggregator);
ea.subscribeOnce<AuthenticatedPayload>(AUTHENTICATED_EVENT, async (payload) => {
loginHost.hidden = true;
await loginApp?.stop(true); // dispose the login root before booting the next one
loginApp = null;
await startMainApp(payload);
});
}),
);
loginApp.app({ host: loginHost, component: LoginWall });
await loginApp.start();
}
async function startMainApp(userData?: AuthenticatedPayload) {
appHost.hidden = false;
mainApp = new Aurelia();
mainApp.register(
StandardConfiguration,
// Add additional configurations for your main app:
// RouterConfiguration,
// ValidationConfiguration,
// etc.
);
mainApp.app({ host: appHost, component: MyApp });
await mainApp.start();
// Store reference if you need to stop this app later
// window.mainApp = mainApp;
}
startLoginApp().catch(console.error);Handling Login and Root Transition
Updating the HTML Structure
Example
Managing Application State
Passing Data Between Roots
Persistent State Options
Additional Considerations
Memory Management and Cleanup
Routing Configuration
Shared Resources
Alternative Approaches
Router Hooks (For Authentication)
Dynamic Composition
Conditional Rendering
Conclusion
Last updated
Was this helpful?