> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cskn.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Web Push

> Notifications for your app when it runs in a browser.

`requestNotificationPermission()` already picks the right path: the device token in a shell, a Web Push subscription in a browser. `useWebPush` is for the UI **around** that subscription: an on/off switch that reflects the real state, and the iOS install instructions.

```tsx theme={null}
import { useWebPush } from '@cskn/sdk';

function PushSwitch() {
  const { status, subscribe, unsubscribe } = useWebPush();

  if (!status) return null;                      // still asking the browser
  if (status.reason === 'native') return null;   // in a shell: already receiving
  if (status.installPrompt) return <p>Tap Share → “Add to Home Screen” to get notifications.</p>;
  if (status.reason === 'denied') return <p>Notifications are blocked in your browser settings.</p>;

  return status.subscribed
    ? <button onClick={unsubscribe}>Turn off notifications</button>
    : <button onClick={subscribe}>Turn on notifications</button>;
}
```

## Status

<ResponseField name="available" type="boolean">Whether subscribing is possible here.</ResponseField>
<ResponseField name="subscribed" type="boolean">Whether this browser holds a subscription for your app.</ResponseField>
<ResponseField name="permission" type="'default' | 'granted' | 'denied' | 'unsupported'">The browser's notification permission.</ResponseField>
<ResponseField name="installPrompt" type="boolean">iOS in a tab: the app must be added to the Home Screen first. Show instructions rather than a button.</ResponseField>

<ResponseField name="reason" type="string">
  Why it is unavailable: `native` (running in a shell), `unsupported` (no Push API), `needs-install` (iOS, not installed), `not-configured` (no push key on this deployment), `denied` (the user refused).
</ResponseField>

## Things to know

* **Subscriptions are per origin.** `photos.cskn.app` and `feed.cskn.app` need separate permission and separate subscriptions; one cannot push for the other.
* **Call `subscribe()` from a click.** Browsers do not show the prompt otherwise, and Chrome may remember the refusal permanently.
* **You ship no service worker or manifest.** The platform serves both on your app's origin (`/cskn-sw.js`, `/manifest.webmanifest`). If your app ships its own manifest, it is left alone.
* **`useWebPush` registers the service worker on mount.** That is also what makes the app installable and adds an offline fallback. Pass `{ register: false }` to skip it.

The hook also returns `refresh()`, plus `standalone` (running as an installed app) and `ios`. Functions: `getWebPushStatus`, `subscribeWebPush`, `unsubscribeWebPush`, `registerServiceWorker`, `isStandalone`, `isIos`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.