概要
「ホーム画面に追加(a2hs)」「パスキー(passkeys)」「プッシュ通知(push)」について、 使える環境か判定し、使えなければ標準ブラウザへ誘導、使える場合はやり方を案内する フレームワーク非依存(Vanilla JS / TS)のライブラリです。各機能は判定とユーザー向け案内に徹し、 パスキーの登録処理やプッシュの購読自体は行いません(それらはホスト側 / 別サービスの実装)。
このページは AI / 開発者がこのページだけを読んで統合できることを目的にしています。 機械可読なプレーン版は llms.txt にあります。
インストール
npm レジストリ(npmjs.com)には公開していません。JSR または GitHub Packages から取得します。
# JSR(推奨)
npx jsr add @kuboon/browser-how-to
# Deno: deno add jsr:@kuboon/browser-how-to
# GitHub Packages(npm 互換): 先に .npmrc を用意
# @kuboon:registry=https://npm.pkg.github.com
npm i @kuboon/browser-how-to
エントリ(サブパス)
必要な機能だけ import すれば、他の機能はバンドルされません(tree-shaking)。push は内部で a2hs を利用します。
| import | 内容 |
|---|---|
@kuboon/browser-how-to | 端末・ブラウザ・アプリ内ブラウザの検出と型 |
@kuboon/browser-how-to/a2hs | ホーム画面追加:判定・手順(ヘッドレス) |
@kuboon/browser-how-to/a2hs/ui | ホーム画面追加:案内モーダル UI |
@kuboon/browser-how-to/passkeys | パスキー:判定・説明(ヘッドレス) |
@kuboon/browser-how-to/passkeys/ui | パスキー:案内モーダル UI |
@kuboon/browser-how-to/push | プッシュ通知:判定(ヘッドレス) |
@kuboon/browser-how-to/push/ui | プッシュ通知:案内モーダル UI |
最短の使い方(UI つき)
各 show*Guide() は環境を判定し、状況に応じたモーダル(許可ボタン / 機種別手順 / 標準ブラウザ誘導)を出し分けます。戻り値 { close() } で閉じられます。
import { showA2hsGuide } from "@kuboon/browser-how-to/a2hs/ui";
import { showPasskeyGuide } from "@kuboon/browser-how-to/passkeys/ui";
import { showPushGuide } from "@kuboon/browser-how-to/push/ui";
document.querySelector("#install").addEventListener("click", () => showA2hsGuide());
document.querySelector("#passkey").addEventListener("click", () => showPasskeyGuide());
document.querySelector("#push").addEventListener("click", () => showPushGuide());
UI のスタイルは bht- プレフィックスの CSS クラスで上書きできます。
すべての show*Guide(options?) は共通オプション { userAgent?, zIndex?, onClose? } を受け付けます。
ルート: 検出 API @kuboon/browser-how-to
import { detectDevice } from "@kuboon/browser-how-to";
const device = detectDevice(/* userAgent?: string */);
// device.platform : "ios" | "ipados" | "android" | "desktop" | "unknown"
// device.browser : "safari" | "chrome" | "firefox" | "samsung" | "edge" | "opera" | "other"
// device.osVersion : { major: number, minor: number } | null
// device.isStandalone: boolean // ホーム画面アプリとして起動中か
// device.inApp : { isInApp: boolean, appId: string | null, appLabel: string | null }
// appId 例: "messenger" | "facebook" | "instagram" | "line" | "twitter" | "wechat"
// | "tiktok" | "threads" | "kakaotalk" | "snapchat" | "pinterest" | "generic-webview"
その他のエクスポート(すべて同期):
detectInAppBrowser(ua): InAppBrowserInfoisStandardBrowser(device): boolean(iOS=Safari / Android=主要ブラウザ かつ アプリ内でない)escapeInAppBrowser(device, options?): EscapeResult— アプリ内ブラウザから標準ブラウザへ脱出detectPlatform / detectBrowser / detectOsVersion / detectStandalonebuildAndroidIntentUrl(url, pkg?) / buildSafariSchemeUrl(url)
EscapeOptions = { url?: string; androidPackage?: string; navigate?: (target: string) => void }
EscapeResult は { method: "redirect"; ok: true; target: string; fallbackSteps: GuideStep[] }
(Android=intent:// / iOS=x-safari-https:// で遷移を試行)か
{ method: "manual"; ok: false; steps: GuideStep[] }(PC 等)。
GuideStep = { text: string; icon?: string; note?: string }
/a2hs — ホーム画面に追加
import { createA2hs } from "@kuboon/browser-how-to/a2hs";
const a2hs = createA2hs(/* { userAgent? } */);
const status = a2hs.getStatus();
// status.support: "installed" | "native-prompt" | "manual" | "in-app-blocked" | "unsupported"
// status.canPrompt: boolean // OS のインストールダイアログを出せるか(Android Chrome 系)
// status.device: DeviceInfo
if (status.support === "native-prompt") {
const outcome = await a2hs.promptInstall(); // "accepted" | "dismissed" | "unavailable"
} else if (status.support === "manual") {
const { title, steps, note } = a2hs.getInstructions(); // 機種別の手順
} else if (status.support === "in-app-blocked") {
a2hs.escapeInAppBrowser(); // Android=自動遷移 / iOS=x-safari 試行+手順
}
// インストール可能/済みの変化を購読
const off = a2hs.onChange((s) => console.log(s.support));
UI: showA2hsGuide({ userAgent?, zIndex?, onClose?, onInstalled?, controller? })。
beforeinstallprompt は import 時に自動捕捉します(PWA 化には manifest が別途必要)。
InstructionSet = { title: string; steps: GuideStep[]; note?: string }
/passkeys — パスキー
import { createPasskeyGuide, detectPasskeyStatus } from "@kuboon/browser-how-to/passkeys";
const status = await detectPasskeyStatus(/* { userAgent? } */);
// status.support: "full" | "cross-device-only" | "in-app-blocked" | "unsupported"
// status.capabilities: {
// webauthnSupported, platformAuthenticatorAvailable, conditionalMediationAvailable,
// crossDeviceSupported, relatedOriginsSupported, usedClientCapabilities
// } // すべて boolean
// status.device: DeviceInfo
const guide = createPasskeyGuide();
guide.explain("what-is-passkey"); // { title, body: string[], steps? }
guide.explain("cross-device"); // スマホで作ったパスキーを PC で使う(QR)手順
guide.explain("where-saved"); // 保存場所(iCloud キーチェーン / Google パスワードマネージャー)
判定は PublicKeyCredential.getClientCapabilities()(未対応は isUVPAA() 等にフォールバック)。
実際の登録・認証(navigator.credentials)はサーバー連携が必要なためホスト側で実装します。
UI: showPasskeyGuide({ userAgent?, zIndex?, onClose?, controller? })。
/push — プッシュ通知(案内のみ)
import { createPushGuide, detectPushStatus } from "@kuboon/browser-how-to/push";
const status = detectPushStatus(/* { userAgent? } */); // 同期
// status.support: "ready" | "needs-install" | "in-app-blocked" | "denied" | "unsupported"
// ready : この後ブラウザの許可ダイアログで「許可」を選べば受け取れる
// needs-install : iOS で未インストール → 先にホーム画面追加(a2hs)が必要
// in-app-blocked: アプリ内ブラウザ → 標準ブラウザへ誘導
// denied : ブロック済み → 設定から再許可(getReenableSteps() に手順)
// unsupported : 通知に非対応
// status.permission: "default" | "granted" | "denied" | "unsupported"
const push = createPushGuide();
push.getReenableSteps(); // GuideStep[](端末別の再許可手順)
通知の購読・許可要求は行いません(前提条件の案内に徹します)。
iOS は「ホーム画面に追加した PWA」でのみ Web Push が使えるため、
showPushGuide() は needs-install 時に内部で showA2hsGuide() を呼び出します。
UI: showPushGuide({ userAgent?, zIndex?, onClose?, controller? })。
挙動メモ
- アプリ内ブラウザ(Messenger / Facebook / Instagram / LINE / X など)では a2hs・passkeys・push が使えないため、標準ブラウザへ誘導します(Android=
intent://自動遷移 / iOS=x-safari-https://試行+手動手順)。 - Android は
beforeinstallpromptを捕捉してワンタップでインストール(native-prompt)。iOS は「共有 → ホーム画面に追加」の手順案内(manual)。 - すべての検出関数は
userAgentを引数で差し替え可能(SSR / テスト向け)。 - 案内文言は日本語のみ。UI は
bht-クラスで上書き可能。