# @wrnexus/mobile > SSR-safe access to Capacitor plugins from WRNexusJS browser code. ## Overview `@wrnexus/mobile` keeps optional native imports out of server rendering while giving browser-owned modules one consistent registry for Capacitor plugins. During SSR, `mobile.isNative()` is `false` and `mobile.platform()` is `"web"`. ## Installation Install a plugin through the WRNexusJS CLI so the web and native projects stay aligned: ```bash wrnexus mobile add @capacitor/camera @capacitor/haptics ``` ## Usage ### Register and invoke a Capacitor plugin Import Capacitor packages only from browser-owned code, never from API routes or SSR helpers. ```ts import { Camera, CameraResultType } from "@capacitor/camera"; import { mobile } from "@wrnexus/mobile"; mobile.registerPlugin("Camera", Camera); export async function takePhoto() { if (!mobile.isNative()) return null; return mobile.invoke("Camera", "getPhoto", { quality: 85, resultType: CameraResultType.Uri, }); } ``` ### Provide a browser fallback `whenNative` runs the first callback only in a Capacitor WebView and can return a web/SSR-safe fallback everywhere else. ```ts import { Haptics, ImpactStyle } from "@capacitor/haptics"; import { mobile } from "@wrnexus/mobile"; mobile.registerPlugin("Haptics", Haptics); export const confirmAction = () => mobile.whenNative( () => mobile.invoke("Haptics", "impact", { style: ImpactStyle.Medium }), () => navigator.vibrate?.(30), ); ``` ### Read an optional plugin without throwing ```ts import type { NetworkPlugin } from "@capacitor/network"; import { mobile } from "@wrnexus/mobile"; const network = mobile.plugin("Network"); const status = network ? await network.getStatus() : { connected: true, connectionType: "unknown" }; ``` ## API - `registerPlugin(name, instance)` registers a browser-imported plugin. - `plugin(name)` returns a plugin or `undefined`; `requirePlugin(name)` throws when absent. - `invoke(plugin, method, options?)` calls a registered method and returns its result. - `whenNative(native, fallback?)` selects native behavior without breaking SSR. - `isNative()` and `platform()` report the current Capacitor environment. Unavailable required plugins throw `MobileUnavailableError` with an actionable message. ## Requirements / Notes - Capacitor plugin imports must remain in browser-owned modules. - `@wrnexus/mobile` re-exports `native` from `@wrnexus/native` for applications that prefer the higher-level cross-platform capability API.