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 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.

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:

import React from "react";
import { Helmet } from "react-helmet-async";
import { StyledLink } from "rakkasjs";

const UserProfilePage = ({ params }) => (
	<div>
		<Helmet title={`StyledLink Example - Rakkas`} />
		<p>
			Hello <b>{params.userName}</b>!
		</p>
		<nav>
			<ul>
				<li>
					<StyledLink
						href="/examples/navlink/Fatih"
						activeStyle={{ fontWeight: "bold" }}
					>
						Fatih&apos;s profile
					</StyledLink>
				</li>
				<li>
					<StyledLink
						href="/examples/navlink/Dan"
						activeStyle={{ fontWeight: "bold" }}
					>
						Dan&apos;s profile
					</StyledLink>
				</li>
				<li>
					<StyledLink
						href="/examples/navlink/Engin"
						activeStyle={{ fontWeight: "bold" }}
					>
						Engin&apos;s profile
					</StyledLink>
				</li>
			</ul>
		</nav>
	</div>
);

export default UserProfilePage;
Rakkas Demo App

For programmatic navigation, use the navigate function exported from the rakkasjs package:

import React from "react";
import { Helmet } from "react-helmet-async";
import { navigate } from "rakkasjs";

const UserProfilePage = ({ params }) => {
	return (
		<div>
			<Helmet title={`Programmatic Navigation Example - Rakkas`} />
			<p>
				Hello <b>{params.userName}</b>!
			</p>
			<nav>
				<button onClick={() => navigate("/examples/navigate/Fatih")}>
					Fatih&apos;s profile
				</button>{" "}
				<button onClick={() => navigate("/examples/navigate/Dan")}>
					Dan&apos;s profile
				</button>{" "}
				<button onClick={() => navigate("/examples/navigate/Engin")}>
					Engin&apos;s profile
				</button>
			</nav>
		</div>
	);
};

export default UserProfilePage;
Rakkas Demo App

StyledLink component also accepts pendingClass and pendingStyle props. They are applied while the navigation is underway due 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.

navigate returns a promise that resolves to true when the navigation successfully 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.

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 whey were called.

Page transitions

The return value of the useRouter custom hook from the rakkasjs package has a currentUrl property. It's a URL object that contains the URL of the currently rendered page. You should always use this property 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 pendingUrl property of the return value of useRouter, if present, contains the URL that the app is transitioning into. You can test for its presence to render some loading animation for example.

Advanced

Rakkas uses the knave-react library behind the scenes to provide client-side navigation features. Apart from what's mentioned above, useCurrentLocation, useNavigationState, usePendingLocation, useNavigationBlocker are also re-exported from rakkasjs and work exactly like described in knave-react documentation.