He
HeliumTS
Note:

HeliumTS is under pre-beta and active development. Expect bugs and breaking changes. If you find any issues, please report them in our GitHub

A stable release is planned for early December 2025.

Navigation

Use the Link component for client-side navigation:

1import { Link } from "heliumts/client";
2
3export default function Nav() {
4 return (
5 <nav>
6 <Link href="/">Home</Link>
7 <Link href="/about">About</Link>
8 <Link href="/blog/my-post">Blog Post</Link>
9 </nav>
10 );
11}

Props

  • href (string): Target URL
  • replace (boolean): Use history.replace instead of history.push
  • prefetch (boolean, default: true): Prefetch page on hover for faster navigation
  • scrollToTop (boolean, default: true): Scroll to top of page after navigation
  • Standard <a> tag props (className, onClick, etc.)

Behavior

  • Left-clicks are intercepted for SPA navigation
  • Modifier keys (Ctrl, Cmd, Shift, Alt) preserve normal link behavior (open in new tab, etc.)
  • Right-clicks and middle-clicks work normally
  • Automatic prefetching: When users hover over or focus on a link, the page chunk is preloaded in the background for instant navigation

Prefetching

Links automatically prefetch page chunks on hover and focus (keyboard navigation). This means when a user clicks a link, the page is often already loaded:

1// Prefetching enabled by default
2<Link href="/heavy-page">Heavy Page</Link>
3
4// Disable prefetching for specific links
5<Link href="/settings" prefetch={false}>Settings</Link>
6
7// Disable scroll-to-top (e.g., for in-page tab navigation)
8<Link href="/settings/profile" scrollToTop={false}>Profile Tab</Link>

Programmatic Navigation

Use the useRouter hook for programmatic navigation:

1import { useRouter } from "heliumts/client";
2
3export default function LoginPage() {
4 const router = useRouter();
5
6 const handleLogin = async () => {
7 // Perform login
8 await login();
9
10 // Navigate to dashboard
11 router.push("/dashboard");
12 };
13
14 return <button onClick={handleLogin}>Login</button>;
15}

push(href: string)

Navigate to a new route (adds to history):

1const router = useRouter();
2
3router.push("/about");
4router.push("/users/123");
5router.push("/search?q=hello");

replace(href: string)

Navigate to a new route (replaces current history entry):

1const router = useRouter();
2
3// Replace current URL (no back button entry)
4router.replace("/login");

Use cases for replace:

  • Redirects after authentication
  • Replacing temporary URLs
  • Preventing back navigation to intermediate states

Redirect Component

For declarative redirects, use the Redirect component instead of calling router.push() during render:

1import { Redirect } from "heliumts/client";
2
3export default function OldDocsPage() {
4 return <Redirect to="/docs/getting-started" />;
5}

Props

  • to (string): Target URL
  • replace (boolean, optional): Use history.replace instead of history.push (default: false)

Why use Redirect?

Calling router.push() directly during render is an anti-pattern in React that can cause issues. The Redirect component uses useLayoutEffect internally to ensure navigation happens after the component mounts but before paint, following React best practices and preventing issues with server-side rendering.

Example Use Cases

1// Redirect index page to a default subpage
2// src/pages/docs/index.tsx
3import { Redirect } from "heliumts/client";
4
5export default function DocsIndex() {
6 return <Redirect to="/docs/getting-started" />;
7}
8
9// Redirect with replace (no history entry)
10export default function OldPage() {
11 return <Redirect to="/new-page" replace />;
12}
13
14// Conditional redirect
15export default function ProtectedPage() {
16 const isAuthenticated = useAuth();
17
18 if (!isAuthenticated) {
19 return <Redirect to="/login" />;
20 }
21
22 return <div>Protected content</div>;
23}

Best Practices

  1. Use Link for internal navigation: Enables SPA navigation, prefetching, and better performance
  2. Use router.replace for redirects: Prevents unwanted back button entries
  3. Use Redirect component for declarative redirects: Follows React best practices
  4. Disable scrollToTop for tab navigation: Prevents jarring scroll behavior for in-page navigation
1// ❌ Don't use <a> for internal links
2<a href="/about">About</a>
3
4// ✅ Use <Link>
5<Link href="/about">About</Link>
6
7// ❌ Don't call router.push during render
8function BadRedirect() {
9 const router = useRouter();
10 router.push("/dashboard"); // Anti-pattern!
11 return null;
12}
13
14// ✅ Use Redirect component
15function GoodRedirect() {
16 return <Redirect to="/dashboard" />;
17}