Skip to main content
Unlisted page
This page is unlisted. Search engines will not index it, and only users having a direct link can access it.

Extend App UI SDK API Reference

Last updated on April 21, 2026

Overview

note

If you scaffolded your project using the official Extend App UI templates, this package is already included. You don't need to install it manually.

The @accelbyte/sdk-extend-app-ui package is the official Extend App UI SDK for building Extend App UIs, which are micro-frontends embedded inside the AccelByte Gaming Services (AGS) Admin Portal. It provides:

  • A React context that handles authentication and permission checking.
  • A Vite dev plugin that proxies requests to the AGS backend.
  • TypeScript types for the module contract between the host (Admin Portal) and your app.

For the full TypeScript source and type definitions beyond what is documented here, see the @accelbyte/sdk-extend-app-ui package on npm.

Key terms

For shared terms (Namespace, IAM permissions, AGS Shared Cloud, AGS Private Cloud, App UI name), see Extend App UI key terms.

  • Micro-frontends: small, self-contained web applications embedded inside a larger portal. Extend App UIs are micro-frontends that run inside the AGS Admin Portal as native-feeling pages.

  • CORS: a browser security policy that blocks web pages from making direct API requests to a different domain than the one serving them. The devProxyPlugin works around this during local development by routing requests through the local dev server.

AppUIModule

AppUIModule is the entry point contract your app must export. The Admin Portal calls mount(container, context) when the user opens your App UI, and calls the cleanup function it returns when the user navigates away.

Minimal example:

// module.tsx
import { type AppUIModule } from '@accelbyte/sdk-extend-app-ui'
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'

export const module: AppUIModule = {
mount(container) {
const root = createRoot(container)

root.render(
<StrictMode>
<div>Hello world!</div>
</StrictMode>
)

return () => root.unmount()
}
}

Full example (with AGS SDK and permission checking):

To make AGS API calls or check permissions, wrap your app with AppUIContextProvider and QueryClientProvider. The SDK uses React Query internally, so a QueryClient is required.

// module.tsx
import { AppUIContextProvider, CrudType, useAppUIContext, type AppUIModule } from '@accelbyte/sdk-extend-app-ui'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'

const client = new QueryClient({ defaultOptions: { queries: { retry: false, refetchOnWindowFocus: false } } })

export const module: AppUIModule = {
mount(container, hostContext) {
const root = createRoot(container)

root.render(
<StrictMode>
<QueryClientProvider client={client}>
<AppUIContextProvider sdkConfig={hostContext.sdkConfig} isCurrentUserHasPermission={hostContext.isCurrentUserHasPermission}>
<Component />
</AppUIContextProvider>
</QueryClientProvider>
</StrictMode>
)

return () => root.unmount()
}
}

// eslint-disable-next-line react-refresh/only-export-components
const Component = () => {
const { isCurrentUserHasPermission } = useAppUIContext()

return (
<div>
<div>Hello world!</div>
<div hidden={!isCurrentUserHasPermission({ action: CrudType.READ, resource: 'ADMIN:NONEXISTENTRESOURCE' })}>Hello world!</div>
</div>
)
}

HostContext

HostContext is the object the Admin Portal passes as the second argument to your mount() function. It gives your App UI everything it needs to make authenticated AGS API calls and check the current user's permissions.

interface HostContext {
/** Core SDK configuration passed from the Admin Portal. Pass this to AppUIContextProvider. */
sdkConfig: SdkConfigOptions
/** The base path the Admin Portal uses to route requests for this App UI. */
basePath: string
/** Returns true if the current portal user has the given permission. */
isCurrentUserHasPermission: (permission: CrudRolePermission) => boolean
}

Pass hostContext.sdkConfig and hostContext.isCurrentUserHasPermission directly to AppUIContextProvider — the full example in AppUIModule shows this pattern.

AppUIContextProvider

AppUIContextProvider is a React context provider that initializes the AccelByte SDK and manages authentication and permission state for your App UI. Wrap your application root with this component.

