Applications API
Single-spa exports named functions and variables rather than a single default export. This means importing must happen in one of two ways:
import { registerApplication, start } from "single-spa";
// or
import * as singleSpa from "single-spa";
registerApplication
registerApplication
is the most important API your root config will use. Use this function to register any application within single-spa.
Note that if an application is registered from within another application, that no hierarchy will be maintained between the applications.
There are two ways of registering your application:
Simple arguments
singleSpa.registerApplication(
"appName",
() => System.import("appName"),
(location) => location.pathname.startsWith("appName"),
);
arguments
- appName: string
- App name that single-spa will register and reference this application with, and will be labelled with in dev tools.
- applicationOrLoadingFn: () => <Function | Promise>
- Must be a loading function that either returns the resolved application or a promise.
- activityFn: (location) => boolean
- Must be a pure function. The function is called with
window.location as the first argument and should return a truthy value whenever the application should be active. - customProps?: Object | () => Object
- Will be passed to the application during each lifecycle method.
returns
undefined
Configuration object
singleSpa.registerApplication({
name: "appName",
app: () => System.import("appName"),
activeWhen: "/appName",
customProps: {
authToken: "xc67f6as87f7s9d",
},
});
singleSpa.registerApplication({
name: "appName",
app: () => System.import("appName"),
activeWhen: "/appName",
// Dynamic custom props that can change based on route
customProps(appName, location) {
return {
authToken: "xc67f6as87f7s9d",
};
},
});
arguments
- name: string
- App name that single-spa will register and reference this application with, and will be labelled with in dev tools.
- app: Application | () => Application | Promise<Application>
- Application object or a function that returns the resolved application (Promise or not)
- activeWhen: string | (location) => boolean | (string | (location) => boolean)[]
Can be a path prefix which will match every URL starting with this path, an activity function (as described in the simple arguments) or an array containing both of them. If any of the criteria is true, it will keep the application active. The path prefix also accepts dynamic values (they must start with ':'), as some paths would receive url params and should still trigger your application.
Examples:
- '/app1'
- ✅ https://app.com/app1
- ✅ https://app.com/app1/anything/everything
- 🚫 https://app.com/app2
- '/users/:userId/profile'
- ✅ https://app.com/users/123/profile
- ✅ https://app.com/users/123/profile/sub-profile/
- 🚫 https://app.com/users//profile/sub-profile/
- 🚫 https://app.com/users/profile/sub-profile/
- '/pathname/#/hash'
- ✅ https://app.com/pathname/#/hash
- ✅ https://app.com/pathname/#/hash/route/nested
- 🚫 https://app.com/pathname#/hash/route/nested
- 🚫 https://app.com/pathname#/another-hash
- ['/pathname/#/hash', '/app1']
- ✅ https://app.com/pathname/#/hash/route/nested
- ✅ https://app.com/app1/anything/everything
- 🚫 https://app.com/pathname/app1
- 🚫 https://app.com/app2
- customProps?: Object | () => Object
- Will be passed to the application during each lifecycle method.
returns
undefined
It is described in detail inside of the Configuration docs
start
singleSpa.start();
// Optionally, you can provide configuration
singleSpa.start({
urlRerouteOnly: true,
});
Must be called by your single spa config. Before start
is called, applications will be loaded, but will never be bootstrapped, mounted or unmounted. The reason for start
is to give you control over the performance of your single page application. For example, you may want to declare registered applications immediately (to start downloading the code for the active ones), but not actually mount the registered applications until an initial AJAX request (maybe to get information about the logged in user) has been completed. In that case, the best performance is achieved by calling registerApplication
immediately, but calling start
after the AJAX request is completed.
arguments
The start(opts)
api optionally accepts a single opts
object, with the following properties. If the opts object is omitted, all defaults will be applied.
urlRerouteOnly
: A boolean that defaults to true. If set to true, calls tohistory.pushState()
andhistory.replaceState()
will not trigger a single-spa reroute unless the client side route was changed. Setting this to true can be better for performance in some situations. For more information, read original issue.
returns
undefined
triggerAppChange
singleSpa.triggerAppChange();
Returns a Promise that will resolve/reject when all apps have mounted/unmounted. This was built for testing single-spa and is likely not needed in a production application.
arguments
none
returns
- Promise
- Returns a Promise that will resolve/reject when all apps have mounted.
navigateToUrl
// Three ways of using navigateToUrl
singleSpa.navigateToUrl("/new-url");
singleSpa.navigateToUrl(document.querySelector("a"));
document.querySelector("a").addEventListener(singleSpa.navigateToUrl);
<!-- A fourth way to use navigateToUrl, this one inside of your HTML -->
<a href="/new-url" onclick="singleSpaNavigate(event)">My link</a>
Use this utility function to easily perform url navigation between registered applications without needing to deal with event.preventDefault()
, pushState
, triggerAppChange()
, etc.
arguments
- navigationObj: string | context | DOMEvent
navigationObj must be one of the following types:
- a url string.
- a context / thisArg that has an
href property; useful for callingsingleSpaNavigate.call(anchorElement) with a reference to the anchor element or other context. - a DOMEvent object for a click event on a DOMElement that has an
href attribute; ideal for the<a onclick="singleSpaNavigate"></a> use case.
returns
undefined
getMountedApps
const mountedAppNames = singleSpa.getMountedApps();
console.log(mountedAppNames); // ['app1', 'app2', 'navbar']
arguments
none
returns
- appNames: string[]
- Each string is the name of a registered application that is currently
MOUNTED .
getAppNames
const appNames = singleSpa.getAppNames();
console.log(appNames); // ['app1', 'app2', 'app3', 'navbar']
arguments
none
returns
- appNames: string[]
- Each string is the name of a registered application regardless of app status.
getAppStatus
const status = singleSpa.getAppStatus("app1");
console.log(status); // one of many statuses (see list below). e.g. MOUNTED
arguments
- appName: string
- Registered application name.
returns
- appStatus: <string | null>
Will be one of the following string constants, or
null if the app does not exist.- NOT_LOADED
- app has been registered with single-spa but has not yet been loaded.
- LOADING_SOURCE_CODE
- app's source code is being fetched.
- NOT_BOOTSTRAPPED
- app has been loaded but not bootstrapped.
- BOOTSTRAPPING
- the
bootstrap lifecycle function has been called but has not finished. - NOT_MOUNTED
- app has been loaded and bootstrapped but not yet mounted.
- MOUNTING
- app is being mounted but not finished.
- MOUNTED
- app is currently active and is mounted to the DOM.
- UNMOUNTING
- app is currently being unmounted but has not finished.
- UNLOADING
- app is currently being unloaded but has not finished.
- SKIP_BECAUSE_BROKEN
- app threw an error during load, bootstrap, mount, or unmount and has been siloed because it is misbehaving and has been skipped. Other apps will continue on normally.
- LOAD_ERROR
The app's loading function returned a promise that rejected. This is often due to a network error attempting to download the JavaScript bundle for the application. Single-spa will retry loading the application after the user navigates away from the current route and then comes back to it.
Handling LOAD_ERROR status to retry module
If a module fails to load (for example, due to network error), single-spa will handle the error but SystemJS will not automatically retry to download the module later. To do so, add a single-spa errorHandler that deletes the module from the SystemJS registry and re-attempt to download the module when System.import()
on an application in LOAD_ERROR
status is called again.
singleSpa.addErrorHandler((err) => {
if (singleSpa.getAppStatus(err.appOrParcelName) === singleSpa.LOAD_ERROR) {
System.delete(System.resolve(err.appOrParcelName));
}
});
unloadApplication
// Unload the application right now, without waiting for it to naturally unmount.
singleSpa.unloadApplication("app1");
// Unload the application only after it naturally unmounts due to a route change.
singleSpa.unloadApplication("app1", { waitForUnmount: true });
The purpose of unloading a registered application is to set it back to a NOT_LOADED status, which means that it will be re-bootstrapped the next time it needs to mount. The main use-case for this was to allow for the hot-reloading of entire registered applications, but unloadApplication
can be useful whenever you want to re-bootstrap your application.
Single-spa performs the following steps when unloadApplication is called.
- Call the unload lifecyle on the registered application that is being unloaded.
- Set the app status to NOT_LOADED
- Trigger a reroute, during which single-spa will potentially mount the application that was just unloaded.
Because a registered application might be mounted when unloadApplication
is called, you can specify whether you want to immediately unload or if you want to wait until the application is no longer mounted. This is done with the waitForUnmount
option.
arguments
- appName: string
- Registered application name.
- options?: {waitForUnmount: boolean = false}
- The options must be an object that has a
waitForUnmount property. WhenwaitForUnmount isfalse , single-spa immediately unloads the specified registered application even if the app is currently mounted. If it istrue , single-spa will unload the registered application as soon as it is safe to do so (when the app status is notMOUNTED ).
returns
- Promise
- This promise will be resolved when the registered application has been successfully unloaded.
unregisterApplication
import { unregisterApplication } from "single-spa";
unregisterApplication("app1").then(() => {
console.log("app1 is now unmounted, unloaded, and no longer registered!");
});
The unregisterApplication
function will unmount, unload, and unregister an application. Once it is no longer registered, the application will never again be mounted.
This api was introduced in single-spa@5.8.0. A few notes about this api:
- Unregistering an application does not delete it from the SystemJS module registry.
- Unregistering an application does not delete its code or javascript frameworks from browser memory.
- An alternative to unregistering applications is to perform permission checks inside of the application's activity function. This has a similar effect of preventing the application from ever mounting.
arguments
- appName: string
returns
- Promise
- This promise will be resolved when the application has been successfully unregistered.
checkActivityFunctions
const appsThatShouldBeActive = singleSpa.checkActivityFunctions();
console.log(appsThatShouldBeActive); // ['app1']
const appsForACertainRoute = singleSpa.checkActivityFunctions(
new URL("/app2", window.location.href),
);
console.log(appsForACertainRoute); // ['app2']
Will call every app's activity function with url
and give you list of which applications should be mounted with that location.
arguments
- location: Location
- A
Location object that will be used instead of window.location when calling every application's activity function to test if they return true.
returns
- appNames: string[]
- Each string is the name of a registered application that matches the provided
url .
addErrorHandler
singleSpa.addErrorHandler((err) => {
console.log(err);
console.log(err.appOrParcelName);
console.log(singleSpa.getAppStatus(err.appOrParcelName));
});
Adds a handler that will be called every time an application throws an error during a lifecycle function or activity function. When there are no error handlers, single-spa throws the error to the window.
- errorHandler: Function(error: Error)
- Must be a function. Will be called with an Error object that additionally has a
message andappOrParcelName property.
returns
undefined
removeErrorHandler
singleSpa.addErrorHandler(handleErr);
singleSpa.removeErrorHandler(handleErr);
function handleErr(err) {
console.log(err);
}
Removes the given error handler function.
arguments
- errorHandler: Function
- Reference to the error handling function.
returns
- boolean
true if the error handler was removed, andfalse if it was not.
mountRootParcel
// Synchronous mounting
const parcel = singleSpa.mountRootParcel(parcelConfig, {
prop1: "value1",
domElement: document.getElementById("a-div"),
});
parcel.mountPromise.then(() => {
console.log("finished mounting the parcel!");
});
// Asynchronous mounting. Feel free to use webpack code splits or SystemJS dynamic loading
const parcel2 = singleSpa.mountRootParcel(() => import("./some-parcel.js"), {
prop1: "value1",
domElement: document.getElementById("a-div"),
});
Will create and mount a single-spa parcel.
Unmounting will need to be triggered manually.
arguments
- parcelConfig: Object or Loading Function
- parcelConfig
- parcelProps: Object with a domElement property
- parcelProps
returns
- Parcel object
- See Parcels API for more detail.
pathToActiveWhen
The pathToActiveWhen
function converts a string URL path into an activity function. The string path may contain route parameters that single-spa will match any characters to. By default, pathToActiveWhen assumes that the string provided is a prefix; however, this can be altered with the exactMatch
parameter.
This function is used by single-spa when a string is passed into registerApplication
as the activeWhen
argument.
Arguments
path
(string): The URL prefix that.exactMatch
(boolean, optional, defaults tofalse
, requires single-spa@>=5.9.0): A boolean that controls whether trailing characters after the path should be allowed. Whenfalse
, trailing characters are allowed. Whentrue
, trailing characters are not allowed.
Return Value
(url: URL) => boolean
A function that accepts a URL
object as an argument and returns a boolean indicating whether the path matches that URL.
Examples:
let activeWhen = singleSpa.pathToActiveWhen("/settings");
activeWhen(new URL("http://localhost/settings")); // true
activeWhen(new URL("http://localhost/settings/password")); // true
activeWhen(new URL("http://localhost/")); // false
activeWhen = singleSpa.pathToActiveWhen("/users/:id/settings");
activeWhen(new URL("http://localhost/users/6f7dsdf8g9df8g9dfg/settings")); // true
activeWhen(new URL("http://localhost/users/1324/settings")); // true
activeWhen(new URL("http://localhost/users/1324/settings/password")); // true
activeWhen(new URL("http://localhost/users/1/settings")); // true
activeWhen(new URL("http://localhost/users/1")); // false
activeWhen(new URL("http://localhost/settings")); // false
activeWhen(new URL("http://localhost/")); // false
activeWhen = singleSpa.pathToActiveWhen("/page#/hash");
activeWhen(new URL("http://localhost/page#/hash")); // true
activeWhen(new URL("http://localhost/#/hash")); // false
activeWhen(new URL("http://localhost/page")); // false
ensureJQuerySupport
singleSpa.ensureJQuerySupport(jQuery);
jQuery uses event delegation so single-spa must monkey-patch each version of jQuery on the page. single-spa will attempt to do this automatically by looking for window.jQuery
or window.$
. Use this explicit method if multiple versions are included on your page or if jQuery is bound to a different global variable.
arguments
- jQuery?: JQueryFn = window.jQuery
- A reference to the global variable that jQuery has been bound to.
returns
undefined
setBootstrapMaxTime
// After three seconds, show a console warning while continuing to wait.
singleSpa.setBootstrapMaxTime(3000);
// After three seconds, move the application to SKIP_BECAUSE_BROKEN status.
singleSpa.setBootstrapMaxTime(3000, true);
// don't do a console warning for slow lifecycles until 10 seconds have elapsed
singleSpa.setBootstrapMaxTime(3000, true, 10000);
Sets the global configuration for bootstrap timeouts.
arguments
- millis: number
- Number of milliseconds to wait for bootstrap to complete before timing out.
- dieOnTimeout: boolean = false
If false, registered applications that are slowing things down will cause nothing more than some warnings in the console up until
millis is reached.If true, registered applications that are slowing things down will be siloed into a SKIP_BECAUSE_BROKEN status where they will never again be given the chance to break everything.
Each registered application can override this behavior for itself.
- warningMillis: number = 1000
- Number of milliseconds to wait between console warnings that occur before the final timeout.
returns
undefined
setMountMaxTime
// After three seconds, show a console warning while continuing to wait.
singleSpa.setMountMaxTime(3000);
// After three seconds, move the application to SKIP_BECAUSE_BROKEN status.
singleSpa.setMountMaxTime(3000, true);
// don't do a console warning for slow lifecycles until 10 seconds have elapsed
singleSpa.setMountMaxTime(3000, true, 10000);
Sets the global configuration for mount timeouts.
arguments
- millis: number
- Number of milliseconds to wait for mount to complete before timing out.
- dieOnTimeout: boolean = false
If false, registered applications that are slowing things down will cause nothing more than some warnings in the console up until
millis is reached.If true, registered applications that are slowing things down will be siloed into a SKIP_BECAUSE_BROKEN status where they will never again be given the chance to break everything.
Each registered application can override this behavior for itself.
- warningMillis: number = 1000
- Number of milliseconds to wait between console warnings that occur before the final timeout.
returns
undefined
setUnmountMaxTime
// After three seconds, show a console warning while continuing to wait.
singleSpa.setUnmountMaxTime(3000);
// After three seconds, move the application to SKIP_BECAUSE_BROKEN status.
singleSpa.setUnmountMaxTime(3000, true);
// don't do a console warning for slow lifecycles until 10 seconds have elapsed
singleSpa.setUnmountMaxTime(3000, true, 10000);
Sets the global configuration for unmount timeouts.
arguments
- millis: number
- Number of milliseconds to wait for unmount to complete before timing out.
- dieOnTimeout: boolean = false
If false, registered applications that are slowing things down will cause nothing more than some warnings in the console up until
millis is reached.If true, registered applications that are slowing things down will be siloed into a SKIP_BECAUSE_BROKEN status where they will never again be given the chance to break everything.
Each registered application can override this behavior for itself.
- warningMillis: number = 1000
- Number of milliseconds to wait between console warnings that occur before the final timeout.
returns
undefined
setUnloadMaxTime
// After three seconds, show a console warning while continuing to wait.
singleSpa.setUnloadMaxTime(3000);
// After three seconds, move the application to SKIP_BECAUSE_BROKEN status.
singleSpa.setUnloadMaxTime(3000, true);
// don't do a console warning for slow lifecycles until 10 seconds have elapsed
singleSpa.setUnloadMaxTime(3000, true, 10000);
Sets the global configuration for unload timeouts.
arguments
- millis: number
- Number of milliseconds to wait for unload to complete before timing out.
- dieOnTimeout: boolean = false
If false, registered applications that are slowing things down will cause nothing more than some warnings in the console up until
millis is reached.If true, registered applications that are slowing things down will be siloed into a SKIP_BECAUSE_BROKEN status where they will never again be given the chance to break everything.
Each registered application can override this behavior for itself.
- warningMillis: number = 1000
- Number of milliseconds to wait between console warnings that occur before the final timeout.
returns
undefined
Events
single-spa fires Events to the window
as a way for your code to hook into URL transitions.
PopStateEvent
single-spa fires PopStateEvent events when it wants to instruct all active applications to re-render. This occurs when one application calls history.pushState, history.replaceState, or triggerAppChange. Single-spa deviates from the browser's default behavior in some cases, as described in this Github issue.
window.addEventListener("popstate", (evt) => {
if (evt.singleSpa) {
console.log(
"This event was fired by single-spa to forcibly trigger a re-render",
);
console.log(evt.singleSpaTrigger); // pushState | replaceState
} else {
console.log("This event was fired by native browser behavior");
}
});
Canceling navigation
Canceling navigation refers to the URL changing and then immediately changing back to what it was before. This is done before any mounting, unmounting, or loading that would otherwise take place. This can be used in conjunction with Vue router and Angular router's built-in navigation guards that allow for cancelation of a navigation event.
To cancel a navigation event, listen to the single-spa:before-routing-event
event:
window.addEventListener(
"single-spa:before-routing-event",
({ detail: { oldUrl, newUrl, cancelNavigation } }) => {
if (
new URL(oldUrl).pathname === "/route1" &&
new URL(newUrl).pathname === "/route2"
) {
cancelNavigation();
}
},
);
The cancelNavigation(val = true)
function optionally accepts a single argument. If the argument (val
) is falsy, navigation will not be canceled. If the argument is a promise, single-spa will wait for the promise to resolve or reject before canceling navigation. If the promise resolves with a falsy value, navigation will not be canceled.
When a navigation is canceled, no applications will be mounted, unmounted, loaded, or unloaded. All single-spa routing events will fire for the canceled navigation, but they will each have the navigationIsCanceled
property set to true
on the event.detail
(Details below in Custom Events section).
Navigation cancelation is sometimes used as a mechanism for preventing users from accessing routes for which they are unauthorized. However, we generally recommend permission checks on each route as the proper way to guard routes, instead of navigation cancelation.
Custom Events
single-spa fires a series of custom events whenever it reroutes. A reroute occurs whenever the browser URL changes in any way or a triggerAppChange
is called. The custom events are fired to the window
. Each custom event has a detail
property with the following properties:
window.addEventListener("single-spa:before-routing-event", (evt) => {
const {
originalEvent,
newAppStatuses,
appsByNewStatus,
totalAppChanges,
oldUrl,
newUrl,
navigationIsCanceled,
cancelNavigation,
} = evt.detail;
console.log(
"original event that triggered this single-spa event",
originalEvent,
); // PopStateEvent | HashChangeEvent | undefined
console.log(
"the new status for all applications after the reroute finishes",
newAppStatuses,
); // { app1: MOUNTED, app2: NOT_MOUNTED }
console.log(
"the applications that changed, grouped by their status",
appsByNewStatus,
); // { MOUNTED: ['app1'], NOT_MOUNTED: ['app2'] }
console.log(
"number of applications that changed status so far during this reroute",
totalAppChanges,
); // 2
console.log("the URL before the navigationEvent", oldUrl); // http://localhost:8080/old-route
console.log("the URL after the navigationEvent", newUrl); // http://localhost:8080/new-route
console.log("has the navigation been canceled", navigationIsCanceled); // false
// The cancelNavigation function is only defined in the before-routing-event
evt.detail.cancelNavigation();
});
The following table shows the order in which the custom events are fired during a reroute:
Event order | Event Name | Condition for firing |
---|---|---|
1 | single-spa:before-app-change or single-spa:before-no-app-change | Will any applications change status? |
2 | single-spa:before-routing-event | — |
3 | single-spa:before-mount-routing-event | — |
4 | single-spa:before-first-mount | Is this the first time any application is mounting? |
5 | single-spa:first-mount | Is this the first time any application was mounted? |
6 | single-spa:app-change or single-spa:no-app-change | Did any applications change status? |
7 | single-spa:routing-event | — |
before-app-change event
window.addEventListener("single-spa:before-app-change", (evt) => {
console.log("single-spa is about to mount/unmount applications!");
console.log(evt.detail.originalEvent); // PopStateEvent
console.log(evt.detail.newAppStatuses); // { app1: MOUNTED }
console.log(evt.detail.appsByNewStatus); // { MOUNTED: ['app1'], NOT_MOUNTED: [] }
console.log(evt.detail.totalAppChanges); // 1
});
A single-spa:before-app-change
event is fired before reroutes that will result in at least one application changing status.
before-no-app-change
window.addEventListener("single-spa:before-no-app-change", (evt) => {
console.log("single-spa is about to do a no-op reroute");
console.log(evt.detail.originalEvent); // PopStateEvent
console.log(evt.detail.newAppStatuses); // { }
console.log(evt.detail.appsByNewStatus); // { MOUNTED: [], NOT_MOUNTED: [] }
console.log(evt.detail.totalAppChanges); // 0
});
A single-spa:before-no-app-change
event is fired before reroutes that will result in zero applications changing status.
before-routing-event
window.addEventListener("single-spa:before-routing-event", (evt) => {
console.log("single-spa is about to mount/unmount applications!");
console.log(evt.detail.originalEvent); // PopStateEvent
console.log(evt.detail.newAppStatuses); // { }
console.log(evt.detail.appsByNewStatus); // { MOUNTED: [], NOT_MOUNTED: [] }
console.log(evt.detail.totalAppChanges); // 0
});
A single-spa:before-routing-event
event is fired before every routing event occurs, which is after each hashchange, popstate, or triggerAppChange, even if no changes to registered applications were necessary.
before-mount-routing-event
window.addEventListener("single-spa:before-mount-routing-event", (evt) => {
console.log("single-spa is about to mount/unmount applications!");
console.log(evt.detail);
console.log(evt.detail.originalEvent); // PopStateEvent
console.log(evt.detail.newAppStatuses); // { app1: MOUNTED }
console.log(evt.detail.appsByNewStatus); // { MOUNTED: ['app1'], NOT_MOUNTED: [] }
console.log(evt.detail.totalAppChanges); // 1
});
A single-spa:before-mount-routing-event
event is fired after before-routing-event
and before routing-event
. It is guaranteed to fire after all single-spa applications have been unmounted, but before any new applications have been mounted.
before-first-mount
window.addEventListener("single-spa:before-first-mount", () => {
console.log(
"single-spa is about to mount the very first application for the first time",
);
});
Before the first of any single-spa applications is mounted, single-spa fires a single-spa:before-first-mount
event; therefore it will only be fired once ever. More specifically, it fires after the application is already loaded but before mounting.
remove a loader bar that the user is seeing right before the first app will be mounted.
first-mount
window.addEventListener("single-spa:first-mount", () => {
console.log("single-spa just mounted the very first application");
});
After the first of any single-spa applications is mounted, single-spa fires a single-spa:first-mount
event; therefore it will only be fired once ever.
log the time it took before the user sees any of the apps mounted.
app-change event
window.addEventListener("single-spa:app-change", (evt) => {
console.log(
"A routing event occurred where at least one application was mounted/unmounted",
);
console.log(evt.detail.originalEvent); // PopStateEvent
console.log(evt.detail.newAppStatuses); // { app1: MOUNTED, app2: NOT_MOUNTED }
console.log(evt.detail.appsByNewStatus); // { MOUNTED: ['app1'], NOT_MOUNTED: ['app2'] }
console.log(evt.detail.totalAppChanges); // 2
});
A single-spa:app-change
event is fired every time that one or more apps were loaded, bootstrapped, mounted, unmounted, or unloaded. It is similar to single-spa:routing-event
except that it will not fire unless one or more apps were actually loaded, bootstrapped, mounted, or unmounted. A hashchange, popstate, or triggerAppChange that does not result in one of those changes will not cause the event to be fired.
no-app-change event
window.addEventListener("single-spa:no-app-change", (evt) => {
console.log(
"A routing event occurred where zero applications were mounted/unmounted",
);
console.log(evt.detail.originalEvent); // PopStateEvent
console.log(evt.detail.newAppStatuses); // { }
console.log(evt.detail.appsByNewStatus); // { MOUNTED: [], NOT_MOUNTED: [] }
console.log(evt.detail.totalAppChanges); // 0
});
When no applications were loaded, bootstrapped, mounted, unmounted, or unloaded, single-spa fires a single-spa:no-app-change
event. This is the inverse of the single-spa:app-change
event. Only one will be fired for each routing event.
routing-event
window.addEventListener("single-spa:routing-event", (evt) => {
console.log("single-spa finished mounting/unmounting applications!");
console.log(evt.detail.originalEvent); // PopStateEvent
console.log(evt.detail.newAppStatuses); // { app1: MOUNTED, app2: NOT_MOUNTED }
console.log(evt.detail.appsByNewStatus); // { MOUNTED: ['app1'], NOT_MOUNTED: ['app2'] }
console.log(evt.detail.totalAppChanges); // 2
});
A single-spa:routing-event
event is fired every time that a routing event has occurred, which is after each hashchange, popstate, or triggerAppChange, even if no changes to registered applications were necessary; and after single-spa verified that all apps were correctly loaded, bootstrapped, mounted, and unmounted.