Chuyển tới nội dung chính

Host Context

useHostContext trả về object McpUiHostContext chứa thông tin môi trường từ host (V-App) — ngôn ngữ, theme, platform, kích thước container, timezone, v.v. Widget dùng thông tin này để thích nghi với ngữ cảnh đang chạy.

import { useHostContext } from '@v-miniapp/ai/web'

function MyWidget() {
const ctx = useHostContext()
// ctx có thể undefined nếu host chưa gửi context

return <div data-theme={ctx?.theme}>...</div>
}

Danh sách thuộc tính

Tất cả thuộc tính đều optional — widget nên kiểm tra ctx?.property trước khi dùng.

Thuộc tínhKiểuMô tả
localestringNgôn ngữ người dùng theo chuẩn BCP 47 (vd: "vi", "en-US")
theme"light" | "dark"Theme màu sắc hiện tại của host
platform"web" | "desktop" | "mobile"Nền tảng đang chạy widget
displayMode"inline" | "fullscreen" | "pip"Chế độ hiển thị hiện tại của widget
availableDisplayModesMcpUiDisplayMode[]Danh sách display mode mà host hỗ trợ
containerDimensionsobjectKích thước iframe container
deviceCapabilitiesobjectKhả năng input của thiết bị (hover, touch)
safeAreaInsetsobjectVùng safe area trên mobile (đơn vị px)
stylesobjectCSS variables và blocks để theming theo host
timeZonestringTimezone người dùng theo chuẩn IANA
toolInfoobjectMetadata của lần gọi tool đã mở widget
userAgentstringĐịnh danh ứng dụng host

locale

Ngôn ngữ và vùng của người dùng theo chuẩn BCP 47.

const ctx = useHostContext()
console.log(ctx?.locale) // "vi", "en-US", "ja", ...

Dùng locale để chọn ngôn ngữ hiển thị cho widget. Xem hướng dẫn đầy đủ tại Đa ngôn ngữ.


theme

Theme màu sắc hiện tại của host: "light" hoặc "dark".

function MyWidget() {
const ctx = useHostContext()
const isDark = ctx?.theme === 'dark'

return (
<div style={{ background: isDark ? '#1a1a1a' : '#ffffff', color: isDark ? '#fff' : '#000' }}>
...
</div>
)
}
ghi chú

Thông thường không cần đọc theme trực tiếp — AIApp provider (từ @v-miniapp/ui-react) tự apply theming từ host context vào toàn bộ widget.


platform

Nền tảng đang chạy widget: "web", "desktop", hoặc "mobile". Dùng để quyết định layout phù hợp.

const ctx = useHostContext()

if (ctx?.platform === 'mobile') {
// Dùng layout compact, bottom sheet, v.v.
} else {
// Dùng layout rộng hơn cho desktop/web
}

displayMode và availableDisplayModes

displayMode cho biết widget đang được hiển thị theo chế độ nào:

Giá trịMô tả
"inline"Nhúng trong context hiện tại (mặc định)
"fullscreen"Hiển thị toàn màn hình
"pip"Picture-in-picture

availableDisplayModes là mảng các chế độ mà host hỗ trợ — dùng để biết host có cho phép chuyển sang fullscreen hay không.

const ctx = useHostContext()

console.log(ctx?.displayMode) // "inline"
console.log(ctx?.availableDisplayModes) // ["inline", "fullscreen"]

const canGoFullscreen = ctx?.availableDisplayModes?.includes('fullscreen')

containerDimensions

Kích thước thực tế của iframe container chứa widget. Truyền width hoặc maxWidth, và height hoặc maxHeight.

type containerDimensions =
({ width: number } | { maxWidth?: number }) &
({ height: number } | { maxHeight?: number })
const ctx = useHostContext()
const dims = ctx?.containerDimensions

// Đọc chiều rộng (width hoặc maxWidth)
const width = 'width' in (dims ?? {}) ? (dims as any).width : (dims as any)?.maxWidth

// Đọc chiều cao (height hoặc maxHeight)
const height = 'height' in (dims ?? {}) ? (dims as any).height : (dims as any)?.maxHeight

deviceCapabilities

Khả năng input của thiết bị — dùng để quyết định có hiển thị tooltip hover hay cần hỗ trợ touch gesture.

Thuộc tínhKiểuMô tả
hoverbooleanThiết bị hỗ trợ hover (con trỏ chuột)
touchbooleanThiết bị hỗ trợ touch input
const ctx = useHostContext()
const { hover, touch } = ctx?.deviceCapabilities ?? {}

// Chỉ hiển thị tooltip khi device hỗ trợ hover
const showTooltipOnHover = hover === true

safeAreaInsets

Vùng an toàn của màn hình trên thiết bị mobile — tránh bị che bởi notch, dynamic island, thanh điều hướng hệ thống, v.v. Đơn vị: px.

Thuộc tínhKiểuMô tả
topnumberInset phía trên (px)
bottomnumberInset phía dưới (px)
leftnumberInset phía trái (px)
rightnumberInset phía phải (px)
const ctx = useHostContext()
const insets = ctx?.safeAreaInsets

return (
<div style={{
paddingTop: insets?.top ?? 0,
paddingBottom: insets?.bottom ?? 0,
}}>
...
</div>
)

timeZone

Timezone của người dùng theo chuẩn IANA Time Zone Database.

const ctx = useHostContext()
const tz = ctx?.timeZone // "Asia/Ho_Chi_Minh", "America/New_York", ...

// Dùng với Intl.DateTimeFormat để format ngày giờ đúng timezone
const formatter = new Intl.DateTimeFormat('vi-VN', {
timeZone: tz,
dateStyle: 'full',
timeStyle: 'short',
})

console.log(formatter.format(new Date())) // "Thứ Sáu, 7 tháng 3, 2025 lúc 10:30"

toolInfo

Metadata của lần gọi tool đã mở widget. Dùng khi widget cần biết tool nào đã kích hoạt nó hoặc cần lấy thông tin tool.

Thuộc tínhKiểuMô tả
idstring?JSON-RPC request ID của lần gọi tool
tool.namestringTên tool
tool.titlestring?Tiêu đề hiển thị của tool
tool.descriptionstring?Mô tả tool
tool.inputSchemaobjectJSON Schema đầu vào
tool.outputSchemaobject?JSON Schema đầu ra
tool.annotationsobject?Gợi ý hành vi: readOnlyHint, destructiveHint, v.v.
const ctx = useHostContext()

console.log(ctx?.toolInfo?.tool.name) // "list-orders"
console.log(ctx?.toolInfo?.id) // "req-abc123"
mẹo

Trong hầu hết trường hợp, widget đọc kết quả tool qua useToolInfo() thay vì toolInfo trong hostContext. toolInfo trong hostContext chủ yếu dùng để đọc metadata của tool (tên, schema) — không phải kết quả thực thi.


styles

Thông tin style từ host để widget tự theming theo giao diện của V-App.

Thuộc tínhKiểuMô tả
variablesMcpUiStylesCSS variables cho theming
cssMcpUiHostCssCSS blocks có thể inject
const ctx = useHostContext()
// Thông thường không cần đọc trực tiếp
ghi chú

Widget không cần dùng styles trực tiếp. AIApp provider (từ @v-miniapp/ui-react) tự nhận và apply toàn bộ theming từ host context — bao gồm CSS variables và color scheme.


userAgent

Chuỗi định danh ứng dụng host — tương tự navigator.userAgent nhưng của V-App.

const ctx = useHostContext()
console.log(ctx?.userAgent) // "V-App/2.x.x iOS/17.0"