Navigation
NukeJS provides a Link component and useRouter hook for client-side navigation without full page reloads.
The Link component
Use <Link> from nukejs for internal navigation. After the first SSR, Link navigates client-side — no full reload, instant transitions.
import { Link } from 'nukejs'
export default function Nav() {
return (
<nav>
<Link href="/">Home</Link>
<Link href="/about">About</Link>
<Link href="/blog">Blog</Link>
<Link href="/docs">Docs</Link>
</nav>
)
}Link does not need to be inside a "use client" component. It renders as a plain <a> tag that the NukeJS runtime intercepts in the browser.className prop
Pass a className prop to style the underlying <a> element:
import { Link } from 'nukejs'
export default function Nav() {
return (
<nav>
<Link href="/" className="nav-link">Home</Link>
<Link href="/about" className="nav-link">About</Link>
<Link href="/pricing" className="nav-link nav-link--cta">Pricing</Link>
</nav>
)
}Active link styling
Use useRouter inside a client component to read the current path and apply an active class:
"use client"
import { Link, useRouter } from 'nukejs'
export default function Nav() {
const router = useRouter()
return (
<nav>
{[
{ href: '/', label: 'Home' },
{ href: '/about', label: 'About' },
{ href: '/blog', label: 'Blog' },
].map(({ href, label }) => (
<Link
key={href}
href={href}
className={router.path === href ? 'active' : ''}
>
{label}
</Link>
))}
</nav>
)
}useRouter
For programmatic navigation — redirecting after a form submit or async action — use useRouter. Because it accesses browser history, it must live inside a "use client" component:
"use client"
import { useState } from 'react'
import { useRouter } from 'nukejs'
export default function LoginForm() {
const router = useRouter()
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
async function handleSubmit() {
const res = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
})
if (res.ok) {
router.push('/dashboard') // adds to history
} else {
router.replace('/login?error=1') // replaces current entry
}
}
return (
<div>
<input type="email" value={email} onChange={e => setEmail(e.target.value)} />
<input type="password" value={password} onChange={e => setPassword(e.target.value)} />
<button type="button" onClick={handleSubmit}>Login</button>
</div>
)
}router.back — programmatic back button
"use client"
import { useRouter } from 'nukejs'
export default function BackButton() {
const { back } = useRouter()
return <button onClick={back}>← Go back</button>
}router.refresh — re-render after a mutation
refresh() re-triggers the current route without changing the URL. Use it after a server mutation to fetch and display updated data:
"use client"
import { useRouter } from 'nukejs'
export default function DeleteButton({ postId }: { postId: string }) {
const { refresh } = useRouter()
async function handleDelete() {
await fetch(`/api/posts/${postId}`, { method: 'DELETE' })
refresh() // re-renders the page so the deleted post disappears
}
return <button onClick={handleDelete}>Delete post</button>
}router API
| Property / Method | Description |
|---|---|
router.path | Current pathname (e.g. /docs/routing). Reactive — updates on every SPA navigation. |
router.push(url) | Navigate to a URL, adds an entry to the history stack. |
router.replace(url) | Navigate without adding to history (replaces current entry). |
router.back() | Go back one step in history. |
router.refresh() | Re-trigger the current route without a URL change — useful after a server mutation to reload page data. |
Link props
| Prop | Type | Description |
|---|---|---|
href | string | Destination URL. |
children | React.ReactNode | Link content. |
className | string (optional) | CSS class(es) applied to the underlying <a> element. |
External links
For external URLs use a plain <a> tag. NukeJS will not intercept it:
<a href="https://github.com/nuke-js/nukejs" target="_blank" rel="noopener">
GitHub ↗
</a>