interface AppUIContextProviderProps {
sdkConfig: SdkConfigOptions
/**
* Provided by the host in production. Omit in development —
* the provider will fall back to its own PermissionGuard.
*/
isCurrentUserHasPermission?: (permission: CrudRolePermission) => boolean
children: ReactNode
}

The provider detects the environment via NODE_ENV and switches behavior accordingly.

AspectDevelopmentProduction
AuthExchanges OAuth2 authorization code, refreshes tokens automaticallySkipped. Admin Portal manages auth.
PermissionsFetches current user and all roles from IAM, sets a permission checkerUses isCurrentUserHasPermission passed by the Admin Portal

Usage example:

import { AppUIContextProvider } from '@accelbyte/sdk-extend-app-ui'

function App() {
return (
<AppUIContextProvider sdkConfig={sdkConfig}>
<YourAppContent />
</AppUIContextProvider>
)
}

useAppUIContext

useAppUIContext is a React hook that gives child components access to the initialized SDK instance and permission utilities provided by AppUIContextProvider.

interface AppUIContextValue {
/** Initialized AccelByteSDK instance. Use this to call AGS APIs. */
sdk: AccelByteSDK
/** True while user data or roles are loading. */
isLoading: boolean
/** Returns true if the current user has the given permission. */
isCurrentUserHasPermission: (permission: CrudRolePermission) => boolean
}

Usage example:

Use isCurrentUserHasPermission to conditionally show UI elements based on the current user's access level. Pass a CrudRolePermission object with an action from CrudType and the permission resource string your Extend service requires.

import { useAppUIContext, CrudType } from '@accelbyte/sdk-extend-app-ui'

function TournamentListHeader() {
const { isCurrentUserHasPermission } = useAppUIContext()

return (
<p hidden={!isCurrentUserHasPermission({ action: CrudType.READ, resource: 'ADMIN:RANDOMRESOURCE' })}>
This header is only visible to users with READ access on ADMIN:RANDOMRESOURCE
</p>
)
}

CrudType is an enum with these values: CREATE, READ, UPDATE, DELETE. Replace ADMIN:RANDOMRESOURCE with the permission resource string for your service. See Permission Fundamentals for how resource strings are structured.

devProxyPlugin

devProxyPlugin is a Vite plugin that proxies API requests to the AGS backend during local development, avoiding CORS errors. Add it to your vite.config.ts.

function devProxyPlugin(options: {
/** AGS backend base URL. Must match the baseURL registered in your IAM OAuth client. */
baseUrl: string
/** OAuth2 redirect URI. Must match the redirect URI registered in your IAM OAuth client. */
redirectURI: string
}): Plugin
note

Both baseUrl and redirectURI must match the values registered in your IAM OAuth client. This is already taken care of by Extend Helper CLI with the setup-env command.

All requests to /proxy/* are forwarded to the AGS backend. Point your SDK's baseURL to /proxy in development:

const sdkConfig = {
baseURL: import.meta.env.DEV ? '/proxy' : 'https://your-ags-instance.accelbyte.io'
// ...
}

The plugin also handles Shared Cloud subdomain routing. In Shared Cloud, each namespace is served from its own subdomain (for example, spaceshooter-game.prod.gamingservices.accelbyte.io). AGS validates the Referer header of incoming requests to confirm they originate from the correct subdomain — a check that fails during local development because your requests come from localhost. To work around this, the plugin reads the access_token cookie, extracts the current namespace from it, and sets the Referer header on each proxied request to match the expected subdomain URL.

Types

For the complete TypeScript interface definitions of all exported types, see the @accelbyte/sdk-extend-app-ui package on npm.

TypeDescription
SdkConfigOptionsCore config passed to AccelByte.SDK()
HostContextObject passed from the host to mount(): sdkConfig, basePath, isCurrentUserHasPermission
AppUIModuleContract your app module must implement: mount(container, context): () => void
CrudRolePermissionPermission descriptor used with isCurrentUserHasPermission
CrudTypeEnum for CRUD actions with string values: CREATE, READ, UPDATE, DELETE

Next steps