signalizejs/spa

Turn any website into a Single Page Application (SPA) in a minute.

Installation

Required import map dependencies:
const { navigate } = await signalize.resolve('spa');

/*
	If you do not want to use any SPA module functions function but still want to torn your page into SPA,
	simply resolve it to initialize the module.
*/
await signalize.resolve('spa');

How it Works

By default, the SPA module performs the following actions:

  • It listens for all clicks on anchor elements (excluding those with the data-spa-ignore attribute) and elements with data-spa-url.
  • If the URL has the same host, scheme, and port, it triggers navigation to that URL.
  • If the only difference between the navigation URL and the current URL in window.location is a hash, it will attempt to select that element and scroll it into the viewport.

Redrawing Parts of the Page

The SPA module uses the Snippets module under the hood. Whenever you trigger navigation by a click or by calling the navigate method, it will send a request, receive a response, and if the response contains any element with the snippet="name" attribute, it will synchronize that snippet with the one on the current page.

Example: Navigation from Page A to Page B

Page A:

<html>
	<head snippet="head">
		<title>Page A</title>
	</head>
	<body>
		<main snippet="content">Page A content</main>
		<footer>Layout Footer</footer>
	</body>
</html>

Page 2:

<html>
	<head snippet="head">
		<title>Page B</title>
	</head>
	<body>
		<main snippet="content">Page B content</main>
		<footer>Layout Footer</footer>
	</body>
</html>

Result:

<html>
	<head snippet="head">
		<title>Page B</title>
	</head>
	<body>
		<main snippet="content">Page B content</main>
		<footer>Layout Footer</footer>
	</body>
</html>

API

The navigate method can be used to manually trigger a navigation to a specific page:

const result = await navigate({
	url: 'string',
	stateAction: 'push' | 'replace' | undefined
});

Attribute Directives

  • data-spa-url: This attribute serves as a fallback URL for the SPA module if the href attribute is not found on a link or element.
  • data-spa-ignore (empty): This attribute instructs the SPA module to ignore the link with this attribute.

Meta Tags

  • <meta name="spa-cache-control" content="no-cache">: This meta tag informs the SPA module not to cache the result of the requested page.
  • <meta name="spa-app-version" content="...">: This meta tag informs the SPA module about the current version of the application.

Response Headers

  • X-Spa-Cache-Control (string): This header can be used to instruct the SPA module not to cache the requested page. Currently, the acceptable value is only no-cache.
  • X-Spa-App-Version (string): This header can be used to inform the SPA module of the current version of the application. It can be useful to notify users that a new version is available and prompt them to refresh the page.

Dispatched Events

You can listen to the following events through the on function:

  • spa:navigation:start: Triggered when a navigation begins.
  • spa:navigation:end: Triggered when a navigation ends
  • spa:page:ready: Triggered on dom:ready and after a successful navigation.
  • spa:request:start: Triggered when the target page is not yet cached and the AJAX request starts.
  • spa:request:end: Triggered when the AJAX request for a page completes.
  • spa:scroll:start: Triggered after the requested page is synchronized with the current DOM. It scrolls the element matching the URL hash into view. This event can be prevented by calling event.preventDefault() in the listener.
  • spa:app-version:changed: Triggered when the meta tag or request header indicating the app version changes in the received data of the requested page. Useful for informing users about a new application version so they can for example refresh the page and get the new version of the app.
  • spa:popstate: Triggered on any window popstate event.
  • spa:clicked: Triggered when a user clicks on a link that can be processed by the SPA module.