{"id":13788467,"url":"https://github.com/venantius/accountant","last_synced_at":"2025-05-16T09:05:55.939Z","repository":{"id":57713155,"uuid":"42385171","full_name":"venantius/accountant","owner":"venantius","description":"ClojureScript navigation for single-page applications, made simple.","archived":false,"fork":false,"pushed_at":"2023-08-28T15:24:05.000Z","size":66,"stargazers_count":252,"open_issues_count":5,"forks_count":39,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-05-09T10:06:50.022Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/venantius.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2015-09-13T05:41:09.000Z","updated_at":"2025-04-16T01:07:30.000Z","dependencies_parsed_at":"2024-01-13T09:36:19.752Z","dependency_job_id":"46b9f0b5-55f8-42e2-859e-7c57add84071","html_url":"https://github.com/venantius/accountant","commit_stats":{"total_commits":55,"total_committers":22,"mean_commits":2.5,"dds":0.6727272727272727,"last_synced_commit":"48ad34296724bacba710fd3a25a968cc9bd3a2df"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/venantius%2Faccountant","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/venantius%2Faccountant/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/venantius%2Faccountant/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/venantius%2Faccountant/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/venantius","download_url":"https://codeload.github.com/venantius/accountant/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254501557,"owners_count":22081528,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":"2024-08-03T21:00:47.341Z","updated_at":"2025-05-16T09:05:50.912Z","avatar_url":"https://github.com/venantius.png","language":"Clojure","funding_links":[],"categories":["front-end"],"sub_categories":[],"readme":"# Accountant\n\nAccountant is a ClojureScript library to make navigation in single-page\napplications simple.\n\nBy default, clicking a link in a ClojureScript application that isn't a simple\nURL fragment will trigger a full page reload. This defeats the purpose of using\nsuch elegant frameworks as Om, Reagent, et al.\n\nWith Accountant, links that correspond to defined routes will trigger\ndispatches to those routes and update the browser's path, but won't reload the\npage.\n\nAccountant also lets you navigate the app to a new URL directly, rather than through\n`\u003ca\u003e` tags.\n\nBe aware that Accountant relies on the browser's HTML5 history, so older\nbrowsers will be left behind.\n\n## Installation\n\nJust add the following to your `project.clj`:\n\n```clojure\n:dependencies [venantius/accountant \"0.2.5\"]\n```\n\n## Usage\n\nAll you have to do to get Accountant working is the following:\n\n```clojure\n(ns your-app-ns\n  (:require [accountant.core :as accountant]))\n\n(accountant/configure-navigation!\n  {:nav-handler   (fn [path] ...)\n   :path-exists?  (fn [path] ...)})\n```\n\nThe `:nav-handler` value is a fn of one argument, the path we're about to navigate to. You'll want to make whatever side-effect you need to render the page here. If you're using secretary, it'd look something like:\n\n```clojure\n(fn [path]\n  (secretary/dispatch! path))\n```\n\nIf you're using bidi + just rendering via react, that might look like:\n\n```clojure\n(fn [path]\n  (om/update! app [:path] path))\n```\n\nThe `:path-exists?` value is a fn of one argument, the path that we're about to navigate to.\nThe fn should return truthy if the path is\nhandled by your SPA, because accountant will call `event.preventDefault()` to\nprevent the browser from doing a full page request.\n\nUsing secretary, `:path-exists?` should have a value like:\n\n```clojure\n(fn [path]\n  (secretary/locate-route path))\n```\n\nUsing bidi, it would look like:\n\n```clojure\n(fn [path]\n  (boolean (bidi/match-route app-routes path)))\n```\n\nBy default, clicking a link to the currently active route will not trigger the\nnavigation handler. You can disable this behavior and always trigger the\nnavigation handler by setting `reload-same-path?` to true during configuration.\n\n```clojure\n(accountant/configure-navigation! {:nav-handler (fn [path] ...)\n                                   :path-exists? (fn [path] ...)\n                                   :reload-same-path? true})\n```\n\nYou can also use Accountant to set the current path in the browser, e.g.\n\n```clojure\n(accountant/navigate! \"/foo/bar/baz\")\n```\n\nIf you want to dispatch the current path, just add the following:\n\n```clojure\n(dispatch-current!)\n```\n\nNote that both `navigate!` and `dispatch-current!` can only be used after calling `configure-navigation!`\n\nTo cleanup the resources allocated by `configure-navigation!`, use `unconfigure-navigation!`. This is useful\nin cases where you create a component that manages configuring navigation, and would like to be able to easily\nstart/stop it.\n\n```clojure\n(accountant/unconfigure-navigation!)\n```\n\n### Caveat: UI Frameworks\nSometimes links may be used nested within UI components, especially when using third-party wrappers, like [react-bootstrap](https://react-bootstrap.github.io/) etc. These links may have an empty `href` attribute or a value like `#`. Two things might happen: Either, if a route is defined for the root path (i.e. '/' or '/#'), accountant will suppress the browser navigation and dispatch via secretary or the browser will reload the page.\n\nTo prevent this accountant looks for an attribute `data-trigger` on every link. The presence of this attribute signals that this link is a means to trigger a callback, not a navigation. If `data-trigger` is defined on a link it gets completely ignored, just like a button.\n\nExample: When using a [DropdownButton](https://react-bootstrap.github.io/components.html#btn-dropdowns) with [MenuItems](https://react-bootstrap.github.io/components.html#menu-items) each item will contain an `\u003ca href=\"#\"...\u003e` element. Since this element can't be replaced, we can at least add arbitrary attributes to it:\n\n```clojure\n(let [dropdown-button (reagent/adapt-react-class js/ReactBootstrap.DropdownButton)\n      menuitem (reagent/adapt-react-class js/ReactBootstrap.MenuItem)]\n  [dropdown-button {:id \"foo\" :title \"...\" :onSelect (fn [idx]...)}\n    [menuitem {:id \"1\"\n               :data-trigger true\n               :eventKey \"1\"}]\n```\n\n## License\n\nCopyright © 2017 W. David Jarvis\n\nDistributed under the Eclipse Public License, the same as Clojure.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvenantius%2Faccountant","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvenantius%2Faccountant","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvenantius%2Faccountant/lists"}