What is piconav
?
piconav
is a tiny library that keeps the browser URL in sync with your JS state for Single Page Applications.
It also syncs the document
title, canonical URL and meta description.
It aims to allow Google indexing of SPA's to prevent the need for server side rendering / hydrating.
Why did you make piconav
?
Why should I use piconav
?
- Easy to use.
- Use
piconav
if you want to get something up and running quickly.
- Easy to replace.
- Minimal API.
piconav
is very simple.- You can copy or customize the functionality quickly.
How does piconav
work?
There are four broad variables in JS and the DOM that need to be kept in sync:
- JS state
- JSX DOM.
- Your state converted into DOM elements via JSX.
- URL
- The browser address bar that the user types into, and which is changed on forward/back browser button presses.
- Document.
- E.g the title,
<link>
meta and canonical URL values.
There are two sources of navigation:
- Browser.
- Any navigation caused by the browser chrome UI (including swipe gestures for forward and back).
- JS.
- Any navigation triggered by handling of a click event or other JS event.
piconav
observes a navigation from one of the sources, and makes sure each of the four variables are in sync.
You need to integrate piconav
into your app by passing it function callbacks - code examples below.
Generally, this is what happens when a navigation happens from each of the two sources:
Note: Indentation roughly shows the function call stack, although with observables it might not be exact as there will be some Mobx functions in the stack also.
- JS Event (e.g click)
- (1) Update state
- (2) Update JSX DOM
nav(navEvent)
- (3) Update URL
- (4) Update Document
- Browser event (e.g. pasting a new URL into the address bar)
- (3) Update URL
events.browser.after(url, params)
- (1) Update state
- (2) Update JSX DOM
- (4) Update Document.
How to add piconav
to your JS project.
How to add `piconav` to your JS project.
Install: yarn add piconav
or npm install piconav
.
1. Create a nav.js
to add configuration and event handlers to piconav
.
import {on, off} from "piconav";
import {storeIns} from "./../stores/store";
const resetPrimaryScroll = () => {
document.querySelector("html").scrollTo(0, 0);
};
const {nav, navByBrowser, updateDoc} = on({
site: {
canonicalDomain: `https://example.com`
},
events: {
js: {
after: ({data}) => {
if (data !== null && "type" in data && data.type !== "home") {
resetPrimaryScroll();
}
}
},
browser: {
after: (url, params) => {
return storeIns.onBrowserNav(url, params);
}
}
}
});
export {
nav,
navByBrowser,
updateDoc
}
2. Import nav.js
to your store, map JS state to document
state.
When the user navigates via browser:
events.browser.after(url, params)
is called.
- Your code is expected to call
updateDoc(navEvent)
soon after.
When the user navigates via JS click:
Example using a MobX store:
@observable curUrl = null;
nav(appSpecificData, src = "js") {
this.curUrl = {
url: "/a/b/c",
title: "A Title",
metaDesc: "A page description",
data: appSpecificData,
src
};
}
Calling piconav
functions after your app navigates to a new URL:
const disposer = observe(storeIns, "curUrl", ({oldValue, newValue}) => {
const {url, title, metaDesc, data, src} = newValue;
const navEvent = {
url,
doc: {
title,
metaDesc
},
data
};
if (src === "js") {
nav(navEvent);
return;
}
if (src === "browser") {
updateDoc(navEvent);
return;
}
});
3. Run navByBrowser
on initial page load.
navByBrowser();