{"id":16372555,"url":"https://github.com/bencompton/framework7-redux","last_synced_at":"2025-10-10T17:05:03.388Z","repository":{"id":15632905,"uuid":"78549288","full_name":"bencompton/framework7-redux","owner":"bencompton","description":"Framework7 plug-in to keep your Redux store in sync with Framework7","archived":false,"fork":false,"pushed_at":"2022-03-15T19:00:20.000Z","size":97,"stargazers_count":38,"open_issues_count":7,"forks_count":7,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-09-08T01:37:40.719Z","etag":null,"topics":["framework7","framework7-react","react","redux"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bencompton.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-10T15:59:33.000Z","updated_at":"2023-12-07T06:13:03.000Z","dependencies_parsed_at":"2022-07-21T06:47:16.612Z","dependency_job_id":null,"html_url":"https://github.com/bencompton/framework7-redux","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bencompton/framework7-redux","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bencompton%2Fframework7-redux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bencompton%2Fframework7-redux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bencompton%2Fframework7-redux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bencompton%2Fframework7-redux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bencompton","download_url":"https://codeload.github.com/bencompton/framework7-redux/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bencompton%2Fframework7-redux/sbom","scorecard":{"id":231729,"data":{"date":"2025-08-11","repo":{"name":"github.com/bencompton/framework7-redux","commit":"7699e6386c52219989781e78621fb740f5ffbbf6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.9,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":6,"reason":"4 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T04:58:20.815Z","repository_id":15632905,"created_at":"2025-08-17T04:58:20.815Z","updated_at":"2025-08-17T04:58:20.815Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001643,"owners_count":26083146,"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","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["framework7","framework7-react","react","redux"],"created_at":"2024-10-11T03:11:46.218Z","updated_at":"2025-10-10T17:05:03.367Z","avatar_url":"https://github.com/bencompton.png","language":"TypeScript","readme":"# Framework7 Redux\n### Framework7 plug-in to keep your Redux store in sync with Framework7\n\n[Framework7](https://github.com/nolimits4web/Framework7) has functionality like routing and showing + hiding modals. This means that there is state in Framework7 for things like the current URL, whether or not a modal is showing, etc. This state is therefore not available in your store, which means that things like time travel debugging and server rendering with server state sent to the client state won't work.\n\nFramework7 Redux is a Framework7 plug-in that syncs state in Framework7 with your store. It also provides actions that you can call to do things like navigate to a URL, go back, and show + hide an alert.\n\n### Who should use Framework7 Redux?\n\nIf you aren't already familiar with [Redux](https://github.com/reactjs/redux) and using React with [Framework7](http://framework7.io), then you will probably want to go learn those libraries before using Framework7 Redux.\n\nNote that **this library is not mandatory** for using Redux with Framework7 and React. When you use Redux with Framework7 and React, you're using state from your store to control what prop values get passed into your components and re-rendering your components when the state changes. This works just fine without this library.\n\nIf you want to control things like navigation and alert dialogs from Redux actions and want these things to work when you do server rendering or time-travel debugging, that's when you need to use Framework7 Redux. If you just want your components to be controlled by state and are fine with navigation and modals being handled outside of Redux, then you don't need Framework7 Redux.\n\n### Getting started\n\n#### Starter template\n\nThe simplest way to get started is to use the [Framework7 + React + Redux starter template](https://github.com/bencompton/framework7-redux-app-template).\n\n#### Custom setup\n\nPull down Framework7 Redux from NPM like so:\n\n```\nnpm install --save framework7-redux\n```\n\nNext, update your store code to look like this:\n\n```javascript\nimport { Framework7StateKernel, framework7Reducer, syncFramework7WithStore } from 'framework7-redux';\n\nexport const framework7StateKernel = new Framework7StateKernel();\n\nexport const store = createStore(\n  combineReducers({\n    framework7: framework7Reducer,\n    ...\n    ...\n  })\n);\n\nsyncFramework7WithStore(store, framework7StateKernel);\n```\n\nFinally, configure your root Framework7 app React component:\n\n```javascript\nimport Framework7 from 'framework7/framework7.esm.bundle';\nimport Framework7React, { App, Views } from 'framework7-react';\n\nimport { routes } from './routes';\nimport { store, framework7StateKernel } from './store';\nimport { framework7ReduxPlugin } from 'framework7-redux';\n\nconst params = {\n  ...\n  routes,\n  stateKernel: framework7StateKernel,\n  clicks: {\n    externalLinks: 'a[href=\"#\"]' // Bypass the built-in routing for link clicks\n  },\n  panel: {\n    closeByBackdropClick: false // Bypass the built-in routing when clicking panel backdrops\n  },\n  popup: {\n    closeByBackdropClick: false // Bypass the built-in routing when clicking popup backdrops\n  }\n};\n\nFramework7.use(Framework7React);\nFramework7.use(framework7ReduxPlugin);\n\nconst MyApp = () =\u003e {\n  return (\n    \u003cProvider store={store}\u003e\n      \u003cApp params={params}\u003e\n        \u003cViews\u003e\n          \u003cView id=\"main-view\" main url=\"/\" /\u003e                        \n        \u003c/Views\u003e\n      \u003c/App\u003e\n    \u003c/Provider\u003e\n  );\n};\n```\n\n### Navigation\n\nBy default, the router in Framework7 will automatically navigate to different pages when the user clicks an anchor tag with an href attribute. This works well for simpler apps, but for larger and more complex apps, it is recommended to handle all navigation through actions and only have presentation logic in your React components. In order to accomplish this, some default navigation settings in Framework7 must be disabled first.\n\n#### Links\n\nIn the Setup section above, the Framework7 param `clicks -\u003e externalLinks` is set to `a[href=\"#\"]` to disable the default automatic Framework7 Link routing behavior. Once that is disabled, you can then safely call actions from the Link's `onClick` event and control all routing through Redux actions.\n\n#### Tabs\n\nTabs in Framework7 can be controlled via routes, as described in the [routing docs](http://framework7.io/docs/routes.html). Once tabs are configured to be routable, the tab links should have `onClick` handlers that call actions just like any other link used with Framework7 Redux.\n\n #### Popups / Panels\n\nPopups and panels can be controlled via routes as of Framework7 v3, as described in the [routing docs](http://framework7.io/docs/routes.html). The behavior of closing Panels and Popups on backdrop click should also be disabled in the Framework7 parameters as shown in the Setup section above. Once that is accomplished, you can use actions to navigate forward to a Popup or Panel route to open them, and then use actions to navigate back to close the Popup or Panel.\n\n#### Navigating forward and back with actions\n\nOnce your the default Framework7 navigation behaviors are disabled and your components are configured to be routable, the following code can be used in your actions to control navigation:\n\n```javascript\nimport { navigateTo, goBack } from 'framework7-redux'\n\nvar routes = [{\n  path: '/',\n  component: HomePage\n}, {\n  path: '/page-1/',\n  component: Page1\n}];\n\n...\n...\n\n//Go to page 1\nstore.dispatch(navigateTo('/page-1/'));\n\n//Go to page 2 and replace page 1 in the history\nstore.dispatch(navigateTo('/page-1/', true));\n\n//Go back to the home page\nstore.dispatch(goBack());\n\n//Navigate a view other than main view\nstore.dispatch(nagivateTo('/left-panel/about/', true, 'left-panel-view'));\nstore.dispatch(goBack('left-panel-view');\n```\n\n### Modals\n\nFramework7's API can be called for alerts, confirm dialogs, etc. While this approach is fine for simpler apps, it is better to control modals via actions so their state will be in your store.\n\n```javascript\nimport { showAlert, closeAlert, showPreloader, hidePreloader } from 'framework7-redux'\n\t\n//Show an alert with no title and the specified alert text\nstore.dispatch(showAlert(('Alert text!'));\n\t\n//Close the alert\nstore.dispatch(closeAlert());\n\t\n//Show an alert with the specified text and title\nstore.dispatch(showAlert(('Alert text!', 'Alert title'));\n\t\n//Show the global app loading spinner\nstore.dispatch(showPreloader());\n\t\n//Hide the global app loading spinner\nstore.dispatch(hidePreloader());\n\t\n//Show the global app loading spinner with custom loading text\nstore.dispatch(showPreloader('Saving...'));\t\n\n//Show a confirm dialog\nstore.dispatch(showConfirm('Are you sure you want to do this?', 'Are you sure?'));\n\n//Cancel a confirm dialog\nstore.dispatch(cancelConfirm());\n\n//Accept a confirm dialog\nstore.dispatch(acceptConfirm());\n```\n\nIt is also possible to get a promise that resolves when the user closes an alert:\n\n```javascript\nimport {showAlert, closeAlert} from 'framework7-redux'\nimport {framework7StateKernel} from './store';\n\nstore.dispatch(showAlert('Alert text'));\n\nframework7StateKernel.getActionPromise(closeAlert().type)\n  .then(() =\u003e store.dispatch(showAlert('Alert closed!')));\n```\n\nYou can then use the promise in the appropriate manner for whatever async action middleware you are using. For example, here is how it would look in [redux-thunk](https://github.com/gaearon/redux-thunk):\n\n```javascript\nconst productFetchFailed = () =\u003e {\n  return dispatch =\u003e {\n    dispatch(showAlert('Product fetch failed!'));\n    \n    //Retry product fetch after the user clicks the \"Ok\" button on the alert\n    framework7StateKernel.getActionPromise(closeAlert().type)\n      .then(() =\u003e dispatch(fetchProducts()))\n  };\n};\n```\n\nHere is an example of a confirm dialog with redux-thunk:\n\n```javascript\nconst someRiskyAction = () =\u003e {\n  return dispatch =\u003e {\n    dispatch(showConfirm('Are you sure you want to do this?', 'Are you sure?'));\n\n    Promise.race([\n      framework7StateKernel.getActionPromise(acceptConfirm().type).then(() =\u003e true),\n      framework7StateKernel.getActionPromise(cancelConfirm().type).then(() =\u003e false)\n    ])\n    .then(confirmed =\u003e {\n      if (confirmed) {\n        dispatch(completeRiskyAction());\n      }\n    });\n  };\n};\n```\n\n### Selectors\n\nFramework7 Redux provides some selectors to retrieve info from your state:\n\n```javascript\nimport { getCurrentRoute, getPreviousRoute } from 'framework7-redux';\n\n// Returns the current URL in the history or undefined if none\nconst currentUrl = getCurrentRoute(store.getState());\n\n// Returns the previous URL in the history or undefined if none\nconst previousUrl = getPreviousRoute(store.getState());\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbencompton%2Fframework7-redux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbencompton%2Fframework7-redux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbencompton%2Fframework7-redux/lists"}