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.

app/components/Nav.tsxtypescript
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 works in server components Unlike some frameworks, NukeJS's 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:

app/components/Nav.tsxtypescript
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:

app/components/Nav.tsxtypescript
"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:

app/components/LoginForm.tsxtypescript
"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

app/components/BackButton.tsxtypescript
"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:

app/components/DeleteButton.tsxtypescript
"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 / MethodDescription
router.pathCurrent 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

PropTypeDescription
hrefstringDestination URL.
childrenReact.ReactNodeLink content.
classNamestring (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>