Skip to content

a fast, declarative microrouter for rescript based on reroute works

Notifications You must be signed in to change notification settings

DCKT/rescript-router

Folders and files

NameName
Last commit message
Last commit date

Latest commit

3bbf30b Â· May 21, 2024

History

44 Commits
Sep 21, 2023
Sep 21, 2023
Sep 21, 2023
Sep 21, 2023
Oct 22, 2019
Sep 21, 2023
Sep 21, 2023
May 21, 2024
Sep 21, 2023
May 21, 2024
May 21, 2024
Oct 22, 2019
May 21, 2024

Repository files navigation

ReScript Router

This is project is based on the great old reroute module. It's just using the latest Reason React API (hooks & context).

Checkout this simple demo

Setup

Install the module :

$ yarn add @dck/rescript-router

Then add it to your bsconfig.json:

{
  "bs-dependencies": ["@rescript/react", "@dck/rescript-router"]
}

Usage

Create your configuration

open RescriptRouter

module RouterConfig = {
  type t =
    | Home
    | About
    | Hello(string)
    | NotFound

  let make = (url: RescriptReactRouter.url) =>
    switch url.path {
    | list{} => Home
    | list{"about"} => About
    | list{"hello", name} => Hello(name)
    | list{"404"}
    | _ =>
      NotFound
    }

  let toString = (route: t) =>
    switch route {
    | Home => "/"
    | About => "/about"
    | Hello(name) => "/hello/" ++ name
    | NotFound => "/404"
    }
}

module Router = CreateRouter(RouterConfig)

Add the Provider

module App = {
  @react.component
  let make = () =>
    <Router.Provider>
      {(~currentRoute) => <>
        <div className="container mx-auto p-4">
          <h1 className="text-xl font-semibold text-center mb-4 text-blue-700">
            {"RescriptRouter example"->React.string}
          </h1>
          <div className="flex flex-row items-center mb-4">
            <CustomLink route=RouterConfig.Home> {"Home"->React.string} </CustomLink>
            <CustomLink route=RouterConfig.About> {"About"->React.string} </CustomLink>
            <CustomLink route={RouterConfig.Hello("dck")}>
              {"Route with params"->React.string}
            </CustomLink>
          </div>
          {switch currentRoute {
          | RouterConfig.Home => <h1> {"Home"->React.string} </h1>
          | RouterConfig.About => <h1> {"About"->React.string} </h1>
          | RouterConfig.Hello(name) =>
            <div>
              <h1> {"Route with params"->React.string} </h1>
              <p> {("Hi : " ++ name)->React.string} </p>
            </div>
          | _ => <h1> {"404 not found"->React.string} </h1>
          }}
        </div>
      </>}
    </Router.Provider>
}

Use built-in Link module

Don't forget to use it inside the Provider 😉

module CustomLink = {
  @react.component
  let make = (~route: RouterConfig.t, ~children) => {
    <Router.Link
      className="rounded block px-3 py-2 bg-gray-200 mr-2 hover:bg-gray-300"
      activeClassName="bg-blue-500 text-white hover:bg-blue-600"
      route>
      children
    </Router.Link>
  }
}

Full example

open RescriptRouter

module RouterConfig = {
  type t =
    | Home
    | About
    | Hello(string)
    | NotFound

  let make = (url: RescriptReactRouter.url) =>
    switch url.path {
    | list{} => Home
    | list{"about"} => About
    | list{"hello", name} => Hello(name)
    | list{"404"}
    | _ =>
      NotFound
    }

  let toString = (route: t) =>
    switch route {
    | Home => "/"
    | About => "/about"
    | Hello(name) => "/hello/" ++ name
    | NotFound => "/404"
    }
}

module Router = CreateRouter(RouterConfig)

module CustomLink = {
  @react.component
  let make = (~route: RouterConfig.t, ~children) => {
    <Router.Link
      className="rounded block px-3 py-2 bg-gray-200 mr-2 hover:bg-gray-300"
      activeClassName="bg-blue-500 text-white hover:bg-blue-600"
      route>
      children
    </Router.Link>
  }
}

module App = {
  @react.component
  let make = () =>
    <Router.Provider>
      {(~currentRoute) => <>
        <div className="container mx-auto p-4">
          <h1 className="text-xl font-semibold text-center mb-4 text-blue-700">
            {"RescriptRouter example"->React.string}
          </h1>
          <div className="flex flex-row items-center mb-4">
            <CustomLink route=RouterConfig.Home> {"Home"->React.string} </CustomLink>
            <CustomLink route=RouterConfig.About> {"About"->React.string} </CustomLink>
            <CustomLink route={RouterConfig.Hello("dck")}>
              {"Route with params"->React.string}
            </CustomLink>
          </div>
          {switch currentRoute {
          | RouterConfig.Home => <h1> {"Home"->React.string} </h1>
          | RouterConfig.About => <h1> {"About"->React.string} </h1>
          | RouterConfig.Hello(name) =>
            <div>
              <h1> {"Route with params"->React.string} </h1>
              <p> {("Hi : " ++ name)->React.string} </p>
            </div>
          | _ => <h1> {"404 not found"->React.string} </h1>
          }}
        </div>
      </>}
    </Router.Provider>
}

Run demo

Install dependencies

yarn

Compiles ReScript files

yarn start

Run webpack-dev-server

yarn demo

Go to http://localhost:8000