@generouted/react-router v1.20.0
Generouted + React Router + Type-safety
Docs
Check out generouted's main docs for the features, conventions and more.
How
This integration is based on a Vite plugin to generate routes types for React Router with generouted conventions. The output is saved by default at src/router.ts and gets updated by the add/change/delete at src/pages/*.
Getting started
In case you don't have a Vite project with React and TypeScript, check Vite documentation to start a new project.
Installation
pnpm add @generouted/react-router react-routerSetup
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import generouted from '@generouted/react-router/plugin'
export default defineConfig({ plugins: [react(), generouted()] })Usage
// src/main.tsx
import { createRoot } from 'react-dom/client'
import { Routes } from '@generouted/react-router'
// import { Routes } from '@generouted/react-router/lazy' // route-based code-splitting
createRoot(document.getElementById('root')!).render(<Routes />)Adding pages
Add the home page by creating a new file src/pages/index.tsx → /, then export a default component:
// src/pages/index.tsx
export default function Home() {
return <h1>Home</h1>
}Optional root layout at pages/_app.tsx
// src/pages/_app.tsx
import { Outlet } from 'react-router'
export default function App() {
return (
<section>
<header>
<nav>...</nav>
</header>
<main>
<Outlet />
</main>
</section>
)
}Type-safe navigation
Autocompletion for Link, useNavigate, useParams and more exported from src/router.ts
// src/pages/index.tsx
import { Link, useNavigate, useParams } from '../router'
export default function Home() {
const navigate = useNavigate()
// typeof params -> { id: string; pid?: string }
const params = useParams('/posts/:id/:pid?')
// typeof params to be passed -> { id: string; pid?: string }
const handler = () => navigate('/posts/:id/:pid?', { params: { id: '1', pid: '0' } })
return (
<div>
{/** ✅ Passes */}
<Link to="/" />
<Link to="/posts/:id" params={{ id: '1' }} />
<Link to="/posts/:id/:pid?" params={{ id: '1' }} />
<Link to="/posts/:id/:pid?" params={{ id: '1', pid: 0 }} />
{/** 🔴 Error: not defined route */}
<Link to="/not-defined-route" />
{/** 🔴 Error: missing required params */}
<Link to="/posts/:id" />
<h1>Home</h1>
</div>
)
}Type-safe global modals
Although all modals are global, it's nice to co-locate modals with relevant routes.
Create modal routes by prefixing a valid route file name with a plus sign +. Why +? You can think of it as an extra route, as the modal overlays the current route:
// src/pages/+login.tsx
import { Modal } from '@/ui'
export default function Login() {
return <Modal>Content</Modal>
}To navigate to a modal use useModals hook exported from src/router.ts:
// src/pages/_app.tsx
import { Outlet } from 'react-router'
import { useModals } from '../router'
export default function App() {
const modals = useModals()
return (
<section>
<header>
<nav>...</nav>
<button onClick={() => modals.open('/login')}>Open modal</button>
</header>
<main>
<Outlet />
</main>
</section>
)
}With useModals you can use modals.open('/modal-path') and modals.close(), and by default it opens/closes the modal on the current active route.
Both methods come with React Router's navigate() options with one prop added at, for optionally navigating to a route while opening/closing a modal, and it's also type-safe!
modals.open(path, options)modals.close(options)
at should be also a valid route path, here are some usage examples:
modals.open('/login', { at: '/auth', replace: true })modals.open('/info', { at: '/invoice/:id', params: { id: 'xyz' } })modals.close({ at: '/', replace: false })
Examples
React Router
License
MIT
10 months ago
9 months ago
12 months ago
9 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago