---
title: 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:

<CodeViewer
  name="guide-samples"
  openFiles={["src/routes/nav/[userName].page.tsx"]}
  url="/nav/Fatih"
/>

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 <a id="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.
