{"id":44936636,"url":"https://github.com/etaque/elm-transit-router","last_synced_at":"2026-02-18T07:32:38.238Z","repository":{"id":62418469,"uuid":"48905667","full_name":"etaque/elm-transit-router","owner":"etaque","description":"DEPRECATED - Drop-in router with transitions for animated, single page apps in Elm.","archived":false,"fork":false,"pushed_at":"2016-03-03T21:03:54.000Z","size":23,"stargazers_count":56,"open_issues_count":4,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-05-09T13:37:03.936Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Elm","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/etaque.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-01-02T10:02:12.000Z","updated_at":"2022-05-27T14:14:10.000Z","dependencies_parsed_at":"2022-11-01T16:46:16.935Z","dependency_job_id":null,"html_url":"https://github.com/etaque/elm-transit-router","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/etaque/elm-transit-router","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etaque%2Felm-transit-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etaque%2Felm-transit-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etaque%2Felm-transit-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etaque%2Felm-transit-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/etaque","download_url":"https://codeload.github.com/etaque/elm-transit-router/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etaque%2Felm-transit-router/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29572419,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T06:19:27.422Z","status":"ssl_error","status_checked_at":"2026-02-18T06:18:44.348Z","response_time":162,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-18T07:32:38.125Z","updated_at":"2026-02-18T07:32:38.231Z","avatar_url":"https://github.com/etaque.png","language":"Elm","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Elm Transit Router\n\n    elm package install etaque/elm-transit-router\n\nDrop-in router with animated route transitions for single page apps in [Elm](http://elm-lang.org/), extracted from (and used in) [Tacks](https://github.com/etaque/tacks/tree/master/client/src).\n\n\n## Features\n\n* Takes care of the *history* interaction and actions plumbing\n* Enables animated transition on route changes, thanks to [elm-transit](http://package.elm-lang.org/packages/etaque/elm-transit/latest)\n* Provides a simple `Signal.Address String` for navigation \n\nThere is a projet example with a minimal usage of the router [right here](./example).\n\n\n## Usage\n\nTo be able to provide animated route transitions, **TransitRouter** (and **Transit** underneath) works by action delegation: it will be able to emit `(Action, Effects Action)` by knowing how to wrap his own `TransitRouter.Action` type into your app's `Action` type. This is why the `actionWrapper` is needed in config below.\n\n\n### Model\n\nSay you have an `Action` type wrapping `TransitRouter.Action`:\n\n```elm\ntype Action = Foo | ... | RouterAction (TransitRouter.Action Route) | NoOp\n```\n\nAlso a `Route` type to describe all routes in your apps:\n\n```elm\ntype Route = Home | ... | NotFound | EmptyRoute\n```\n\nYou must then extend your model with `WithRoute` on `Route` type:\n\n```elm\ntype alias Model = TransitRouter.WithRoute Route \n  { foo: String }\n```\n\nYour `Model` is now enabled to work with `TransitRouter`. Initialize it with the `EmptyRoute` that should render nothing in your view, to avoid content flashing on app init.\n\n```elm\ninitialModel : Model\ninitialModel =\n  { transitRouter = TransitRouter.empty EmptyRoute\n  , foo = \"\"\n  }\n```\n\n\n### Update\n\nA config should be prepared:\n\n```elm\nrouterConfig : TransitRouter.Config Route Action Model\n\n-- which expands to:\nrouterConfig :\n  { mountRoute : Route -\u003e Route -\u003e Model -\u003e (Model, Effects Action)\n  , getDurations : Route -\u003e Route -\u003e Model -\u003e (Float, Float)\n  , actionWrapper : TransitRouter.Action Route -\u003e Action\n  , routeDecoder : String -\u003e Route\n  }\n```\n\n* In `mountRoute`, you'll provide what should be done in your `update` when a new route is mounted. The `Route` params are previous and new routes.\n\n* In `getDurations`, you'll return the transition durations, given previous/new route and current model. Write `\\_ _ _ -\u003e (50, 200)` if you always want an exit of 50ms then an enter of 200ms. You `mountRoute` will happend at the end of exit.\n\n* `actionWrapper` will be used to transform internal `TransitAction.Action` to your own `Action`.\n\n* `routeDecoder` takes the current path as input and should return the associated route.\nSee my [elm-route-parser](http://package.elm-lang.org/packages/etaque/elm-route-parser/latest) package for help on this.\n\n\nIt's now time to wire `init` and `update` functions:\n\n```elm\ninit : String -\u003e (Model, Effects Action)\ninit path =\n  TransitRouter.init routerConfig path initialModel\n```\n\nThis will parse and mount initial route on app init. You can get initial path value by setting up a `port` in main and provide current path from JS side.\n\nIn `update`, the lib will take care of routes updates and transition control.\n\n```elm\nupdate : Action -\u003e Model -\u003e (Model, Effects Action)\nupdate action model =\n  case action of\n\n    NoOp -\u003e\n      (model, Effects.none)\n\n    RouterAction routeAction -\u003e\n      TransitRouter.update routerConfig routeAction model\n\n    Foo -\u003e\n      (doFoo model, Effects.none)\n```\n\n\n### View\n\nThis is where visible part of routing happens. You just have to match current route to render the current route's view, using `getRoute`:\n\n\n```elm\ncontentView : Address Action -\u003e Model -\u003e Html\ncontentView address model =\n  case (TransitRouter.getRoute model) of\n\n    Home -\u003e\n      homeView address model\n    \n    --- and so on\n\n```\n\nNow for animations, there is `getTransition`, to be used with [elm-transit-style](http://package.elm-lang.org/packages/etaque/elm-transit-style/latest) (or directly with `Transit.getStatus` and `Transit.getValue` from [elm-transit](http://package.elm-lang.org/packages/etaque/elm-transit/latest)).\n\n```elm\nview : Address Action -\u003e Model -\u003e Html\nview address model =\n  div\n    [ style (TransitStyle.fadeSlideLeft 100 (getTransition model)) ]\n    [ contentView address model ]\n```\n\nLinks: use `pushPathAddress` for clink handling, for instance within that kind of helper:\n\n```elm\nclickTo : String -\u003e List Attribute\nclickTo path =\n  [ href path\n  , onWithOptions\n      \"click\"\n      { stopPropagation = True, preventDefault = True }\n      Json.value\n      (\\_ -\u003e message TransitRouter.pushPathAddress path)\n  ]\n```\n\n### Routing with Effects\n\nSuppose you are in the module of one of the screens and you want to switch routes after handling an action (for instance after handling the result from a task). You can do this by using the redirect effect:\n\n```elm\nredirect : Routes.Route -\u003e Effects ()\nredirect route =\n  Routes.toPath route\n    |\u003e Signal.send TransitRouter.pushPathAddress\n    |\u003e Effects.task\n```\n\nIn the update function of the screen module you will not have access to the `RouteAction` action, since it is defined in the main app module. To be able to make the effect work in your update function, map it to a null operation:\n\n```elm\nupdate : Action -\u003e Model -\u003e (Model, Effects Action)\nupdate action model =\n  case action of\n\n    NoOp -\u003e\n      (model, Effects.none)\n\n    TaskCompleted -\u003e\n      (model, Effects.map (\\_ -\u003e NoOp) (redirect Home))\n```\n\n\n## Subrouting transitions\n\nIf you app contains submenus, you might want to adapt the scope of transition animation, ie you only want to animate the submenu content when you switch from a submenu item to another, not the whole content of your page.\n\nA good way to do that is to create a type to indicate the current route switch happening, and to store it in your model, so you will be able to adapt the animation in your views. Let's say you have an admin submenu:\n\n```elm\ntype RouteSwitch = Global | InAdmin | NoSwitch\n\ntype alias Model = TransitRouter.WithRoute Route \n  { foo: String\n  , routeSwitch : RouteSwitch\n  }\n```\n\nTypes are in place, but we still need to set `routeSwitch` value, and `Config.mountRoute` is the right place for that as it provides previous and new route, so you can compare them and decide what is the current switch:\n\n```elm\nmountRoute : Route -\u003e Route -\u003e Model -\u003e (Model, Effects Action)\nmountRoute prevRoute newRoute model =\n  let\n    routeSwitch = case (prevRoute, newRoute) of\n      (Admin _, Admin _) -\u003e\n        InAdmin\n      _ -\u003e\n        Global\n    newModel = { model | routeSwitch = routeSwitch }\n  in\n    case newRoute of\n      ...\n```\n\nThen you have everything in your hands in order to show animation in the right view, be it global content or admin content only.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fetaque%2Felm-transit-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fetaque%2Felm-transit-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fetaque%2Felm-transit-router/lists"}