Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/hanakla/froute
Type safe and flexible router for React
https://github.com/hanakla/froute
react react-router router
Last synced: 2 days ago
JSON representation
Type safe and flexible router for React
- Host: GitHub
- URL: https://github.com/hanakla/froute
- Owner: hanakla
- License: mit
- Created: 2020-08-25T09:01:48.000Z (about 4 years ago)
- Default Branch: dev
- Last Pushed: 2024-10-14T07:46:41.000Z (about 1 month ago)
- Last Synced: 2024-11-07T23:05:50.392Z (6 days ago)
- Topics: react, react-router, router
- Language: TypeScript
- Homepage:
- Size: 3.48 MB
- Stars: 34
- Watchers: 1
- Forks: 0
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[npm-url]: https://www.npmjs.com/package/@fleur/froute
[ci-image-url]: https://img.shields.io/github/workflow/status/fleur-js/froute/CI?logo=github&style=flat-square
[version-image-url]: https://img.shields.io/npm/v/@fleur/froute?style=flat-square
[license-url]: https://opensource.org/licenses/MIT
[license-image]: https://img.shields.io/npm/l/@fleur/froute.svg?style=flat-square
[downloads-image]: https://img.shields.io/npm/dw/@fleur/froute.svg?style=flat-square&logo=npm
[bundlephobia-url]: https://bundlephobia.com/result?p=@fleur/[email protected]
[bundlephobia-image]: https://img.shields.io/bundlephobia/minzip/@fleur/froute?style=flat-square![CI][ci-image-url] [![latest][version-image-url]][npm-url] [![BundleSize][bundlephobia-image]][bundlephobia-url] [![License][license-image]][license-url] [![npm][downloads-image]][npm-url]
# Froute
[CHANGELOG](./pkgs/froute/CHANGELOG.md)
Framework independent Router for React.
Can use with both Fleur / Redux (redux-thunk).With provides Next.js subset `useRouter`
```
yarn add @fleur/froute
```- [Features](#features)
- [API Overview](#api-overview)
- [Hooks](#hooks)
- [Components](#components)
- [Example](#example)
- [Next.js compat status](#nextjs-compat-status)
- [How to type-safe useRoute](#how-to-type-safe-useroute)## Features
See all examples in [this spec](https://github.com/fleur-js/froute/blob/master/src/index.spec.tsx) or [examples](https://github.com/fleur-js/froute/tree/master/examples)
- Library independent
- Works with Redux and Fleur
- Next.js's Router subset compatiblity (`useRouter`, `withRouter`)
- Supports dynamic import without any code transformer
- Supports Sever Side Rendering
- Supports preload
- `ResponseCode` and `Redirect` component
- Custom route resolution (for i18n support)
- URL Builder## API Overview
### Hooks
- `useRouter` - **Next.js subset compat hooks**
- `withRouter` available
- `useFrouteRouter` - `useRouter` superset (not compatible to Next.js's `useRouter`)
- `useRouteComponent`
- `useBeforeRouteChange(listener: () => Promise | boolean | void)`
- It can prevent routing returns `Promise | false`Deprecated APIs
The following hooks are deprecated. These features are available from `useFrouteRouter`.
- `useParams`
- `useLocation`
- `useNavigation`
- `useUrlBuilder`### Components
- ``
- `` - Type-safe routing
- ``
- ` import('./pages/index'),
}),
user: routeOf('/users/:userId').action({
component: () => import('./pages/user'),
preload: (store: Store, params /* => inferred to { userId: string } */) =>
Promise.all([ store.dispatch(fetchUser(param.userId)) ]),
})
}
```App:
```tsx
import { useRouteComponent, ResponseCode } from '@fleur/froute'export const App = () => {
const { PageComponent } = useRouteComponent()return (
{PageComponent ? (
) : (
)}
)
}
```User.tsx:
```tsx
import { useRouter, buildPath } from '@fleur/froute'
import { routes, ResponseCode, Redirect } from './routes'export default () => {
const { query: { userId } } = useRouter()
const user = useSelector(getUser(userId))if (!user) {
return (
)
}if (user.suspended) {
return (
This account is suspended.
)
}
return (
Hello, {user.name}!
Show latest update friend
)
}
```Server side:
```tsx
import { createRouter } from '@fleur/froute'
import { routes } from './routes'server.get("*", async (req, res, next) => {
const router = createRouter(routes, {
preloadContext: store
})await router.navigate(req.url)
await context.preloadCurrent();const content = ReactDOM.renderToString(
)// Handling redirect
if (router.redirectTo) {
res.redirect(router.statusCode, router.redirectTo)
} else{
res.status(router.statusCode)
}
const stream = ReactDOM.renderToNodeStream(
{content}
).pipe(res)router.dispose()
})
```Client side:
```tsx
import { createRouter, FrouteContext } from '@fleur/froute'domready(async () => {
const router = createRouter(routes, {
preloadContext: store,
});await router.navigate(location.href)
await router.preloadCurrent({ onlyComponentPreload: true })ReactDOM.render((
),
document.getElementById('root')
)
})
```## Next.js compat status
- Compat API via `useRouter` or `withRouter`
- Compatible features
- `query`, `push()`, `replace()`, `prefetch()`, `back()`, `reload()`
- `pathname` is provided, but Froute's pathname is not adjust to file system route.
- Any type check not provided from Next.js (Froute is provided, it's compat breaking)
- Next.js specific functions not supported likes `asPath`, `isFallback`, `basePath`, `locale`, `locales` and `defaultLocale`
- `` only href props compatible but behaviour in-compatible.
- Froute's Link has `` element. Next.js is not.
- `as`, `passHref`, `prefetch`, `replace`, `scroll`, `shallow` is not supported currently.
- `pathname` is return current `location.pathname`, not adjust to component file path base pathname.
- `router.push()`, `router.replace()`
- URL Object is does not support currentry
- `as` argument is not supported
- `router.beforePopState` is not supported
- Use `useBeforeRouteChange()` hooks instead
- `router.events`
- Partially supported: `routeChangeStart`, `routeChangeComplete`, `routeChangeError`
- Only `url` or `err` arguments.
- Not implemented: `err.cancelled` and `{ shallow }` flag.
- Not implemented: `beforeHistoryChange`, `hashChangeStart`, `hashChangeComplete`
### Why froute provides Next.js compat hooks?It aims to migrate to Next.js from react-router or another router.
Froute's `useRouter` aims to provide a `useRouter` that is partially compatible with the Next.js `useRouter`, thereby guaranteeing an intermediate step in the migration of existing React Router-based applications to Next.js.
### How to type-safe useRoute
Use this snippet in your app.
(It's breaking to Type-level API compatibility from Next.js)```tsx
// Copy it in-your-app/useRouter.ts
import { useRouter as useNextCompatRouter } from '@fleur/froute'
export const useRouter: UseRouter = useNextCompatRouter
```Usage:
```tsx
// Route definition
const routes = {
users: routeOf('/users/:id'),
}// Typeing to `Routes`, it's free from circular dependency
export type Routes = typeof routes// Component
import { useRouter } from './useRouter'
import { Routes } from './your-routes'const Users = () => {
const router = useRouter()
router.query.id // It infering to `string`.
}
```