Skip to main content
The useUser hook returns session-stable user information. These values are set once at initialization and do not change during the session.

Basic usage

import { useUser } from "skybridge/web";

function UserInfo() {
  const { locale, userAgent } = useUser();

  return (
    <div>
      <p>Locale: {locale}</p>
      <p>Device: {userAgent.device.type}</p>
      <p>Touch: {userAgent.capabilities.touch ? "Yes" : "No"}</p>
    </div>
  );
}

Returns

type UserState = {
  locale: string;
  userAgent: UserAgent;
};

type UserAgent = {
  device: {
    type: "mobile" | "tablet" | "desktop" | "unknown";
  };
  capabilities: {
    hover: boolean;
    touch: boolean;
  };
};

locale

The user’s locale string in BCP 47 format (e.g., "en-US", "fr-FR", "ja-JP").

userAgent

Information about the user’s device and its capabilities.

userAgent.device.type

The type of device the user is on:
  • mobile - Mobile phone
  • tablet - Tablet device
  • desktop - Desktop or laptop computer
  • unknown - Unable to determine device type

userAgent.capabilities.hover

Whether the device supports hover interactions (typically true for desktop, false for touch-only devices).

userAgent.capabilities.touch

Whether the device supports touch interactions.

Examples

Localized Greeting

import { useUser } from "skybridge/web";

function LocalizedGreeting() {
  const { locale } = useUser();

  const greetings: Record<string, string> = {
    en: "Hello!",
    fr: "Bonjour!",
    es: "Hola!",
    de: "Hallo!",
    ja: "こんにちは!",
  };

  const language = locale.split("-")[0];
  const greeting = greetings[language] || greetings.en;

  return <h1>{greeting}</h1>;
}

Date Formatting

import { useUser } from "skybridge/web";

function LocalizedDate({ date }: { date: Date }) {
  const { locale } = useUser();

  const formattedDate = new Intl.DateTimeFormat(locale, {
    dateStyle: "full",
    timeStyle: "short",
  }).format(date);

  return <time dateTime={date.toISOString()}>{formattedDate}</time>;
}

Number and Currency Formatting

import { useUser } from "skybridge/web";

function PriceDisplay({ amount, currency }: { amount: number; currency: string }) {
  const { locale } = useUser();

  const formattedPrice = new Intl.NumberFormat(locale, {
    style: "currency",
    currency,
  }).format(amount);

  return <span className="price">{formattedPrice}</span>;
}

Responsive Component

import { useUser } from "skybridge/web";

function ResponsiveLayout({ children }: { children: React.ReactNode }) {
  const { userAgent } = useUser();

  const layoutClass = {
    mobile: "layout-compact",
    tablet: "layout-medium",
    desktop: "layout-full",
    unknown: "layout-full",
  }[userAgent.device.type];

  return <div className={layoutClass}>{children}</div>;
}

Touch-Friendly Controls

import { useUser } from "skybridge/web";

function Slider({ value, onChange }: { value: number; onChange: (v: number) => void }) {
  const { userAgent } = useUser();

  // Use larger touch targets on touch devices
  const thumbSize = userAgent.capabilities.touch ? 44 : 20;

  return (
    <input
      type="range"
      value={value}
      onChange={(e) => onChange(Number(e.target.value))}
      style={{
        height: thumbSize,
        cursor: userAgent.capabilities.hover ? "pointer" : "default",
      }}
    />
  );
}