Skip to main content
When your web application runs inside the Despia native runtime, the user agent string includes “despia” along with platform identifiers like “iphone”, “ipad”, or “android”. Check navigator.userAgent to detect this and conditionally render platform-specific features.

Installation

npm install despia-native
import despia from 'despia-native';

How it works

The Despia runtime injects “despia” into the user agent string alongside the standard platform identifiers. A simple substring check tells you which environment your code is running in.
// Any Despia runtime
const isDespia = navigator.userAgent.toLowerCase().includes('despia')

// iOS only
const isDespiaIOS = isDespia && (
    navigator.userAgent.toLowerCase().includes('iphone') ||
    navigator.userAgent.toLowerCase().includes('ipad')
)

// Android only
const isDespiaAndroid = isDespia && navigator.userAgent.toLowerCase().includes('android')

Conditional payment flow

Show an in-app purchase button inside Despia and a web checkout flow in the browser. This is the standard pattern for hybrid apps that ship to both the App Store and the web, since native stores require their own billing for digital goods.
import { useState, useEffect } from 'react'
import despia from 'despia-native'

function CheckoutButton() {
    const [isDespia, setIsDespia] = useState(false)

    useEffect(() => {
        setIsDespia(navigator.userAgent.toLowerCase().includes('despia'))
    }, [])

    if (isDespia) {
        return (
            <button onClick={() => despia('iap://?productId=pro_monthly')}>
                Purchase in App
            </button>
        )
    }

    return (
        <button onClick={() => window.location.href = 'https://checkout.stripe.com/...'}>
            Purchase with Stripe
        </button>
    )
}

Platform-specific UI

Render different layouts or copy depending on which platform the user is on. Useful for store review compliance, where iOS and Android have different policy requirements around external links and payment language.
function App() {
    const userAgent = navigator.userAgent.toLowerCase()
    const isDespia = userAgent.includes('despia')
    const isDespiaIOS = isDespia && (userAgent.includes('iphone') || userAgent.includes('ipad'))
    const isDespiaAndroid = isDespia && userAgent.includes('android')

    return (
        <div>
            {isDespia && (
                <div className="banner">
                    Running natively on {isDespiaIOS ? 'iOS' : 'Android'}
                </div>
            )}

            {!isDespia && (
                <a href="/download">Get the app</a>
            )}
        </div>
    )
}

SSR safety

navigator is undefined during server-side rendering in frameworks like Next.js or Remix. Guard the check with a typeof test or run it inside useEffect so it executes on the client only.
const isDespia = typeof navigator !== 'undefined' &&
    navigator.userAgent.toLowerCase().includes('despia')

Resources

NPM Package

despia-native