{"id":22665147,"url":"https://github.com/br0ken-/web-push-api","last_synced_at":"2025-10-12T02:39:45.180Z","repository":{"id":139226575,"uuid":"239957228","full_name":"BR0kEN-/web-push-api","owner":"BR0kEN-","description":"Utility to subscribe/unsubscribe to Push API notifications and syncing with backend.","archived":false,"fork":false,"pushed_at":"2020-02-14T10:08:24.000Z","size":13,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-06T08:12:41.411Z","etag":null,"topics":["push-api","push-notifications","web-push","web-push-api"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/BR0kEN-.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-12T08:03:29.000Z","updated_at":"2020-08-02T14:46:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"e1f33488-a912-4feb-9777-e432e64ffa1e","html_url":"https://github.com/BR0kEN-/web-push-api","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BR0kEN-%2Fweb-push-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BR0kEN-%2Fweb-push-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BR0kEN-%2Fweb-push-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BR0kEN-%2Fweb-push-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BR0kEN-","download_url":"https://codeload.github.com/BR0kEN-/web-push-api/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246165524,"owners_count":20734045,"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":["push-api","push-notifications","web-push","web-push-api"],"created_at":"2024-12-09T13:19:46.824Z","updated_at":"2025-10-12T02:39:40.146Z","avatar_url":"https://github.com/BR0kEN-.png","language":"JavaScript","readme":"# Web Push API\n\nThe API for subscribing/unsubscribing to [Push API](https://developer.mozilla.org/en-US/docs/Web/API/Push_API) notifications and optional syncing the subscription to your backend.\n\n## Installation\n\n```bash\nnpm i --save web-push-api\n```\n\n## Usage\n\n### Abstract example.\n\n```javascript\nimport { isSupported, getPushSubscriptionFlow, getPushSubscriptionPayload } from 'web-push-api';\n\nif (isSupported) {\n  getPushSubscriptionFlow((method, pushSubscription) =\u003e {\n    sendRequestToBackend(method, getPushSubscriptionPayload(pushSubscription));\n  });\n}\n```\n\n### React component\n\n```javascript\nimport React, { useEffect, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { isSupported, getPushSubscriptionFlow, getPushSubscriptionPayload } from 'web-push-api';\n\nimport Spinner from 'your-spinner-component';\n\nconst flow = !isSupported ? null : getPushSubscriptionFlow((method, pushSubscription) =\u003e {\n  fetch('https://example.com/web-push-api/subscription', { method, body: getPushSubscriptionPayload(pushSubscription) })\n    .then((response) =\u003e response.json())\n    .then(({ errors }) =\u003e errors.map(showError))\n    .catch(showError);\n});\n\n/**\n * @param {Error|string} error\n */\nfunction showError(error) {\n  alert(error instanceof Error ? error.message : error);\n}\n\n/**\n * @param {function(state: Object): void} updateState\n * @param {('getPermission'|'getSubscription'|'subscribe'|'unsubscribe')} method\n * @param {('permission'|'subscription')} affects\n * @param {string|null} valueOnError\n * @param {string} [applicationServerKey]\n */\nfunction doFlowAction(updateState, method, affects, valueOnError, applicationServerKey) {\n  (async () =\u003e {\n    let value = valueOnError;\n\n    try {\n      value = await flow[method](applicationServerKey);\n    } catch (error) {\n      showError(error);\n    }\n\n    updateState({ processing: false, [affects]: value });\n  })();\n}\n\n/**\n * @param {function(state: Object): void} updateState\n * @param {('subscribe'|'unsubscribe')} method\n * @param {string} [applicationServerKey]\n *\n * @return {function(event: Event): void}\n */\nfunction getFlowActionHandler(updateState, method, applicationServerKey) {\n  return (event) =\u003e {\n    event.preventDefault();\n    updateState({ processing: true });\n    doFlowAction(updateState, method, 'subscription', null, applicationServerKey);\n  };\n}\n\nfunction PushNotificationsSubscriber({ offline, applicationServerKey }) {\n  const [{ permission, subscription, processing = true }, setState] = useState({});\n  const updateState = (state) =\u003e setState((prevState) =\u003e ({ ...prevState, ...state }));\n  let children;\n\n  useEffect(() =\u003e {\n    if (permission === undefined) {\n      doFlowAction(updateState, 'getPermission', 'permission', 'denied');\n    } else if (!offline \u0026\u0026 permission === 'granted' \u0026\u0026 subscription === undefined) {\n      doFlowAction(updateState, 'getSubscription', 'subscription', null);\n    }\n  }, [offline, permission, subscription, updateState]);\n\n  if (processing) {\n    children = (\n      \u003cSpinner small /\u003e\n    );\n  } else if (permission !== 'granted' || offline) {\n    const title = offline \n      ? 'This feature is not available since the app is offline. Please come back later.' \n      : 'Please turn notifications on. This will allow you receiving updates even if the application is closed.';\n\n    children = (\n      \u003cspan title={ title }\u003e\n        \u003ci className=\"icon-notifications-off\" /\u003e\n      \u003c/span\u003e\n    );\n  } else if (subscription === null) {\n    children = (\n      \u003cbutton\n        title=\"Click to subscribe to push notifications.\"\n        onClick={ getFlowActionHandler(updateState, 'subscribe', applicationServerKey) }\n      \u003e\n        \u003ci className=\"icon-notifications-none\" /\u003e\n      \u003c/button\u003e\n    );\n  } else {\n    children = (\n      \u003cbutton\n        title=\"Click to unsubscribe from push notifications.\"\n        onClick={ getFlowActionHandler(updateState, 'unsubscribe') }\n      \u003e\n        \u003ci className=\"icon-notifications-active\" /\u003e\n      \u003c/button\u003e\n    );\n  }\n\n  return (\n    \u003cdiv className=\"push-notifications\"\u003e\n      { children }\n    \u003c/div\u003e\n  );\n}\n\nPushNotificationsSubscriber.propTypes = {\n  offline: PropTypes.bool.isRequired,\n  applicationServerKey: PropTypes.string.isRequired,\n};\n\nexport default flow ? PushNotificationsSubscriber : () =\u003e null;\n```\n\n## Alternatives\n\n- https://github.com/dmitry-korolev/push-js\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbr0ken-%2Fweb-push-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbr0ken-%2Fweb-push-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbr0ken-%2Fweb-push-api/lists"}