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
Link Component
Use the Link component for client-side navigation:
1import { Link } from "heliumts/client";23export 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 URLreplace(boolean): Usehistory.replaceinstead ofhistory.pushprefetch(boolean, default:true): Prefetch page on hover for faster navigationscrollToTop(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 default2<Link href="/heavy-page">Heavy Page</Link>34// Disable prefetching for specific links5<Link href="/settings" prefetch={false}>Settings</Link>67// 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";23export default function LoginPage() {4 const router = useRouter();56 const handleLogin = async () => {7 // Perform login8 await login();910 // Navigate to dashboard11 router.push("/dashboard");12 };1314 return <button onClick={handleLogin}>Login</button>;15}
Navigation Methods
push(href: string)
Navigate to a new route (adds to history):
1const router = useRouter();23router.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();23// 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";23export default function OldDocsPage() {4 return <Redirect to="/docs/getting-started" />;5}
Props
to(string): Target URLreplace(boolean, optional): Usehistory.replaceinstead ofhistory.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 subpage2// src/pages/docs/index.tsx3import { Redirect } from "heliumts/client";45export default function DocsIndex() {6 return <Redirect to="/docs/getting-started" />;7}89// Redirect with replace (no history entry)10export default function OldPage() {11 return <Redirect to="/new-page" replace />;12}1314// Conditional redirect15export default function ProtectedPage() {16 const isAuthenticated = useAuth();1718 if (!isAuthenticated) {19 return <Redirect to="/login" />;20 }2122 return <div>Protected content</div>;23}
Best Practices
- Use Link for internal navigation: Enables SPA navigation, prefetching, and better performance
- Use router.replace for redirects: Prevents unwanted back button entries
- Use Redirect component for declarative redirects: Follows React best practices
- Disable scrollToTop for tab navigation: Prevents jarring scroll behavior for in-page navigation
1// ❌ Don't use <a> for internal links2<a href="/about">About</a>34// ✅ Use <Link>5<Link href="/about">About</Link>67// ❌ Don't call router.push during render8function BadRedirect() {9 const router = useRouter();10 router.push("/dashboard"); // Anti-pattern!11 return null;12}1314// ✅ Use Redirect component15function GoodRedirect() {16 return <Redirect to="/dashboard" />;17}