types/browser
ArtworkRequestConfig
Properties
| Property | Type | Description |
|---|---|---|
method? | HttpMethod | - |
path? | string | The request path. - For browser requests, this is the track's url - For media requests, this is the track's src value - For artwork requests, this is the track's artwork URL |
baseUrl? | string | - |
headers? | Record<string, string> | - |
query? | Record<string, string> | - |
body? | string | - |
contentType? | string | - |
userAgent? | string | - |
resolve? | (track) => Promise<RequestConfig> | Per-track request resolution callback. Called for each track to generate the request configuration based on track metadata (artist, album, src, etc.). The returned config is merged with base configs, then passed to transform if provided. Example artwork: { resolve: async (track) => ({ path: /covers/${track.artist}/${track.album}.jpg, query: { quality: 'high' } }) } |
transform? | MediaRequestConfigTransformer | Final transformation callback for media/artwork requests. Called after resolve (if provided) with the merged request config. Receives optional ImageContext with size hints from Android Auto/CarPlay. Use this for: - Adding size query params dynamically - URL signing - Adding authentication tokens Param The merged request configuration Param Optional image context with size hints Example artwork: { transform: async ({ request, context }) => ({ ...request, query: { ...request.query, w: context?.width ? String(context.width) : '600', sig: await signUrl(request.path) } }) } |
imageQueryParams? | ImageQueryParams | Query parameter names for automatic context injection from CarPlay/Android Auto. When configured, the image context (size, color scheme) from CarPlay/Android Auto is automatically added as query parameters to artwork URLs. This is a simpler alternative to using transform for context-aware URLs. Example // CDN expects ?w=400&h=400 artwork: { baseUrl: 'https://images.cdn.com', imageQueryParams: { width: 'w', height: 'h' } } // CDN expects single size param ?size=400 artwork: { baseUrl: 'https://images.cdn.com', imageQueryParams: { width: 'size' } } |
BrowseError
type BrowseError = object;Return BrowseError from a browse callback to display an error to the user. The error message will be shown in an error dialog in CarPlay and Android Auto.
On the app side, the error is surfaced as a NavigationError with code: 'callback-error'. Use useNavigationError() to get the error details, or useFormattedNavigationError() for a display-friendly version.
Example
browse: async ({ path }) => {
if (!user.subscribed) {
return { error: 'Please subscribe to access this content' }
}
return fetchContent(path)
}Properties
error
error: string;BrowserConfiguration
type BrowserConfiguration = object;Properties
path?
optional path: string;Initial navigation path. Setting this triggers initial navigation to the specified path.
request?
optional request: TransformableRequestConfig;Shared request settings applied to all HTTP requests (browse, search, media, artwork). Specific configs override these defaults.
browse?
optional browse: BrowserSource;Default browse source when no matching route is found.
media?
optional media: MediaRequestConfig;Media/audio stream request configuration.
artwork?
optional artwork: ArtworkRequestConfig;Configuration for artwork/image requests. Used to transform artwork URLs for CDNs that require different authentication tokens, base URLs, or query parameters than audio requests.
Artwork URLs are transformed when tracks are processed (before being passed to media controllers like Android Auto). This is different from media requests which are transformed at playback time.
Note: Since media controllers load images directly from URLs, HTTP headers cannot be applied to artwork requests. Use query parameters for authentication tokens if your CDN supports it.
Example
// Different CDN for images with signed URL parameters
artwork: {
baseUrl: 'https://images.cdn.example.com',
query: { token: 'image-auth-token' }
}
// Per-track artwork URL resolution using track metadata
artwork: {
resolve: async (track) => ({
baseUrl: 'https://images.cdn.example.com',
path: `/covers/${track.artist}/${track.album}.jpg`,
query: { token: await getSignedToken(track) }
})
}search?
optional search: SearchSource;Configuration for search functionality. Enables search capabilities in the media browser, typically accessed through voice commands or search UI.
Optional - if not provided, search functionality will be disabled. Required for Android Auto/CarPlay voice search integration with support for structured voice commands.
Search receives structured parameters from voice commands like:
- "play music" → mode='any', query=""
- "play jazz" → mode='genre', genre="jazz", query="jazz"
- "play michael jackson" → mode='artist', artist="michael jackson", query="michael jackson"
- "play thriller by michael jackson" → mode='album', album="thriller", artist="michael jackson"
- "play billie jean" → mode='song', title="billie jean", query="billie jean"
Can be either:
- SearchSourceCallback: Receives SearchParams with query, and optional mode/artist/album/genre/title/playlist fields
- TransformableRequestConfig: API endpoint where all search parameters are automatically added to request.query:
- q: search query string (always present)
- mode: search mode (any/genre/artist/album/song/playlist) - omitted for unstructured search
- artist, album, genre, title, playlist: included when present
Example
// Callback approach - direct access to structured parameters
search: async (params) => {
// Use structured fields for precise searches
if (params.mode === 'artist' && params.artist) {
return await db.query('SELECT * FROM tracks WHERE artist = ?', [params.artist]);
}
if (params.mode === 'album' && params.album && params.artist) {
return await db.query('SELECT * FROM tracks WHERE album = ? AND artist = ?',
[params.album, params.artist]);
}
// Fall back to full-text search
return await searchByQuery(params.query);
}
// API configuration - parameters automatically added to query string
search: {
baseUrl: 'https://api.example.com/search',
// GET /search?q=thriller&mode=album&album=thriller&artist=michael+jackson&limit=20
transform(request) {
return {
...request,
query: { ...request.query, limit: 20 }
};
}
}tabs?
optional tabs: TabsSource;Configuration for navigation tabs in the media browser. The first tab's URL is automatically loaded when the browser starts.
Optional - if not provided, no tab navigation will be available. Limited to maximum 4 tabs for automotive platform compatibility (Android Auto/CarPlay).
Can provide static array of Track objects with urls as tabs, API configuration, or custom callback.
routes?
optional routes: Record<string, BrowserSource | RouteConfig>;Route-specific configurations. Maps URL paths to browse sources. Routes match by prefix, most specific (most slashes) wins.
Can be a simple BrowserSource or extended RouteConfig with media/artwork overrides.
Example
routes: {
'/favorites': async () => getFavorites(),
'/artists': { baseUrl: 'https://music-api.com' },
'/premium': {
browse: { baseUrl: 'https://premium-api.com' },
artwork: { baseUrl: 'https://premium-images.cdn.com' }
}
}singleTrack?
optional singleTrack: boolean;When true, only play the selected track without queuing siblings. When false (default), replace queue with all tracks from parent context and start at selected track.
Default
falseandroidControllerOfflineError?
optional androidControllerOfflineError: boolean;Show an offline error message in external controllers (Android Auto, Wear OS, Automotive) when network connectivity is lost.
When enabled, displays a standard offline error item in the media browser instead of the normal content when the network is offline.
Only applies to external Media3 controllers, not in-app browsing.
Default
truePlatform
android
carPlayUpNextButton?
optional carPlayUpNextButton: boolean;Enable the "Up Next" button on the CarPlay Now Playing screen.
When enabled, tapping "Up Next" shows the current playback queue, allowing users to see upcoming tracks and jump to a specific position.
The button is automatically hidden when the queue has only one track.
Default
truePlatform
ios
carPlayNowPlayingButtons?
optional carPlayNowPlayingButtons: CarPlayNowPlayingButton[];Configure up to 5 buttons on the CarPlay Now Playing screen. These buttons are arranged using the array order from left to right.
Example
carPlayNowPlayingButtons: ['repeat']Default
[]Platform
ios
formatNavigationError?
optional formatNavigationError: FormatNavigationErrorCallback;Callback to customize error messages for navigation errors. Used by CarPlay and available via useFormattedNavigationError() for app UI.
If not provided or returns undefined, default English messages are used.
Example
formatNavigationError: (error) => ({
title: t(`error.${error.code}`),
message: error.code === 'http-error'
? t('error.httpMessage', { status: error.statusCode })
: error.message
})BrowseResult
type BrowseResult =
| ResolvedTrack
| BrowseError;Result type for browse callbacks. Can be either a ResolvedTrack (success) or BrowseError (failure).
BrowserSource
type BrowserSource =
| ResolvedTrack
| BrowserSourceCallback
| TransformableRequestConfig;BrowserSourceCallback()
type BrowserSourceCallback = (param) => Promise<BrowseResult>;Parameters
| Parameter | Type |
|---|---|
param | BrowserSourceCallbackParam |
Returns
Promise<BrowseResult>
BrowserSourceCallbackParam
type BrowserSourceCallbackParam = object;Properties
path
path: string;routeParams?
optional routeParams: Record<string, string>;CarPlayNowPlayingButton
type CarPlayNowPlayingButton = "shuffle" | "repeat" | "favorite" | "playback-rate";Custom button types for CarPlay Now Playing screen.
'shuffle': Shuffle button that toggles shuffle mode on/off'repeat': Repeat button that cycles through off → track → queue → off'favorite': Heart button to toggle favorite state of current track'playback-rate': Playback speed button that cycles through rate options
Platform
ios
FormatNavigationErrorCallback()
type FormatNavigationErrorCallback = (params) => FormattedNavigationError | undefined;Callback to customize navigation error display. Return localized title and message for error presentation.
Parameters
| Parameter | Type | Description |
|---|---|---|
params | FormatNavigationErrorParams | Object containing error details and context |
Returns
FormattedNavigationError | undefined
Display information for the error, or undefined to use defaults
Example
// Override only specific error types or routes
formatNavigationError: ({ error, defaultFormatted, path }) => {
// Custom message for local server routes
if (error.code === 'network-error' && path.startsWith('/errors')) {
return {
title: 'Server Not Running',
message: 'Start the local server with: yarn server'
}
}
// Use default for other errors
return defaultFormatted
}FormatNavigationErrorParams
type FormatNavigationErrorParams = object;Parameters passed to the formatNavigationError callback.
Properties
error
error: NavigationError;The navigation error that occurred
defaultFormatted
defaultFormatted: FormattedNavigationError;The default formatted error (useful for selective overrides)
path
path: string;The path that was being navigated to when the error occurred
FormattedNavigationError
type FormattedNavigationError = object;Formatted navigation error for display in UI. Used by CarPlay/Android Auto and available via useFormattedNavigationError() for app UI.
Properties
title
title: string;Title shown in the error action sheet header.
Default values:
'content-not-found': "Content Not Found" (English)'network-error': "Network Error" (English)'http-error': System-localized status text (e.g., "Not Found", "Service Unavailable")'callback-error': "Error" (English)'unknown-error': "Error" (English)
message
message: string;Message body shown below the title in the error action sheet.
Default value: error.message
HttpMethod
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS";ImageContext
Context for image loading requests. Provides pixel dimensions and appearance info from Android Auto/CarPlay.
Example
// Use transform for custom URL manipulation
transform: async ({ request, context }) => ({
...request,
query: {
...request.query,
variant: context?.width && context.width < 200 ? 'thumb' : 'full'
}
})
// Or use imageQueryParams for simple declarative mapping
artwork: {
imageQueryParams: { width: 'w', height: 'h' }
}Properties
ImageQueryParams
Query parameter names for automatic context injection from CarPlay/Android Auto. Maps ImageContext fields to query parameter names for your CDN.
Properties
| Property | Type | Description |
|---|---|---|
width? | string | Query parameter name for width (e.g., 'w', 'width', 'size') |
height? | string | Query parameter name for height (e.g., 'h', 'height'). If omitted, only width is added. |
MediaRequestConfig
Configuration for media resource requests (audio streams, artwork images). Extends TransformableRequestConfig with per-track resolution capabilities.
Used for both media (audio streaming) and artwork (image loading) configuration in BrowserConfiguration.
Configuration Hierarchy
When a request is made, configs are merged in this order (later overrides earlier):
request(base config) - shared settings like user agent, common headersmedia/artworkconfig - resource-specific settingsresolve(track)result - per-track overrides (if provided)transform(request)result - final modifications (if provided)
Usage Patterns
Simple CDN configuration:
media: {
baseUrl: 'https://audio.cdn.example.com',
headers: { 'X-API-Key': 'your-api-key' }
}Per-track URL resolution:
media: {
resolve: async (track) => ({
baseUrl: 'https://audio.cdn.example.com',
path: `/streams/${track.src}`,
query: { token: await getSignedToken(track.src) }
})
}Dynamic request signing:
artwork: {
baseUrl: 'https://images.cdn.example.com',
transform: async (request) => ({
...request,
query: { ...request.query, sig: await signUrl(request.path) }
})
}See
- BrowserConfiguration.media - Audio stream configuration
- BrowserConfiguration.artwork - Image/artwork configuration
Properties
| Property | Type | Description |
|---|---|---|
method? | HttpMethod | - |
path? | string | The request path. - For browser requests, this is the track's url - For media requests, this is the track's src value - For artwork requests, this is the track's artwork URL |
baseUrl? | string | - |
headers? | Record<string, string> | - |
query? | Record<string, string> | - |
body? | string | - |
contentType? | string | - |
userAgent? | string | - |
transform? | RequestConfigTransformer | - |
resolve? | (track) => Promise<RequestConfig> | Per-track request resolution callback. Called for each track to generate the final request configuration. Receives the full Track object, allowing URL generation based on track metadata (artist, album, src, etc.). The returned config is merged with base configs, then passed to transform if provided. Example resolve: async (track) => ({ path: /audio/${track.artist}/${track.album}/${track.src}, query: { quality: 'high' } }) |
MediaRequestConfigTransformer()
type MediaRequestConfigTransformer = (params) => Promise<RequestConfig>;Transform callback for media/artwork requests. Unlike the route-based RequestConfigTransformer, this receives ImageContext for size-aware transformations instead of route parameters.
Use this when your CDN uses named variants or size presets. For simple pixel-based query params, use imageQueryParams instead.
Parameters
| Parameter | Type | Description |
|---|---|---|
params | MediaTransformParams | The transform parameters containing request and optional context |
Returns
Promise<RequestConfig>
Modified request configuration
Example
artwork: {
transform: async ({ request, context }) => ({
...request,
query: {
...request.query,
// Use semantic size for CDN variant selection
variant: context?.width && context.width < 200 ? 'thumb' : 'full',
sig: await signUrl(request.path)
}
})
}MediaTransformParams
Parameters for the media request transform callback.
Properties
| Property | Type | Description |
|---|---|---|
request | RequestConfig | The merged request configuration to transform |
context? | ImageContext | Optional image context with size hints from Android Auto/CarPlay |
RequestConfig
Properties
| Property | Type | Description |
|---|---|---|
method? | HttpMethod | - |
path? | string | The request path. - For browser requests, this is the track's url - For media requests, this is the track's src value - For artwork requests, this is the track's artwork URL |
baseUrl? | string | - |
headers? | Record<string, string> | - |
query? | Record<string, string> | - |
body? | string | - |
contentType? | string | - |
userAgent? | string | - |
RequestConfigTransformer()
type RequestConfigTransformer = (request, routeParams?) => Promise<RequestConfig>;Parameters
| Parameter | Type |
|---|---|
request | RequestConfig |
routeParams? | Record<string, string> |
Returns
Promise<RequestConfig>
RouteConfig
type RouteConfig = object;Route configuration with per-route media and artwork overrides.
Example
routes: {
'/premium': {
browse: async () => fetchPremiumContent(),
media: { baseUrl: 'https://premium-audio.cdn.com' },
artwork: { baseUrl: 'https://premium-images.cdn.com' }
}
}Properties
browse?
optional browse: BrowserSource;Override browse config for this route.
media?
optional media: MediaRequestConfig;Override media config for this route.
artwork?
optional artwork: ArtworkRequestConfig;Override artwork config for this route.
RouteSource
type RouteSource =
| BrowserSourceCallback
| TransformableRequestConfig;SearchMode
type SearchMode = "any" | "genre" | "artist" | "album" | "song" | "playlist";Search mode types for structured voice search.
any: Play any content - smart shuffle or last playlist (query will be empty string)genre: Search by genreartist: Search by artistalbum: Search by albumsong: Search by song/track titleplaylist: Search by playlist name
See
- BrowserConfiguration.search
- SearchParams
SearchParams
Structured search parameters from voice commands.
Voice commands are parsed by Android into structured parameters:
- "play something" → mode=null, query="something"
- "play music" → mode='any', query=""
- "play jazz" → mode='genre', genre="jazz", query="jazz"
- "play michael jackson" → mode='artist', artist="michael jackson", query="michael jackson"
- "play thriller by michael jackson" → mode='album', album="thriller", artist="michael jackson"
- "play billie jean" → mode='song', title="billie jean", query="billie jean"
Properties
| Property | Type | Description |
|---|---|---|
mode? | SearchMode | The search mode indicating what type of search is being performed, or null for unstructured search |
query | string | The original search query string (always present, but may be empty string ""). When mode='any' with empty string query, return any content you think the user would like (e.g., recently played, favorites, or smart shuffle). |
genre? | string | Genre name for genre-specific search |
artist? | string | Artist name for artist/album/song search |
album? | string | Album name for album-specific search |
title? | string | Song title for song-specific search |
playlist? | string | Playlist name for playlist-specific search |
SearchSource
type SearchSource =
| SearchSourceCallback
| TransformableRequestConfig;Search source configuration for handling search requests.
See
BrowserConfiguration.search
SearchSourceCallback()
type SearchSourceCallback = (params) => Promise<Track[]>;Parameters
| Parameter | Type |
|---|---|
params | SearchParams |
Returns
Promise<Track[]>
TabsSource
type TabsSource =
| Track[]
| TabsSourceCallback
| TransformableRequestConfig;Tab source configuration for navigation tabs.
When using API configuration (TransformableRequestConfig), the request path defaults to '/' and should return an array of Track objects with urls representing the tabs.
TabsSourceCallback()
type TabsSourceCallback = () => Promise<Track[]>;Returns
Promise<Track[]>
TransformableRequestConfig
Request configuration that supports async transformation. Extends RequestConfig with a transform callback for dynamic request modification.
The transform callback receives the merged request config and can modify it before the request is made. This is useful for adding dynamic headers, signing URLs, or other request-time modifications.
Example
const config: TransformableRequestConfig = {
baseUrl: 'https://api.example.com',
transform: async (request) => ({
...request,
headers: {
...request.headers,
'Authorization': `Bearer ${await getAccessToken()}`
}
})
}Properties
| Property | Type | Description |
|---|---|---|
method? | HttpMethod | - |
path? | string | The request path. - For browser requests, this is the track's url - For media requests, this is the track's src value - For artwork requests, this is the track's artwork URL |
baseUrl? | string | - |
headers? | Record<string, string> | - |
query? | Record<string, string> | - |
body? | string | - |
contentType? | string | - |
userAgent? | string | - |
transform? | RequestConfigTransformer | - |