Client-side navigation

Rakkas provides a Link component (in the rakkasjs package) for SPA-style client-side navigation. It takes exactly the same props as the HTML <a> element but intercepts the user's click to handle the navigation without reloading the page.

StyledLink is similar but it accepts activeClass and activeStyle to apply a different style when the href property matches the current URL. It is useful for marking the active item in a navigation menu, for example. It also accepts pendingClass and pendingStyle props. They are applied while the navigation is underway due to the user clicking on this link. This feature is useful for giving the user immediate feedback about the fact that their click has been registered and is being processed.

Let's add client-side navigation to the previous example by replacing the <a> elements with StyledLink and by adding some inline styling for the active link. Notice how the page refreshes without a full reload now when you click on a link:

For programmatic navigation, you can use history.back(), history.forward() and history.go() to navigate back and forward in the browser history but you can't use history.pushState() or history.replaceState() because Rakkas would have no way of knowing they were called. It provides the navigate function for this purpose.

navigate returns a promise that resolves to true when the navigation completes and false if it is aborted (due to another call to navigate, for example). If navigate is called with a link that causes a full reload, the promise never resolves or rejects.

Page transitions

The return value of the useLocation custom hook from the rakkasjs package has the current and pending properties. You should always use these properties instead of window.location because, a) window is not available during server-side rendering, and b) you'll get the wrong URL during page transitions: When the user clicks on a Link, the URL in the location bar of the browser changes immediately but the old page is still shown while the new one is being loaded.

The pending property contains the URL that the app is transitioning into. You can test if it's defined to render some loading animation for example.

Link prefetching

The Link component accepts a prefetch prop that controls whether and when to load the code for the new page. It's a way to anticipate the user's next action and load the code for the next page in advance, resulting in a faster navigation experience.

Options are:

  • "eager": Load as soon as the link is rendered.
  • "viewport": Load when the link enters the viewport.
  • "idle": Same as "viewport" but only when the browser is idle. It falls back to "hover" on browsers that don't support requestIdleCallback.
  • "hover": Load when the user hovers over or taps on the link. This is the default.
  • "tap": Load when the user taps or starts clicking on the link.
  • "never": Only load when the link is clicked.