All Projects → fleur-js → froute

fleur-js / froute

Licence: MIT License
Type safe and flexible router for React

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to froute

React Router Page Transition
Highly customizable page transition component for your React Router
Stars: ✭ 531 (+1612.9%)
Mutual labels:  router, react-router
React Redux Graphql Apollo Bootstrap Webpack Starter
react js + redux + graphQL + Apollo + react router + hot reload + devTools + bootstrap + webpack starter
Stars: ✭ 127 (+309.68%)
Mutual labels:  router, react-router
React Router Util
Useful components and utilities for working with React Router
Stars: ✭ 320 (+932.26%)
Mutual labels:  router, react-router
React Native Simple Router
A community maintained router component for React Native
Stars: ✭ 266 (+758.06%)
Mutual labels:  router, react-router
use-react-router-breadcrumbs
tiny, flexible, hook for rendering route breadcrumbs with react-router v6
Stars: ✭ 170 (+448.39%)
Mutual labels:  router, react-router
yarr
A React router library enabling the render-as-you-fetch concurrent UI pattern.
Stars: ✭ 97 (+212.9%)
Mutual labels:  router, react-router
React Redux Antdesign Webpack Starter
react + redux + ant design + react-router 4 + webpack 4 starter
Stars: ✭ 44 (+41.94%)
Mutual labels:  router, react-router
Redux First History
🎉 Redux First History - Redux history binding support react-router - @reach/router - wouter
Stars: ✭ 163 (+425.81%)
Mutual labels:  router, react-router
React Live Route
📌 An enhanced react-router-v4/5 Route that keeps route alive.
Stars: ✭ 207 (+567.74%)
Mutual labels:  router, react-router
React Router Native Stack
A stack navigation component for react-router-native
Stars: ✭ 171 (+451.61%)
Mutual labels:  router, react-router
smoothr
A custom React router that leverages the Web Animations API and CSS animations.
Stars: ✭ 28 (-9.68%)
Mutual labels:  router, react-router
boring-router
A type-safe MobX router with parallel routing support.
Stars: ✭ 74 (+138.71%)
Mutual labels:  router, react-router
cra-redux-boilerplate
⚛️🔨create-react-app application with redux and another cool libraries to make your life easier.
Stars: ✭ 15 (-51.61%)
Mutual labels:  router, react-router
chomex
Chrome Extension Messaging Routing Kit / Promisify Chrome Messaging / LocalStorage Object Mapper
Stars: ✭ 41 (+32.26%)
Mutual labels:  router
Fakeflix
Not the usual clone that you can find on the web.
Stars: ✭ 4,429 (+14187.1%)
Mutual labels:  react-router
yew-router
Router extension to yew
Stars: ✭ 27 (-12.9%)
Mutual labels:  router
react-douban
A React project
Stars: ✭ 21 (-32.26%)
Mutual labels:  react-router
highway
Highway - A Modern Javascript Transitions Manager
Stars: ✭ 1,349 (+4251.61%)
Mutual labels:  router
Study-Room
Connect and study together with friends over text and voice channels, over a click of a button. Web application for chat and audio streaming.
Stars: ✭ 21 (-32.26%)
Mutual labels:  react-router
smoovy
A collection of small and useful js packages (smooth scrolling, utils, etc.) preventing copy & paste
Stars: ✭ 25 (-19.35%)
Mutual labels:  router

CI latest BundleSize License npm

Froute

Framework independent Router for React.
Can use with both Fleur / Redux (redux-thunk).

With provides Next.js subset useRouter

yarn add @fleur/froute

Features

See all examples in this spec or 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> | boolean | void)
    • It can prevent routing returns Promise<false> | false
Deprecated APIs

The following hooks are deprecated. These features are available from useFrouteRouter.

  • useParams
  • useLocation
  • useNavigation
  • useUrlBuilder

Components

  • <Link href={string} />
  • <FrouteLink to={routeDef} params={object} query={object} /> - Type-safe routing
  • <ResponseCode status={number} />
  • <Redirect url={string} status={number = 302}

Getting started

Route definition:

export const routes = {
  index: routeOf('/').action({
    component: () => 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:

import { useRouteComponent, ResponseCode } from '@fleur/froute'

export const App = () => {
  const { PageComponent } = useRouteComponent()

  return (
    <div>
      {PageComponent ? (
        <PageComponent /> 
      ) : (
        <ResponseCode status={404}>
          <NotFound />
        </ResponseCode>
      )}
    </div>
  )
}

User.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 (
      <ResponseCode status={404}>
        <NotFound />
      </ResponseCode>
    )
  }

  if (user.suspended) {
    return (
      <Redirect status={301} url='/'>
        This account is suspended.
      </Redirect>
    )
  }
  
  return (
    <div>
      Hello, {user.name}!
      <br />
      <Link href={buildPath(routes.user, { userId: '2' })}>
        Show latest update friend
      </Link>
    </div>
  )
}

Server side:

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(
    <FrouteContext router={router}>
      <App />
    </FrouteContext>
  )

  // Handling redirect
  if (router.redirectTo) {
    res.redirect(router.statusCode, router.redirectTo)
  } else{
    res.status(router.statusCode)
  }
  
  const stream = ReactDOM.renderToNodeStream(
    <Html>
      {content}
    </Html>
  ).pipe(res)

  router.dispose()
})

Client side:

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((
      <FrouteContext router={router}>
        <App />
      </FrouteContext>
    ),
    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
    • <Link /> only href props compatible but behaviour in-compatible.
      • Froute's Link has <a /> 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)

// Copy it in-your-app/useRouter.ts
import { useRouter as useNextCompatRouter } from '@fleur/froute'
export const useRouter: UseRouter = useNextCompatRouter

Usage:

// 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<typeof Routes['users']>()
  router.query.id // It infering to `string`.
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].