Routing

Phyre uses file-based routing. Create a file, get a route.

Basic Routes

Files in src/client/routes/ automatically become routes:

plaintext
src/client/routes/ ├── index.jsx → / ├── about.jsx → /about └── contact.jsx → /contact

Example page:

jsx
// src/client/routes/about.jsx export default function About() { return ( <div> <h1>About Us</h1> <p>Welcome to our about page!</p> </div> ); }

Dynamic Routes

Use [param] syntax for dynamic segments:

plaintext
src/client/routes/ └── posts/ └── [id].jsx → /posts/:id

Access parameters with useParams:

jsx
// src/client/routes/posts/[id].jsx import { useParams } from 'react-router'; export default function PostDetail() { const { id } = useParams(); return <h1>Post {id}</h1>; }

Examples:
/posts/1 → id = "1"
/posts/hello → id = "hello"

Nested Routes

Create folders to nest routes:

plaintext
src/client/routes/ └── blog/ ├── index.jsx → /blog ├── [slug].jsx → /blog/:slug └── categories/ ├── index.jsx → /blog/categories └── [name].jsx → /blog/categories/:name

Index Routes

index.jsx files represent the default route for that path:

plaintext
src/client/routes/ └── dashboard/ ├── index.jsx → /dashboard └── settings.jsx → /dashboard/settings

Navigation

Link Component

Use React Router's Link for client-side navigation:

jsx
import { Link } from 'react-router'; export default function Navigation() { return ( <nav> <Link to="/">Home</Link> <Link to="/about">About</Link> <Link to="/posts/123">Post 123</Link> </nav> ); }

Programmatic Navigation

Use useNavigate hook for navigation in code:

jsx
import { useNavigate } from 'react-router'; export default function LoginForm() { const navigate = useNavigate(); const handleSubmit = async (e) => { e.preventDefault(); // Login logic... navigate('/dashboard'); }; return ( <form onSubmit={handleSubmit}> {/* form fields */} </form> ); }

Route Priority

When multiple routes could match, Phyre follows this priority:

  1. Exact static routes (/about)
  2. Dynamic routes (/posts/[id])

Example:

plaintext
src/client/routes/ └── posts/ ├── new.jsx → /posts/new (priority 1) └── [id].jsx → /posts/:id (priority 2)

/posts/new will match new.jsx, not [id].jsx