diff --git a/.gitmodules b/.gitmodules
index 69fadb243778..b77afc4b8580 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -154,14 +154,14 @@
branch = main
shallow = true
[submodule "web-ui"]
- path = open-video-ui/external/web-ui
+ path = theoplayer/external/web-ui
url = https://github.com/THEOplayer/web-ui.git
branch = main
[submodule "android-ui"]
- path = open-video-ui/external/android-ui
+ path = theoplayer/external/android-ui
url = https://github.com/THEOplayer/android-ui.git
branch = main
[submodule "react-native-theoplayer-ui"]
- path = open-video-ui/external/react-native-theoplayer-ui
+ path = theoplayer/external/react-native-theoplayer-ui
url = https://github.com/THEOplayer/react-native-theoplayer-ui.git
branch = main
diff --git a/.mdxlintignore b/.mdxlintignore
index 90a0ec4f2e4a..681fc0fb60db 100644
--- a/.mdxlintignore
+++ b/.mdxlintignore
@@ -16,7 +16,5 @@ theolive_versioned_docs/*/api/
# Submodules
theoplayer/external/
theoplayer_versioned_docs/*/external/
-open-video-ui/external/
-open-video-ui_versioned_docs/*/external/
# Not part of the site
.agents/
diff --git a/.prettierignore b/.prettierignore
index b5bf95db929a..1e2e6c8a18ba 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -28,5 +28,3 @@ theolive_versioned_docs/*/api/
# Submodules
theoplayer/external/
theoplayer_versioned_docs/*/external/
-open-video-ui/external/
-open-video-ui_versioned_docs/*/external/
diff --git a/ads_versioned_docs/version-v1/getting-started/android.mdx b/ads_versioned_docs/version-v1/getting-started/android.mdx
index 70f1e21cf42c..c1cf2ab90ad5 100644
--- a/ads_versioned_docs/version-v1/getting-started/android.mdx
+++ b/ads_versioned_docs/version-v1/getting-started/android.mdx
@@ -92,7 +92,7 @@ theoPlayerView.player.source = SourceDescription.Builder(
## Integrating with Open Video UI
-When using the [Open Video UI for Android](/open-video-ui/android/), you need to create and add the `TheoAdsIntegration` before creating your `DefaultUI` or `UIController`. You can then create an OptiView Ads-enabled source and set it as `player.source`:
+When using the [Open Video UI for Android](/theoplayer/ui/android/open-video-ui/), you need to create and add the `TheoAdsIntegration` before creating your `DefaultUI` or `UIController`. You can then create an OptiView Ads-enabled source and set it as `player.source`:
```kotlin
import androidx.activity.compose.setContent
diff --git a/ads_versioned_docs/version-v1/getting-started/web.mdx b/ads_versioned_docs/version-v1/getting-started/web.mdx
index ec585bfb2553..5d1b97e3e27c 100644
--- a/ads_versioned_docs/version-v1/getting-started/web.mdx
+++ b/ads_versioned_docs/version-v1/getting-started/web.mdx
@@ -72,7 +72,7 @@ player.source = {
## Integrating with Open Video UI
-OptiView Ads works seamlessly together with [Open Video UI for Web](/open-video-ui/web/). You can pass your OptiView Ads-enabled source directly to the UI's `source` property:
+OptiView Ads works seamlessly together with [Open Video UI for Web](/theoplayer/ui/web/open-video-ui/). You can pass your OptiView Ads-enabled source directly to the UI's `source` property:
```html
diff --git a/docusaurus.config.ts b/docusaurus.config.ts
index 2dd50d14d115..ddac4d67e463 100644
--- a/docusaurus.config.ts
+++ b/docusaurus.config.ts
@@ -9,7 +9,6 @@ import type * as ClientRedirectsPlugin from '@docusaurus/plugin-client-redirects
import type * as OpenApiPlugin from 'docusaurus-plugin-openapi-docs/src/types';
import type { Props as PlatformSidebarNavbarItemProps } from './src/theme/NavbarItem/PlatformSidebarNavbarItem';
import type { Configuration as WebpackConfiguration } from 'webpack';
-import { version as webUiVersion } from './open-video-ui/external/web-ui/package.json';
import sidebarItemsGenerator from './src/plugin/sidebarItemsGenerator';
import remarkLinkRewrite from './src/plugin/remarkLinkRewrite';
import openApiLinkRewrite from './src/plugin/openApiLinkRewrite';
@@ -265,23 +264,6 @@ const config: Config = {
},
} satisfies OpenApiPlugin.PluginOptions,
],
- [
- '@docusaurus/plugin-content-docs',
- {
- ...docsConfigBase,
- id: 'open-video-ui',
- path: 'open-video-ui',
- routeBasePath: '/open-video-ui',
- sidebarPath: './sidebarsOpenVideoUI.ts',
- lastVersion: 'current',
- versions: {
- current: {
- label: webUiVersion,
- },
- },
- sidebarItemsGenerator,
- } satisfies DocsPlugin.Options,
- ],
[
'@docusaurus/plugin-content-docs',
{
@@ -435,7 +417,31 @@ const config: Config = {
{
redirects: [...redirectsMillicast, ...redirectsAds, ...redirectsTHEOPlayer],
createRedirects(existingPath) {
- if (existingPath.startsWith('/theoplayer/how-to-guides/web/uplynk/')) {
+ const uiPathMatch = existingPath.match(/^\/theoplayer\/ui\/(web|android|ios|react-native|roku)(\/.*)?$/);
+ if (uiPathMatch) {
+ const [, platform, suffix = ''] = uiPathMatch;
+ const oldPrefix = `/theoplayer/how-to-guides/${platform}/ui`;
+ const oldPaths = [`${oldPrefix}${suffix}`];
+ if (suffix === '' || suffix === '/' || ['/open-video-ui/', '/open-video-ui/react/', '/chromeless/', '/default-ui/'].includes(suffix)) {
+ oldPaths.push(`${oldPrefix}${suffix}${suffix.endsWith('/') ? '' : '/'}introduction/`);
+ }
+ if (platform === 'web' && suffix.startsWith('/open-video-ui/react/') && suffix !== '/open-video-ui/react/') {
+ oldPaths.push(suffix);
+ } else if (
+ platform === 'web' &&
+ suffix.startsWith('/open-video-ui/') &&
+ !suffix.startsWith('/open-video-ui/react/') &&
+ suffix !== '/open-video-ui/' &&
+ suffix !== '/open-video-ui/getting-started/'
+ ) {
+ oldPaths.push(suffix.replace('/open-video-ui/', '/open-video-ui/web/'));
+ } else if (platform === 'android' && suffix.startsWith('/open-video-ui/') && suffix !== '/open-video-ui/') {
+ oldPaths.push(suffix.replace('/open-video-ui/', '/open-video-ui/android/'));
+ } else if (platform === 'react-native' && suffix.startsWith('/open-video-ui/') && suffix !== '/open-video-ui/') {
+ oldPaths.push(suffix.replace('/open-video-ui/', '/open-video-ui/react-native/'));
+ }
+ return oldPaths;
+ } else if (existingPath.startsWith('/theoplayer/how-to-guides/web/uplynk/')) {
return [existingPath.replace('/theoplayer/how-to-guides/web/uplynk/', '/theoplayer/how-to-guides/miscellaneous/verizon-media/')];
} else if (existingPath.startsWith('/theolive/v1/api/')) {
return [existingPath.replace('/theolive/v1/api/', '/theolive/api/')];
@@ -454,7 +460,7 @@ const config: Config = {
// Generates /llms.txt, /llms-full.txt, //llms.txt, //llms-full.txt and a .md twin of every page
llmsTxt: {
siteTitle: 'Dolby OptiView Documentation',
- siteDescription: 'Developer documentation for Dolby OptiView Player, Open Video UI, Live, Real-time, Ads and Ad Engine.',
+ siteDescription: 'Developer documentation for Dolby OptiView Player, Live, Real-time, Ads and Ad Engine.',
content: {
enableMarkdownFiles: true,
relativePaths: false,
@@ -478,7 +484,7 @@ const config: Config = {
slug: 'theoplayer',
title: 'Dolby OptiView Player',
description:
- 'Dolby OptiView Player (formerly THEOplayer) enables you to deploy cutting-edge video playback experiences, efficiently and on any device, including on web, mobile, smart TVs, set-top-boxes and gaming consoles.',
+ "Dolby OptiView Player (formerly THEOplayer) enables you to deploy cutting-edge video playback experiences on any device. Use the basic default UI, customize your player with Open Video UI's ready-made components, or build a complete UI from scratch with the chromeless player.",
platformSidebars: {
web: 'Web SDK',
android: 'Android SDK',
@@ -489,18 +495,6 @@ const config: Config = {
roku: 'Roku SDK',
},
},
- {
- slug: 'open-video-ui',
- title: 'Open Video UI',
- description:
- 'The Open Video UI provides component libraries for building a world-class video player experience powered by the OptiView Player SDK, with dedicated libraries for web, Android and React Native.',
- platformSidebars: {
- web: 'Web',
- android: 'Android',
- react: 'React',
- 'react-native': 'React Native',
- },
- },
{
slug: 'theolive',
title: 'Dolby OptiView Live',
@@ -529,12 +523,15 @@ const config: Config = {
} satisfies LlmsTxtOptions,
],
[
- (_context, options: { webpack: (isServer: boolean) => WebpackConfiguration }) => ({
- name: 'webpack-plugin',
- configureWebpack(_config, isServer) {
- return options.webpack(isServer);
- },
- }),
+ (_context: unknown, pluginOptions: unknown) => {
+ const options = pluginOptions as { webpack: (isServer: boolean) => WebpackConfiguration };
+ return {
+ name: 'webpack-plugin',
+ configureWebpack(_config: WebpackConfiguration, isServer: boolean) {
+ return options.webpack(isServer);
+ },
+ };
+ },
{
webpack: (isServer: boolean): WebpackConfiguration => ({
optimization: {
@@ -559,6 +556,17 @@ const config: Config = {
const parsedDocPath = parseDocPath(params.filePath)!;
const { docPluginId } = parsedDocPath;
let { docPath } = parsedDocPath;
+ const uiDocMatch = docPath.match(/^how-to-guides\/(web|android|ios|react-native|roku)\/ui\/(.+)\.mdx?$/);
+ if (docPluginId === 'theoplayer' && uiDocMatch) {
+ const [, platform, path] = uiDocMatch;
+ const uiPath = path === 'introduction' ? '' : path.replace(/\/introduction$/, '');
+ frontMatter.slug = `/ui/${platform}/${uiPath}`;
+ }
+ if (docPath.startsWith('external/web-ui/') && typeof frontMatter.slug === 'string') {
+ frontMatter.slug = frontMatter.slug
+ .replace(/^\/web(?=\/|$)/, '/ui/web/open-video-ui')
+ .replace(/^\/react(?=\/|$)/, '/ui/web/open-video-ui/react');
+ }
if (!frontMatter.slug && docPath.startsWith('external/')) {
// Add a slug to all external doc pages
frontMatter.slug = docPath
@@ -566,19 +574,20 @@ const config: Config = {
.replace('external/', '')
.replace(/\.mdx?$/, '')
// Map external projects to desired URLs
- .replace('web-ui/docs/', '/web/')
- .replace('android-ui/docs/', '/android/')
- .replace('web-ui/CHANGELOG', '/web/changelog')
- .replace('web-ui/react/CHANGELOG', '/react/changelog')
- .replace('android-ui/CHANGELOG', '/android/changelog')
+ .replace('web-ui/docs/react/', '/ui/web/open-video-ui/react/')
+ .replace('web-ui/docs/', '/ui/web/open-video-ui/')
+ .replace('android-ui/docs/', '/ui/android/open-video-ui/')
+ .replace('web-ui/react/CHANGELOG', '/ui/web/open-video-ui/react/changelog')
+ .replace('web-ui/CHANGELOG', '/ui/web/open-video-ui/changelog')
+ .replace('android-ui/CHANGELOG', '/ui/android/open-video-ui/changelog')
.replace('react-native-theoplayer/CHANGELOG', '/changelog/react-native')
.replace('react-native-theoplayer/doc/', '/getting-started/frameworks/react-native/')
.replace('flutter-theoplayer-sdk/flutter_theoplayer_sdk/flutter_theoplayer_sdk/', 'flutter-theoplayer-sdk/flutter_theoplayer_sdk/')
.replace('flutter-theoplayer-sdk/flutter_theoplayer_sdk/CHANGELOG', '/flutter/changelog')
.replace('flutter-theoplayer-sdk/flutter_theoplayer_sdk/README', '/getting-started/frameworks/flutter/getting-started')
.replace('flutter-theoplayer-sdk/doc/', '/flutter/guides/')
- .replace('react-native-theoplayer-ui/CHANGELOG', '/react-native/changelog')
- .replace('react-native-theoplayer-ui/doc/', '/react-native/')
+ .replace('react-native-theoplayer-ui/CHANGELOG', '/ui/react-native/open-video-ui/changelog')
+ .replace('react-native-theoplayer-ui/doc/', '/ui/react-native/open-video-ui/')
.replace(/react-native-connectors\/([^/]+)\/CHANGELOG/, '/connectors/react-native/$1/changelog')
.replace(/react-native-connectors\/([^/]+)\/README/, '/connectors/react-native/$1/getting-started')
.replace(/react-native-connectors\/([^/]+)\/doc\//, '/connectors/react-native/$1/')
@@ -599,7 +608,7 @@ const config: Config = {
// Fix changelog titles
frontMatter.title ??= 'Changelog';
if (!frontMatter.description) {
- if (docPluginId === 'open-video-ui') {
+ if (docPath.includes('web-ui/') || docPath.includes('android-ui/') || docPath.includes('react-native-theoplayer-ui/')) {
frontMatter.description = "Find out what's new in Open Video UI.";
} else if (docPluginId === 'theoplayer' && !docPath.includes('connector')) {
frontMatter.description = "Find out what's new in the OptiView Player.";
@@ -617,7 +626,7 @@ const config: Config = {
} else if (docPath.endsWith('readme.md')) {
frontMatter.title ??= 'Getting started';
if (!frontMatter.description) {
- if (docPluginId === 'open-video-ui') {
+ if (docPath.includes('web-ui/') || docPath.includes('android-ui/') || docPath.includes('react-native-theoplayer-ui/')) {
frontMatter.description = 'Start building your UI in just a few minutes!';
} else if (docPath.includes('connector')) {
frontMatter.description = 'Set up your connector in just a few minutes!';
@@ -631,7 +640,7 @@ const config: Config = {
},
},
- staticDirectories: ['static', 'theoplayer/static', 'ads/static', 'adengine/static', 'open-video-ui/external/web-ui/docs/static'],
+ staticDirectories: ['static', 'theoplayer/static', 'ads/static', 'adengine/static', 'theoplayer/external/web-ui/docs/static'],
themeConfig: {
// TODO OpenGraph image for OptiView?
@@ -657,27 +666,13 @@ const config: Config = {
},
items: [
{
- type: 'dropdown',
+ type: 'custom-platformSidebar',
+ docsPluginId: 'theoplayer',
label: 'Player',
href: '/theoplayer',
+ activeBasePath: '/theoplayer',
position: 'left',
- items: [
- {
- type: 'custom-platformSidebar',
- docsPluginId: 'theoplayer',
- label: 'OptiView Player',
- href: '/theoplayer',
- activeBasePath: '/theoplayer',
- } satisfies PlatformSidebarNavbarItemProps,
- {
- type: 'custom-platformSidebar',
- docsPluginId: 'open-video-ui',
- label: 'Open Video UI',
- href: '/open-video-ui',
- activeBasePath: '/open-video-ui',
- } satisfies PlatformSidebarNavbarItemProps,
- ],
- },
+ } satisfies PlatformSidebarNavbarItemProps,
{
type: 'dropdown',
label: 'Ads',
@@ -762,6 +757,9 @@ const config: Config = {
apiKey: '415e178afdd1c3ea819b42fb9a6a1c99',
indices: [{ name: 'theoplayer' }],
contextualSearch: true,
+ searchPage: {
+ path: 'search',
+ },
replaceSearchResultPathname: {
from: '/docs/',
to: process.env.DOCUSAURUS_BASE_URL || '/docs/',
@@ -818,7 +816,11 @@ function isMarkdownUrl(href: string): boolean {
}
function externalDocUrl(docPath: string): string {
- const [, projectName, externalDocPath] = docPath.match(/\bexternal\/([^/]+)\/(.+)$/);
+ const match = docPath.match(/\bexternal\/([^/]+)\/(.+)$/);
+ if (!match) {
+ throw new Error(`Invalid external documentation path: ${docPath}`);
+ }
+ const [, projectName, externalDocPath] = match;
return `https://github.com/THEOplayer/${projectName}/blob/-/${externalDocPath}`;
}
diff --git a/open-video-ui/android/index.mdx b/open-video-ui/android/index.mdx
deleted file mode 100644
index b23b83e87a03..000000000000
--- a/open-video-ui/android/index.mdx
+++ /dev/null
@@ -1,14 +0,0 @@
----
-sidebar_label: Introduction
----
-
-# Open Video UI for Android
-
-import Intro from '../shared/_intro.mdx';
-import RebrandingNotice from '../callouts/_rebranding_notice.md';
-import SidebarDocCardList from '@site/src/components/SidebarDocCardList';
-
-
-
-
-
diff --git a/open-video-ui/callouts/_rebranding_notice.md b/open-video-ui/callouts/_rebranding_notice.md
deleted file mode 100644
index a4e4fadf7e9f..000000000000
--- a/open-video-ui/callouts/_rebranding_notice.md
+++ /dev/null
@@ -1,5 +0,0 @@
-:::info[OptiView Rebranding]
-
-OptiView Player is the new name for THEOplayer as part of the OptiView product suite. During the transition, you may still see references to THEOplayer. OptiView Player and THEOplayer refer to the same product.
-
-:::
diff --git a/open-video-ui/index.mdx b/open-video-ui/index.mdx
deleted file mode 100644
index 1baca13cde9e..000000000000
--- a/open-video-ui/index.mdx
+++ /dev/null
@@ -1,25 +0,0 @@
----
-displayed_sidebar: web
-sidebar_label: Introduction
----
-
-# Open Video UI
-
-import Intro from './shared/_intro.mdx';
-import RebrandingNotice from './callouts/_rebranding_notice.md';
-import DocCardList from '@theme/DocCardList';
-import useBaseUrl from '@docusaurus/useBaseUrl';
-import { getPlatforms } from '@site/src/util/platform';
-
-
-
-
- ({
- type: 'link',
- label: desc.label,
- description: desc.description,
- customProps: { icon: desc.icon },
- href: useBaseUrl(`open-video-ui/${desc.platform}`),
- }))}
-/>
diff --git a/open-video-ui/react-native/index.mdx b/open-video-ui/react-native/index.mdx
deleted file mode 100644
index 21ac4b2462b0..000000000000
--- a/open-video-ui/react-native/index.mdx
+++ /dev/null
@@ -1,14 +0,0 @@
----
-sidebar_label: Introduction
----
-
-# Open Video UI for React Native
-
-import Intro from '../shared/_intro.mdx';
-import RebrandingNotice from '../callouts/_rebranding_notice.md';
-import SidebarDocCardList from '@site/src/components/SidebarDocCardList';
-
-
-
-
-
diff --git a/open-video-ui/react/index.mdx b/open-video-ui/react/index.mdx
deleted file mode 100644
index 63e7d58e182f..000000000000
--- a/open-video-ui/react/index.mdx
+++ /dev/null
@@ -1,14 +0,0 @@
----
-sidebar_label: Introduction
----
-
-# Open Video UI for React
-
-import Intro from '../shared/_intro.mdx';
-import RebrandingNotice from '../callouts/_rebranding_notice.md';
-import SidebarDocCardList from '@site/src/components/SidebarDocCardList';
-
-
-
-
-
diff --git a/open-video-ui/shared/_intro.mdx b/open-video-ui/shared/_intro.mdx
deleted file mode 100644
index 1943e666ab19..000000000000
--- a/open-video-ui/shared/_intro.mdx
+++ /dev/null
@@ -1,6 +0,0 @@
-The Open Video UI provides component libraries for building a world-class video player experience powered by the OptiView Player SDK.
-
-- Use the default UI for a great out-of-the-box experience, or use the individual components to build your own custom UI.
-- Dedicated libraries for each platform, so your UI always feels native in your app.
-
-On these pages, you'll learn how to get started with the Open Video UI and make your very own UI.
diff --git a/open-video-ui/web/index.mdx b/open-video-ui/web/index.mdx
deleted file mode 100644
index f5b91fb1394f..000000000000
--- a/open-video-ui/web/index.mdx
+++ /dev/null
@@ -1,14 +0,0 @@
----
-sidebar_label: Introduction
----
-
-# Open Video UI for Web
-
-import Intro from '../shared/_intro.mdx';
-import RebrandingNotice from '../callouts/_rebranding_notice.md';
-import SidebarDocCardList from '@site/src/components/SidebarDocCardList';
-
-
-
-
-
diff --git a/redirectsTHEOPlayer.json b/redirectsTHEOPlayer.json
index ce06b82318fc..9c437b598c79 100644
--- a/redirectsTHEOPlayer.json
+++ b/redirectsTHEOPlayer.json
@@ -1,11 +1,35 @@
[
+ {
+ "from": "/open-video-ui",
+ "to": "/theoplayer/ui/web/open-video-ui/"
+ },
+ {
+ "from": "/open-video-ui/web",
+ "to": "/theoplayer/ui/web/open-video-ui/"
+ },
+ {
+ "from": "/open-video-ui/web/getting-started",
+ "to": "/theoplayer/ui/web/open-video-ui/getting-started/"
+ },
+ {
+ "from": "/open-video-ui/android",
+ "to": "/theoplayer/ui/android/open-video-ui/"
+ },
+ {
+ "from": "/open-video-ui/react",
+ "to": "/theoplayer/ui/web/open-video-ui/react/"
+ },
+ {
+ "from": "/open-video-ui/react-native",
+ "to": "/theoplayer/ui/react-native/open-video-ui/"
+ },
{
"from": "/theoplayer/getting-started/sdks/web/getting-started-extended",
"to": "/theoplayer/getting-started/sdks/web/getting-started/"
},
{
"from": "/theoplayer/getting-started/sdks/web/getting-started-with-the-open-source-web-ui",
- "to": "/open-video-ui/web/getting-started"
+ "to": "/theoplayer/ui/web/open-video-ui/getting-started/"
},
{
"from": "/theoplayer/getting-started/sdks/web/how-to-use-vr-using-webxr/",
@@ -381,71 +405,71 @@
},
{
"from": "/theoplayer/how-to-guides/ui/",
- "to": "/theoplayer/how-to-guides/web/ui/introduction/"
+ "to": "/theoplayer/ui/web/"
},
{
"from": "/theoplayer/how-to-guides/ui/introduction/",
- "to": "/theoplayer/how-to-guides/web/ui/introduction/"
+ "to": "/theoplayer/ui/web/"
},
{
"from": "/theoplayer/how-to-guides/ui/is-it-possible-to-remove-an-element/",
- "to": "/theoplayer/how-to-guides/web/ui/remove-ui-element/"
+ "to": "/theoplayer/ui/web/remove-ui-element/"
},
{
"from": "/theoplayer/how-to-guides/ui/how-to-align-timeline-in-the-middle/",
- "to": "/theoplayer/how-to-guides/web/ui/align-timeline/"
+ "to": "/theoplayer/ui/web/align-timeline/"
},
{
"from": "/theoplayer/how-to-guides/ui/how-to-change-big-play-button/",
- "to": "/theoplayer/how-to-guides/web/ui/change-big-play-button/"
+ "to": "/theoplayer/ui/web/change-big-play-button/"
},
{
"from": "/theoplayer/how-to-guides/ui/how-to-make-control-keys-always-visible/",
- "to": "/theoplayer/how-to-guides/web/ui/keep-control-bar-visible/"
+ "to": "/theoplayer/ui/web/keep-control-bar-visible/"
},
{
"from": "/theoplayer/how-to-guides/ui/is-it-possible-to-hide-googla-ima/",
- "to": "/theoplayer/how-to-guides/web/ui/hide-google-ima-ui/"
+ "to": "/theoplayer/ui/web/hide-google-ima-ui/"
},
{
"from": "/theoplayer/how-to-guides/ui/how-to-build-chromeless-ui/",
- "to": "/theoplayer/how-to-guides/web/ui/build-chromeless-ui/"
+ "to": "/theoplayer/ui/web/build-chromeless-ui/"
},
{
"from": "/theoplayer/how-to-guides/ui/how-to-insert-a-button/",
- "to": "/theoplayer/how-to-guides/web/ui/insert-a-button/"
+ "to": "/theoplayer/ui/web/insert-a-button/"
},
{
"from": "/theoplayer/how-to-guides/ui/how-to-change-default-UI-language-to-other/",
- "to": "/theoplayer/how-to-guides/web/ui/change-ui-language/"
+ "to": "/theoplayer/ui/web/change-ui-language/"
},
{
"from": "/theoplayer/how-to-guides/ui/customize-ui-during-playback/",
- "to": "/theoplayer/how-to-guides/web/ui/customize-ui-during-ad-playback/"
+ "to": "/theoplayer/ui/web/customize-ui-during-ad-playback/"
},
{
"from": "/theoplayer/how-to-guides/ui/how-to-change-how-a-video-should-fit-inside-a-container/",
- "to": "/theoplayer/how-to-guides/web/ui/change-video-fit/"
+ "to": "/theoplayer/ui/web/change-video-fit/"
},
{
"from": "/theoplayer/how-to-guides/ui/how-to-make-audio-only-player/",
- "to": "/theoplayer/how-to-guides/web/ui/audio-only-player/"
+ "to": "/theoplayer/ui/web/audio-only-player/"
},
{
"from": "/theoplayer/how-to-guides/ui/customising-vertical-volume-slider/",
- "to": "/theoplayer/how-to-guides/web/ui/vertical-volume-slider/"
+ "to": "/theoplayer/ui/web/vertical-volume-slider/"
},
{
"from": "/theoplayer/how-to-guides/ui/ui-skinning/",
- "to": "/theoplayer/how-to-guides/web/ui/ui-skinning/"
+ "to": "/theoplayer/ui/web/ui-skinning/"
},
{
"from": "/theoplayer/how-to-guides/ui/how-to-detect-visibility-default-control-bar/",
- "to": "/theoplayer/how-to-guides/web/ui/detect-control-bar-visibility/"
+ "to": "/theoplayer/ui/web/detect-control-bar-visibility/"
},
{
"from": "/theoplayer/how-to-guides/ui/how-to-disable-click-to-pause/",
- "to": "/theoplayer/how-to-guides/web/ui/disable-click-to-pause/"
+ "to": "/theoplayer/ui/web/disable-click-to-pause/"
},
{
"from": "/theoplayer/how-to-guides/miscellaneous/",
diff --git a/sidebarsOpenVideoUI.ts b/sidebarsOpenVideoUI.ts
deleted file mode 100644
index dbdd5f19ebb4..000000000000
--- a/sidebarsOpenVideoUI.ts
+++ /dev/null
@@ -1,148 +0,0 @@
-import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
-
-const sidebars: SidebarsConfig = {
- web: [
- 'web/index',
- { type: 'doc', id: 'external/web-ui/docs/getting-started' },
- {
- type: 'category',
- label: 'How-to guides',
- description: 'Learn how to integrate our rich set of features into your own UI.',
- customProps: {
- icon: '📖',
- },
- link: { type: 'generated-index', slug: 'web/guides' },
- items: [{ type: 'autogenerated', dirName: 'external/web-ui/docs/guides' }],
- },
- {
- type: 'category',
- label: 'Examples',
- description: 'Find inspiration for your UI from our live demos!',
- customProps: {
- icon: '🛝',
- },
- link: { type: 'generated-index', slug: 'web/examples' },
- items: [{ type: 'autogenerated', dirName: 'external/web-ui/docs/examples' }],
- },
- { type: 'doc', id: 'external/web-ui/CHANGELOG' },
- {
- type: 'link',
- label: 'API reference',
- description: 'Discover all components provided by Open Video UI for Web.',
- customProps: {
- icon: '*️⃣',
- },
- href: 'https://theoplayer.github.io/web-ui/api/',
- },
- {
- type: 'link',
- label: 'GitHub',
- description: 'Browse the source code or report issues on GitHub.',
- customProps: {
- icon: 'github',
- },
- href: 'https://github.com/THEOplayer/web-ui/',
- },
- ],
- android: [
- 'android/index',
- { type: 'doc', id: 'android/getting-started' },
- {
- type: 'category',
- label: 'How-to guides',
- description: 'Learn how to integrate our rich set of features into your own UI.',
- customProps: {
- icon: '📖',
- },
- link: { type: 'generated-index', slug: 'android/guides' },
- items: [{ type: 'autogenerated', dirName: 'external/android-ui/docs/guides' }],
- },
- { type: 'doc', id: 'external/android-ui/CHANGELOG' },
- {
- type: 'link',
- label: 'API reference',
- description: 'Discover all components provided by Open Video UI for Android.',
- customProps: {
- icon: '*️⃣',
- },
- href: 'https://theoplayer.github.io/android-ui/api/',
- },
- {
- type: 'link',
- label: 'GitHub',
- description: 'Browse the source code or report issues on GitHub.',
- customProps: {
- icon: 'github',
- },
- href: 'https://github.com/THEOplayer/android-ui/',
- },
- ],
- react: [
- 'react/index',
- { type: 'doc', id: 'external/web-ui/docs/react/getting-started' },
- {
- type: 'category',
- label: 'How-to guides',
- description: 'Learn how to integrate our rich set of features into your own UI.',
- customProps: {
- icon: '📖',
- },
- link: { type: 'generated-index', slug: 'react/guides' },
- items: [{ type: 'autogenerated', dirName: 'external/web-ui/docs/react/guides' }],
- },
- {
- type: 'category',
- label: 'Examples',
- description: 'Find inspiration for your UI from our live demos!',
- customProps: {
- icon: '🛝',
- },
- link: { type: 'generated-index', slug: 'react/examples' },
- items: [{ type: 'autogenerated', dirName: 'external/web-ui/docs/react/examples' }],
- },
- { type: 'doc', id: 'external/web-ui/react/CHANGELOG' },
- {
- type: 'link',
- label: 'API reference',
- description: 'Discover all components and hooks provided by Open Video UI for React.',
- customProps: {
- icon: '*️⃣',
- },
- href: 'https://theoplayer.github.io/web-ui/react-api/',
- },
- {
- type: 'link',
- label: 'GitHub',
- description: 'Browse the source code or report issues on GitHub.',
- customProps: {
- icon: 'github',
- },
- href: 'https://github.com/THEOplayer/web-ui/tree/main/react/',
- },
- ],
- 'react-native': [
- 'react-native/index',
- { type: 'autogenerated', dirName: 'external/react-native-theoplayer-ui/doc' },
- { type: 'doc', id: 'external/react-native-theoplayer-ui/CHANGELOG' },
- {
- type: 'link',
- label: 'API reference',
- description: 'Discover all components and functions provided by the React Native UI.',
- customProps: {
- icon: '*️⃣',
- },
- href: 'https://theoplayer.github.io/react-native-theoplayer-ui/api/',
- },
- {
- type: 'link',
- label: 'GitHub',
- description: 'Browse the source code or report issues on GitHub.',
- customProps: {
- icon: 'github',
- },
- href: 'https://github.com/THEOplayer/react-native-theoplayer-ui/',
- },
- ],
-};
-
-export default sidebars;
diff --git a/sidebarsTheoplayer.ts b/sidebarsTheoplayer.ts
index 4a21081d2f19..73e582d19569 100644
--- a/sidebarsTheoplayer.ts
+++ b/sidebarsTheoplayer.ts
@@ -49,9 +49,13 @@ const sidebars: SidebarsConfig = {
{
type: 'autogenerated',
dirName: 'how-to-guides/web',
+ customProps: {
+ exclude: ['UI'],
+ },
},
],
}),
+ webUiCategory(),
examplesCategory({
link: { type: 'doc', id: 'examples/index' },
items: [{ type: 'autogenerated', dirName: 'examples' }],
@@ -87,9 +91,13 @@ const sidebars: SidebarsConfig = {
{
type: 'autogenerated',
dirName: 'how-to-guides/android',
+ customProps: {
+ exclude: ['UI'],
+ },
},
],
}),
+ androidUiCategory(),
connectorsCategory({
link: { type: 'doc', id: 'connectors/android/index' },
items: androidConnectorItems(),
@@ -121,9 +129,13 @@ const sidebars: SidebarsConfig = {
{
type: 'autogenerated',
dirName: 'how-to-guides/ios',
+ customProps: {
+ exclude: ['UI'],
+ },
},
],
}),
+ iosUiCategory(),
connectorsCategory({
link: { type: 'doc', id: 'connectors/ios/index' },
items: iosConnectorItems(),
@@ -155,9 +167,13 @@ const sidebars: SidebarsConfig = {
{
type: 'autogenerated',
dirName: 'how-to-guides/react-native',
+ customProps: {
+ exclude: ['ui'],
+ },
},
],
}),
+ reactNativeUiCategory(),
connectorsCategory({
link: { type: 'doc', id: 'connectors/react-native/index' },
items: reactNativeConnectorItems(),
@@ -235,9 +251,13 @@ const sidebars: SidebarsConfig = {
{
type: 'autogenerated',
dirName: 'how-to-guides/roku',
+ customProps: {
+ exclude: ['UI'],
+ },
},
],
}),
+ rokuUiCategory(),
connectorsCategory({
link: { type: 'doc', id: 'connectors/roku/index' },
items: [
@@ -388,6 +408,337 @@ function howToGuidesCategory(config: PartialSidebarItemCategoryConfig): SidebarI
);
}
+function webUiCategory(): SidebarItemCategoryConfig {
+ return {
+ type: 'category',
+ label: 'UI',
+ description: 'Choose a ready-made UI, customize with Open Video UI, or build from scratch.',
+ customProps: {
+ icon: '🎨',
+ },
+ link: { type: 'doc', id: 'how-to-guides/web/ui/introduction' },
+ items: [
+ {
+ type: 'category',
+ label: 'Open Video UI',
+ description: 'Customize the player with ready-made, open-source components.',
+ items: [
+ 'how-to-guides/web/ui/open-video-ui/introduction',
+ { type: 'doc', id: 'external/web-ui/docs/getting-started' },
+ howToGuidesCategory({
+ description: 'Learn how to integrate our rich set of features into your own UI.',
+ link: { type: 'generated-index', slug: 'ui/web/open-video-ui/guides' },
+ items: [{ type: 'autogenerated', dirName: 'external/web-ui/docs/guides' }],
+ }),
+ examplesCategory({
+ description: 'Find inspiration for your UI from our live demos!',
+ link: { type: 'generated-index', slug: 'ui/web/open-video-ui/examples' },
+ items: [
+ {
+ type: 'category',
+ label: 'Prebuilt Open Video UI',
+ description: 'Examples using the preassembled Open Video UI component layout.',
+ items: [{ type: 'autogenerated', dirName: 'external/web-ui/docs/examples/default-ui' }],
+ },
+ {
+ type: 'category',
+ label: 'Composed Open Video UI',
+ description: 'Examples composing individual Open Video UI components into custom layouts.',
+ items: [{ type: 'autogenerated', dirName: 'external/web-ui/docs/examples/custom-ui' }],
+ },
+ ],
+ }),
+ {
+ type: 'category',
+ label: 'React',
+ items: [
+ 'how-to-guides/web/ui/open-video-ui/react/introduction',
+ { type: 'doc', id: 'external/web-ui/docs/react/getting-started' },
+ howToGuidesCategory({
+ description: 'Learn how to integrate our rich set of features into your own UI.',
+ link: { type: 'generated-index', slug: 'ui/web/open-video-ui/react/guides' },
+ items: [{ type: 'autogenerated', dirName: 'external/web-ui/docs/react/guides' }],
+ }),
+ examplesCategory({
+ description: 'Find inspiration for your UI from our live demos!',
+ link: { type: 'generated-index', slug: 'ui/web/open-video-ui/react/examples' },
+ items: [
+ {
+ type: 'category',
+ label: 'Prebuilt Open Video UI',
+ items: [{ type: 'autogenerated', dirName: 'external/web-ui/docs/react/examples/default-ui' }],
+ },
+ {
+ type: 'category',
+ label: 'Composed Open Video UI',
+ items: [{ type: 'autogenerated', dirName: 'external/web-ui/docs/react/examples/custom-ui' }],
+ },
+ ],
+ }),
+ { type: 'doc', id: 'external/web-ui/react/CHANGELOG' },
+ apiReferencesLink({
+ label: 'API reference',
+ description: 'Discover all components and hooks provided by Open Video UI for React.',
+ href: 'https://theoplayer.github.io/web-ui/react-api/',
+ }),
+ githubLink({
+ href: 'https://github.com/THEOplayer/web-ui/tree/main/react/',
+ }),
+ ],
+ },
+ { type: 'doc', id: 'external/web-ui/CHANGELOG' },
+ apiReferencesLink({
+ label: 'API reference',
+ description: 'Discover all components provided by Open Video UI for Web.',
+ href: 'https://theoplayer.github.io/web-ui/api/',
+ }),
+ githubLink({
+ href: 'https://github.com/THEOplayer/web-ui/',
+ }),
+ ],
+ },
+ {
+ type: 'category',
+ label: 'Chromeless',
+ description: 'Start without a UI and build every control from scratch.',
+ items: [
+ 'how-to-guides/web/ui/chromeless/introduction',
+ { type: 'doc', id: 'how-to-guides/web/ui/build-chromeless-ui', label: 'Getting started' },
+ {
+ type: 'category',
+ label: 'How-to guides',
+ items: [
+ 'how-to-guides/web/ui/chromeless/mapping-components',
+ 'how-to-guides/web/ui/chromeless/ux-enhancements',
+ 'how-to-guides/web/ui/chromeless/error-handling',
+ ],
+ },
+ {
+ type: 'category',
+ label: 'Examples',
+ items: ['how-to-guides/web/ui/chromeless/sample-code'],
+ },
+ ],
+ },
+ {
+ type: 'category',
+ label: 'Default UI',
+ description: 'Use and adapt the basic UI included with the Web SDK.',
+ items: [
+ 'how-to-guides/web/ui/default-ui/introduction',
+ 'how-to-guides/web/ui/default-ui/getting-started',
+ {
+ type: 'category',
+ label: 'How-to guides',
+ items: [
+ 'how-to-guides/web/ui/remove-ui-element',
+ 'how-to-guides/web/ui/align-timeline',
+ 'how-to-guides/web/ui/change-big-play-button',
+ 'how-to-guides/web/ui/keep-control-bar-visible',
+ 'how-to-guides/web/ui/detect-control-bar-visibility',
+ 'how-to-guides/web/ui/hide-google-ima-ui',
+ 'how-to-guides/web/ui/insert-a-button',
+ 'how-to-guides/web/ui/change-ui-language',
+ 'how-to-guides/web/ui/customize-ui-during-ad-playback',
+ 'how-to-guides/web/ui/change-video-fit',
+ 'how-to-guides/web/ui/audio-only-player',
+ 'how-to-guides/web/ui/vertical-volume-slider',
+ 'how-to-guides/web/ui/disable-click-to-pause',
+ 'how-to-guides/web/ui/ui-skinning',
+ ],
+ },
+ ],
+ },
+ ],
+ };
+}
+
+function androidUiCategory(): SidebarItemCategoryConfig {
+ return {
+ type: 'category',
+ label: 'UI',
+ description: 'Customize with Open Video UI or build from scratch.',
+ customProps: {
+ icon: '🎨',
+ },
+ link: { type: 'doc', id: 'how-to-guides/android/ui/introduction' },
+ items: [
+ {
+ type: 'category',
+ label: 'Open Video UI',
+ description: 'Customize the player with ready-made, open-source components.',
+ items: [
+ 'how-to-guides/android/ui/open-video-ui/introduction',
+ 'how-to-guides/android/ui/open-video-ui/getting-started',
+ howToGuidesCategory({
+ description: 'Learn how to integrate our rich set of features into your own UI.',
+ link: { type: 'generated-index', slug: 'ui/android/open-video-ui/guides' },
+ items: [{ type: 'autogenerated', dirName: 'external/android-ui/docs/guides' }],
+ }),
+ examplesCategory({
+ items: [
+ {
+ type: 'link',
+ label: 'Android example application',
+ href: 'https://github.com/THEOplayer/android-ui/tree/main/app',
+ },
+ ],
+ }),
+ { type: 'doc', id: 'external/android-ui/CHANGELOG' },
+ apiReferencesLink({
+ label: 'API reference',
+ description: 'Discover all components provided by Open Video UI for Android.',
+ href: 'https://theoplayer.github.io/android-ui/api/',
+ }),
+ githubLink({
+ href: 'https://github.com/THEOplayer/android-ui/',
+ }),
+ ],
+ },
+ {
+ type: 'category',
+ label: 'Chromeless',
+ description: 'Start without a UI and build every control from scratch.',
+ items: [
+ 'how-to-guides/android/ui/chromeless/introduction',
+ { type: 'doc', id: 'how-to-guides/android/ui/build-chromeless-ui', label: 'Getting started' },
+ {
+ type: 'category',
+ label: 'How-to guides',
+ items: [
+ 'how-to-guides/android/ui/chromeless/mapping-components',
+ 'how-to-guides/android/ui/change-video-fit',
+ 'how-to-guides/android/ui/chromeless/ux-enhancements',
+ 'how-to-guides/android/ui/chromeless/error-handling',
+ ],
+ },
+ ],
+ },
+ ],
+ };
+}
+
+function reactNativeUiCategory(): SidebarItemCategoryConfig {
+ return {
+ type: 'category',
+ label: 'UI',
+ description: 'Customize with Open Video UI or build from scratch.',
+ customProps: {
+ icon: '🎨',
+ },
+ link: { type: 'doc', id: 'how-to-guides/react-native/ui/introduction' },
+ items: [
+ {
+ type: 'category',
+ label: 'Open Video UI',
+ description: 'Customize the player with ready-made, open-source components.',
+ items: [
+ 'how-to-guides/react-native/ui/open-video-ui/introduction',
+ { type: 'doc', id: 'external/react-native-theoplayer-ui/doc/getting-started' },
+ howToGuidesCategory({
+ items: [
+ { type: 'doc', id: 'external/react-native-theoplayer-ui/doc/localization' },
+ { type: 'doc', id: 'external/react-native-theoplayer-ui/doc/limitations' },
+ ],
+ }),
+ examplesCategory({
+ items: [
+ {
+ type: 'link',
+ label: 'React Native example application',
+ href: 'https://github.com/THEOplayer/react-native-theoplayer-ui/tree/main/example',
+ },
+ ],
+ }),
+ { type: 'doc', id: 'external/react-native-theoplayer-ui/CHANGELOG' },
+ apiReferencesLink({
+ label: 'API reference',
+ description: 'Discover all components and functions provided by Open Video UI for React Native.',
+ href: 'https://theoplayer.github.io/react-native-theoplayer-ui/api/',
+ }),
+ githubLink({
+ href: 'https://github.com/THEOplayer/react-native-theoplayer-ui/',
+ }),
+ ],
+ },
+ {
+ type: 'category',
+ label: 'Chromeless',
+ description: 'Start without a UI and build every control from scratch.',
+ items: ['how-to-guides/react-native/ui/chromeless/introduction', 'how-to-guides/react-native/ui/chromeless/getting-started'],
+ },
+ ],
+ };
+}
+
+function iosUiCategory(): SidebarItemCategoryConfig {
+ return {
+ type: 'category',
+ label: 'UI',
+ description: 'Build a native interface from scratch.',
+ customProps: {
+ icon: '🎨',
+ },
+ link: { type: 'doc', id: 'how-to-guides/ios/ui/introduction' },
+ items: [
+ {
+ type: 'category',
+ label: 'Chromeless',
+ description: 'Start without a UI and build every control from scratch.',
+ items: [
+ 'how-to-guides/ios/ui/chromeless/introduction',
+ { type: 'doc', id: 'how-to-guides/ios/ui/build-chromeless-ui', label: 'Getting started' },
+ {
+ type: 'category',
+ label: 'How-to guides',
+ items: [
+ 'how-to-guides/ios/ui/chromeless/mapping-components',
+ 'how-to-guides/ios/ui/change-video-fit',
+ 'how-to-guides/ios/ui/chromeless/ux-enhancements',
+ 'how-to-guides/ios/ui/chromeless/error-handling',
+ ],
+ },
+ ],
+ },
+ ],
+ };
+}
+
+function rokuUiCategory(): SidebarItemCategoryConfig {
+ return {
+ type: 'category',
+ label: 'UI',
+ description: 'Use Roku native controls or build a SceneGraph interface from scratch.',
+ customProps: {
+ icon: '🎨',
+ },
+ link: { type: 'doc', id: 'how-to-guides/roku/ui/introduction' },
+ items: [
+ {
+ type: 'category',
+ label: 'Chromeless',
+ items: [
+ 'how-to-guides/roku/ui/chromeless/introduction',
+ { type: 'doc', id: 'how-to-guides/roku/ui/build-chromeless-ui', label: 'Getting started' },
+ ],
+ },
+ {
+ type: 'category',
+ label: 'Default UI',
+ items: [
+ 'how-to-guides/roku/ui/default-ui/introduction',
+ 'how-to-guides/roku/ui/default-ui/getting-started',
+ {
+ type: 'category',
+ label: 'How-to guides',
+ items: ['how-to-guides/roku/ui/remove-ui-element'],
+ },
+ ],
+ },
+ ],
+ };
+}
+
function apiReferencesLink(config: PartialSidebarItemLink): SidebarItemLink {
return mergeSidebarItems(
{
diff --git a/src/components/HomepageFeatures/index.tsx b/src/components/HomepageFeatures/index.tsx
index a7e7f72d6da4..4404d07fba4e 100644
--- a/src/components/HomepageFeatures/index.tsx
+++ b/src/components/HomepageFeatures/index.tsx
@@ -34,15 +34,12 @@ const FeatureList: FeatureItem[] = [
device, including on web, mobile, smart TVs, set-top-boxes and gaming consoles.
- Pair it with Open Video UI to easily build and customize your video player UI to match your branding style through a comprehensive library
- of open-source UI components.
+ Start with the basic default UI, customize the player with Open Video UI's ready-made components, or use the chromeless player to build
+ every part of the UI from scratch.
>
),
- to: [
- { link: '/theoplayer', text: 'OptiView Player' },
- { link: '/open-video-ui', text: 'Open Video UI' },
- ],
+ to: [{ link: '/theoplayer', text: 'Get Started' }],
},
{
title: 'Dolby OptiView Live',
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 1bbc7f32a2ed..819c0759af50 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -23,7 +23,7 @@ function HomepageHeader() {
export default function Home(): JSX.Element {
return (
-
+
diff --git a/src/plugin/llmsTxt.ts b/src/plugin/llmsTxt.ts
index 0dae5d14a723..744f99f2792e 100644
--- a/src/plugin/llmsTxt.ts
+++ b/src/plugin/llmsTxt.ts
@@ -195,7 +195,8 @@ async function writeProductFiles(
* same `postBuild` step: Docusaurus runs the `postBuild` hooks of all plugins in parallel, so a
* separate plugin could not rely on the generated Markdown being present yet.
*/
-export default function llmsTxt(context: LoadContext, options: Options): Plugin {
+export default function llmsTxt(context: LoadContext, pluginOptions: unknown): Plugin {
+ const options = pluginOptions as Options;
const { siteConfig } = context;
const siteUrl = normalizeUrl([siteConfig.url, siteConfig.baseUrl]);
const inner = llmsTxtPlugin(context, {
diff --git a/src/theme/DocBreadcrumbs/index.tsx b/src/theme/DocBreadcrumbs/index.tsx
index 186933c5451d..eb363b77fe1e 100644
--- a/src/theme/DocBreadcrumbs/index.tsx
+++ b/src/theme/DocBreadcrumbs/index.tsx
@@ -47,8 +47,6 @@ function getMainDocTitle(docPluginId: string): string | null {
switch (docPluginId) {
case 'theoplayer':
return 'Player';
- case 'open-video-ui':
- return 'Open Video UI';
case 'theoads':
return 'Ads';
case 'adengine':
diff --git a/src/theme/DocVersionBanner/index.tsx b/src/theme/DocVersionBanner/index.tsx
index 826ebe810267..715dd5b3cb2e 100644
--- a/src/theme/DocVersionBanner/index.tsx
+++ b/src/theme/DocVersionBanner/index.tsx
@@ -11,8 +11,6 @@ function getProductNameByPluginId(pluginId: string): string {
// Keep these in sync with @docusaurus/plugin-content-docs plugin IDs in Docusaurus config
case 'theoplayer':
return 'THEOplayer';
- case 'open-video-ui':
- return 'Open Video UI';
case 'ads':
return 'OptiView Ads';
case 'adengine':
diff --git a/src/util/platform.ts b/src/util/platform.ts
index a97d38ba097c..7a0c5b674f5c 100644
--- a/src/util/platform.ts
+++ b/src/util/platform.ts
@@ -96,50 +96,8 @@ const theoplayerPlatforms: readonly PlatformDescription[] = [
},
];
-const openVideoUiPlatforms: readonly PlatformDescription[] = [
- {
- platform: 'web',
- label: 'Open Video UI for Web',
- description: 'For desktop and mobile web browsers using Web Components',
- gettingStartedDoc: 'web/getting-started',
- icon: 'web',
- minVersion: 1,
- },
- {
- platform: 'android',
- label: 'Open Video UI for Android',
- description: 'For Android smartphones and tablets using Jetpack Compose',
- gettingStartedDoc: 'android/getting-started',
- icon: 'android',
- minVersion: 1,
- },
- {
- platform: 'react',
- label: 'Open Video UI for React',
- description: 'For web apps using React components',
- gettingStartedDoc: 'react/getting-started',
- icon: 'react',
- minVersion: 1,
- },
- {
- platform: 'react-native',
- label: 'Open Video UI for React Native',
- shortLabel: 'React Native UI',
- description: 'For cross-platform apps using React Native components',
- gettingStartedDoc: 'react-native/getting-started',
- icon: 'react',
- minVersion: 1,
- },
-];
-
export function getPlatforms(docsPluginId: string): readonly PlatformDescription[] {
- if (docsPluginId === 'theoplayer') {
- return theoplayerPlatforms;
- } else if (docsPluginId === 'open-video-ui') {
- return openVideoUiPlatforms;
- } else {
- return [];
- }
+ return docsPluginId === 'theoplayer' ? theoplayerPlatforms : [];
}
export function getPlatformsByVersion(docsPluginId: string, version?: string): readonly PlatformDescription[] {
@@ -164,14 +122,9 @@ export function usePlatforms(): readonly PlatformDescriptionWithUrl[] {
type PlatformDescriptionsByName = Record;
const theoplayerPlatformsByName = Object.fromEntries(theoplayerPlatforms.map((desc) => [desc.platform, desc])) as PlatformDescriptionsByName;
-const openVideoUiPlatformsByName = Object.fromEntries(openVideoUiPlatforms.map((desc) => [desc.platform, desc])) as PlatformDescriptionsByName;
export function getPlatformByName(docsPluginId: string, platformName: PlatformName): PlatformDescription | undefined {
- if (docsPluginId === 'theoplayer') {
- return theoplayerPlatformsByName[platformName];
- } else if (docsPluginId === 'open-video-ui') {
- return openVideoUiPlatformsByName[platformName];
- }
+ return docsPluginId === 'theoplayer' ? theoplayerPlatformsByName[platformName] : undefined;
}
export function isDocSharedWithPlatform(docsPluginId: string, doc: GlobalDoc, platformName: PlatformName) {
@@ -198,8 +151,6 @@ export function getPlatformDoc(docsPluginId: string, version: GlobalVersion, doc
}
if (docsPluginId === 'theoplayer') {
return findMatchingTheoplayerDoc(version, doc, platformName);
- } else if (docsPluginId === 'open-video-ui') {
- return findMatchingOpenVideoUiDoc(version, doc, platformName);
}
}
@@ -257,6 +208,12 @@ function findMatchingTheoplayerDoc(version: GlobalVersion, doc: GlobalDoc, platf
if (matchingDoc) return matchingDoc;
}
}
+ // UI
+ const uiMatch = docPath.match(/^\/ui\/([a-z-]+)(|\/.*)$/);
+ if (uiMatch && isPlatformName(uiMatch[1])) {
+ const prefix = `${version.path}/ui/${platformName}`;
+ return findMatchingDoc(version, doc, prefix, uiMatch[2], '');
+ }
// How-to guides
const howToGuideMatch = docPath.match(/^\/how-to-guides\/([a-z-]+)(|\/.*)$/);
if (howToGuideMatch && isPlatformName(howToGuideMatch[1])) {
@@ -271,15 +228,6 @@ function findMatchingTheoplayerDoc(version: GlobalVersion, doc: GlobalDoc, platf
}
}
-function findMatchingOpenVideoUiDoc(version: GlobalVersion, doc: GlobalDoc, platformName: PlatformName): GlobalDoc | undefined {
- const docPath = doc.path.replace(version.path, '');
- const match = docPath.match(/^\/([a-z-]+)(|\/.*)$/);
- if (match && isPlatformName(match[1])) {
- const prefix = `${version.path}/${platformName}`;
- return findMatchingDoc(version, doc, prefix, match[2], '');
- }
-}
-
function findMatchingDoc(version: GlobalVersion, doc: GlobalDoc, prefix: string, suffix: string, fallbackSuffix: string): GlobalDoc | undefined {
// Find exact match
const exactDocPath = `${prefix}${suffix}`.replace(/\/$/, '');
diff --git a/open-video-ui/external/android-ui b/theoplayer/external/android-ui
similarity index 100%
rename from open-video-ui/external/android-ui
rename to theoplayer/external/android-ui
diff --git a/open-video-ui/external/react-native-theoplayer-ui b/theoplayer/external/react-native-theoplayer-ui
similarity index 100%
rename from open-video-ui/external/react-native-theoplayer-ui
rename to theoplayer/external/react-native-theoplayer-ui
diff --git a/open-video-ui/external/web-ui b/theoplayer/external/web-ui
similarity index 100%
rename from open-video-ui/external/web-ui
rename to theoplayer/external/web-ui
diff --git a/theoplayer/getting-started/01-sdks/01-web/00-getting-started.mdx b/theoplayer/getting-started/01-sdks/01-web/00-getting-started.mdx
index 116256bb1284..611143221199 100644
--- a/theoplayer/getting-started/01-sdks/01-web/00-getting-started.mdx
+++ b/theoplayer/getting-started/01-sdks/01-web/00-getting-started.mdx
@@ -211,10 +211,10 @@ Next, we’ll include the THEOplayer SDK.
To access the THEOplayer API and default UI, you must first include the THEOplayer library files.
The JavaScript library exposes the THEOplayer API and the CSS library contains the default UI.
-:::tip[Open Video UI]
+:::tip[Customize your player with Open Video UI]
-The Open Video UI is our new Web UI. It provides component libraries for building a world-class video player experience powered by the THEOplayer SDK.
-[See our Getting Started guide to start using the Open Video UI.](/open-video-ui/web/getting-started/)
+The Web SDK includes a basic default UI. When you need a more customized player, Open Video UI provides ready-made components that you can compose and style instead of building every control from scratch.
+[Get started with Open Video UI for Web.](/theoplayer/ui/web/open-video-ui/getting-started/)
:::
diff --git a/theoplayer/getting-started/01-sdks/01-web/01-getting-started-accessibility.mdx b/theoplayer/getting-started/01-sdks/01-web/01-getting-started-accessibility.mdx
index 5730020d4047..71fc320b8a82 100644
--- a/theoplayer/getting-started/01-sdks/01-web/01-getting-started-accessibility.mdx
+++ b/theoplayer/getting-started/01-sdks/01-web/01-getting-started-accessibility.mdx
@@ -61,11 +61,11 @@ Common roles are:
### Focus Style
-Focus Style allows the buttons on the video player (the control bar, menu items, close buttons, etc.) to be outlined in order to make them more visible when they are clicked or hovered over. This feature makes it easier for all viewers to see and understand which buttons are in use and which one they have selected. Also while hovered over, the Tooltips feature can make it easier for users by giving them a text description of the button on the UI. For example, when hovered over the mute button, it is outlined and a readers also see the word "Mute" appear on their UI. You can change the look of the default UI with our [UI Skinning Guide](/theoplayer/how-to-guides/web/ui/ui-skinning/) or fully customize every element of your video player with our [Open Video UI](/open-video-ui/web/).
+Focus Style allows the buttons on the video player (the control bar, menu items, close buttons, etc.) to be outlined in order to make them more visible when they are clicked or hovered over. This feature makes it easier for all viewers to see and understand which buttons are in use and which one they have selected. Also while hovered over, the Tooltips feature can make it easier for users by giving them a text description of the button on the UI. For example, when hovered over the mute button, it is outlined and a readers also see the word "Mute" appear on their UI. You can change the look of the default UI with our [UI Skinning Guide](/theoplayer/ui/web/ui-skinning/) or fully customize every element of your video player with our [Open Video UI](/theoplayer/ui/web/open-video-ui/).
### User Interface Customization
-User Interface, or UI, is the aspect of the video content that the viewer engages with. For viewers with disabilities, it is important that colors have sufficient contrast with the text and its background. The contrast is not limited to captions, but also includes the text on images, buttons and icons. This feature is especially helpful for viewers with color blindness or low contrast visibility, which is common in aging viewers, as well as viewers in difficult light conditions. It is also important for the video player to have a clear layout and design, to make it as easy and accessible to all viewers as possible. You can change the look of the default UI with our [UI Skinning Guide](/theoplayer/how-to-guides/web/ui/ui-skinning/) or fully customize every element of your video player with our [Open Video UI](/open-video-ui/web/).
+User Interface, or UI, is the aspect of the video content that the viewer engages with. For viewers with disabilities, it is important that colors have sufficient contrast with the text and its background. The contrast is not limited to captions, but also includes the text on images, buttons and icons. This feature is especially helpful for viewers with color blindness or low contrast visibility, which is common in aging viewers, as well as viewers in difficult light conditions. It is also important for the video player to have a clear layout and design, to make it as easy and accessible to all viewers as possible. You can change the look of the default UI with our [UI Skinning Guide](/theoplayer/ui/web/ui-skinning/) or fully customize every element of your video player with our [Open Video UI](/theoplayer/ui/web/open-video-ui/).
### Keyboard Compatibility
diff --git a/theoplayer/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md b/theoplayer/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
index 8bcccf25b51c..0a12e11eaaae 100644
--- a/theoplayer/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
+++ b/theoplayer/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
@@ -77,7 +77,7 @@ selectQuality(resolutions[0]);
##### Android SDK
-Android SDK does not have a built-in UI. It also does not support JavaScript injection. However, you can implement a similar custom quality selection menu using [Open Video UI for Android](/open-video-ui/android/) and following the same logic for Web SDK.
+Android SDK does not have a built-in UI. It also does not support JavaScript injection. However, you can implement a similar custom quality selection menu using [Open Video UI for Android](/theoplayer/ui/android/open-video-ui/) and following the same logic for Web SDK.
##### iOS SDK
diff --git a/theoplayer/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-11.md b/theoplayer/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-11.md
index 23893d98e0c7..c0243e2c6ee8 100644
--- a/theoplayer/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-11.md
+++ b/theoplayer/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-11.md
@@ -11,7 +11,7 @@ Run the following command to install THEOplayer Web SDK version 11:
npm install theoplayer@11
```
-If you're using the [Open Video UI for Web](/open-video-ui/web/) or one
+If you're using the [Open Video UI for Web](/theoplayer/ui/web/open-video-ui/) or one
of [our connectors](/theoplayer/connectors/web/),
make sure to update them to the latest version too to ensure proper support for THEOplayer version 11.
diff --git a/theoplayer/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-11.md b/theoplayer/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-11.md
index f32ba1dde8ea..fd2f5a289be8 100644
--- a/theoplayer/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-11.md
+++ b/theoplayer/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-11.md
@@ -13,7 +13,7 @@ dependencies {
}
```
-If you're using the [Open Video UI for Android](/open-video-ui/android/) or one of [our connectors](/theoplayer/connectors/android/),
+If you're using the [Open Video UI for Android](/theoplayer/ui/android/open-video-ui/) or one of [our connectors](/theoplayer/connectors/android/),
make sure to update them to the latest version too to ensure proper support for THEOplayer version 11.
## Player methods must be called from the main thread
diff --git a/theoplayer/how-to-guides/android/ui/build-chromeless-ui.mdx b/theoplayer/how-to-guides/android/ui/build-chromeless-ui.mdx
index 119f16c5fc29..f6a76d17d58e 100644
--- a/theoplayer/how-to-guides/android/ui/build-chromeless-ui.mdx
+++ b/theoplayer/how-to-guides/android/ui/build-chromeless-ui.mdx
@@ -1,20 +1,18 @@
---
sidebar_position: 1
-sidebar_label: Build a chromeless UI
+sidebar_label: Getting started
---
-# How to build a chromeless UI on Android
+# Getting started with a chromeless UI on Android
+import DocCardList from '@theme/DocCardList';
import Intro from '../../shared/ui/_build-chromeless-ui-intro.mdx';
-import UXEnhancements from '../../shared/ui/_build-chromeless-ui-ux-enhancements.mdx';
-## Creating a chromeless player instance
+## Create a chromeless player instance
-The Android SDK does not ship a default UI. A
-[`THEOplayerView`](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/THEOplayerView.html)
-only renders the video itself, so every UI on top of it is a UI of your own making.
+The Android SDK does not ship a default UI. A [`THEOplayerView`](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/THEOplayerView.html) renders the video, and your application adds its own controls on top.
```kotlin
val config = THEOplayerConfig.Builder()
@@ -24,242 +22,35 @@ val theoPlayerView = THEOplayerView(this, config)
val player = theoPlayerView.player
```
-The rest of this article refers to this `player` variable.
+The following guides refer to this `player` variable. If you prefer to start with ready-made components, use [Open Video UI for Android](open-video-ui/introduction.mdx).
-If you'd rather start from a ready-made UI and customize it,
-have a look at [Open Video UI for Android](/open-video-ui/android/).
+## Track player states
-## Tracking transitions between states
-
-Refer to the article on ["How to track player states"](../player/track-player-states.mdx) to advance your understanding
-on video player states. Understanding the video player lifecycle is a vital part of building a chromeless UI.
+Before adding controls, learn how to [track player states](../player/track-player-states.mdx). Your UI should respond correctly when playback starts, pauses, buffers, ends, or encounters an error.

-This article explains how to track the start of a video and its end, but also how to detect buffering, errors and much more.
-You'll need to implement (some of) these transitions in your chromeless UI in order to render the appropriate components.
-
-## Mapping components
-
-A video player UI can be dissected into different components (or controls).
-A component offers context, and it may also offer an action. The "play button" is an example of an action component,
-but the "current time text" (X in the screenshot below) is a context component.
-
-As a developer, you should understand which controls are out there, and which video player APIs are relevant.
-
-This section addresses the following components:
-
-1. Play button
-2. Pause button
-3. Volume mute button
-4. Volume change button
-5. Current time text
-6. Duration text
-7. Scrub bar
-8. Buffered blocks
-9. Live button
-10. Audio change component
-11. Subtitle change component
-12. Video quality change component
-13. Fullscreen and inline button
-14. Picture-in-picture button
-15. Chromecast button
-16. AirPlay button
-
-Additionally, we'll discuss the following overlays:
-
-1. Subtitle cues
-2. Advertisement metadata
-
-
-
-Instead of providing inline code on this article, we'll refer to other articles as much as possible,
-because linking the THEOplayer API to your custom components is an application of many of the existing how-to guides
-for a specific use-case.
-
-If you know how to navigate our API references, you don't even need this section.
-The graphic below (originally referenced in ["custom analytics integration"](../analytics/custom-analytics-integration.mdx)) gives
-a basic overview of many of the relevant interfaces and events.
-
-
-
-### Play button
-
-You should show your play button when you are in a paused state, as described in ["how to track player states"](../player/track-player-states.mdx).
-If a viewer clicks your play button, you should call the `play()` on your `player` instance as documented in our
-[API reference](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#play--).
-
-### Pause button
-
-You should show your pause button when you are in a playing state, as described in ["how to track player states"](../player/track-player-states.mdx).
-If a viewer clicks your pause button, you should call the `pause()` on your `player` instance as documented in our
-[API reference](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#pause--).
-
-### Volume mute button
-
-You can check whether your volume is muted through the `muted` property (or method) on your `player` instance as documented in
-our [isMuted()](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#isMuted--) and [setMuted()](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#setMuted-boolean-).
-You should consider showing a different button depending on whether `muted` returns `true` or `false`.
-If a viewer clicks your mute button, you should set `muted` to `!muted`.
-
-### Volume change button
-
-You can get and set your volume level through the `volume` property (or method) on your `player` instance as documented in
-our [getVolume()](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#getVolume--) and [setVolume()](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#setVolume-double-).
-You should consider showing a different button depending on the volume level.
-
-Note that you cannot control the volume level on Android, as this is delegated to the hardware buttons.
-You can only toggle the muted state.
-
-### Current time text
-
-You can get the current time through the `currentTime` property (or method) on your `player` instance as documented in
-our [requestCurrentTime()](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#requestCurrentTime-com.theoplayer.android.api.player.RequestCallback-) and [setCurrentTime()](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#setCurrentTime-double-).
-
-Note that `currentTime` returns a relative value in seconds.
-If you are dealing with live streams, you might want to use `currentProgramDateTime` instead, as this returns an absolute value like `"2022-04-01T13:37:42.666Z"`.
-This property (or method) is especially useful when implementing an [EPG](https://en.wikipedia.org/wiki/Electronic_program_guide) experience.
-
-### Duration text
-
-You can get the duration of a stream through the `duration` property (or method) on your `player` instance as documented in our
-[API reference](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#getDuration--).
-
-The `duration` will return the duration in seconds for VOD streams, and `Infinity` for live streams.
-
-You can calculate the remaining duration by subtracting the `currentTime` from the `duration`.
-
-### Scrub bar
-
-Related to the subsection on "Current time text",
-you can seek to a different playhead position through the `currentTime` property (or `setCurrentTime()` method) on your `player` instance.
-Alternatively, for live streams, you may also use `currentProgramDateTime` to seek to absolute playhead positions.
-
-You can only seek to a playhead position that is within any of the time ranges of your `seekable` property (or method) of your `player` instance as documented in our
-[API reference](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#requestSeekable-com.theoplayer.android.api.player.RequestCallback-).
-
-You subscribe to the `timeupdate` event to periodically update your scrub bar bullet.
-This event is dispatched every ~200ms during playback.
-Refer to our [API reference](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/event/player/PlayerEventTypes.html#TIMEUPDATE) for more info on this event.
-
-A `seek` event is dispatched when you set a new value for `currentTime` or `currentProgramDateTime`.
-A `seeked` event is dispatched when the seek was successful.
-Refer to our [API reference](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/event/player/PlayerEventTypes.html#SEEKING) for more info on these events.
-You should consider displaying a "stalling icon" between these two events.
-
-#### Buffered blocks
-
-You may also want to annotate parts of the scrub bar that have already been buffered.
-When the viewer seeks to a buffered block playback immediately starts.
-
-You can track information on what's being buffered through the `progress` event.
-Refer to our [API reference](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/event/player/PlayerEventTypes.html#PROGRESS) for more info on this event.
-In the callback of the `progress` event,
-you will want to query the `buffered` property (or method) to iterate through the available buffered time ranges.
-The `buffered` property (or method) is described in our [API reference](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#requestBuffered-com.theoplayer.android.api.player.RequestCallback-).
-
-### Live button
-
-A stream is a live stream when your `duration` property (or method) returns `Infinity`.
-If you want to implement a button that takes you to the "most live point" when clicked,
-then you set `currentTime` to the maximum `seekable` `end` time.
-
-### Audio change component
-
-Refer to the article on ["how to detect audio tracks"](../media-tracks/detect-audio-tracks.mdx)
-to know how to detect the available audio tracks. You'll need this article to know which audio tracks are part of your stream.
-
-Refer to the article on ["how to enable and disable audio tracks"](../media-tracks/enable-disable-audio-tracks.mdx)
-to know how to enable or disable another audio track. You'll need this article to enable another audio track.
-
-Refer to the article on ["how to detect audio track changes"](../media-tracks/detect-audio-track-changes.mdx)
-to know how to detect when an audio track has been enabled or disabled. You'll need this article to correctly annotate your UI.
-
-### Subtitle change component
-
-Refer to the article on ["how to detect text tracks"](../text-tracks/detect-text-tracks.mdx)
-to know how to detect the available text tracks. You'll need this article to know which subtitles and closed captions are part of your stream.
-
-Refer to the article on ["how to enable and disable text tracks"](../text-tracks/enable-disable-text-tracks.mdx)
-to know how to enable or disable another text track.
-
-Refer to the article on ["how to detect text track changes"](../text-tracks/detect-text-track-changes.mdx)
-to know how to detect when a text track has been enabled or disabled. You'll need this article to correctly annotate your UI.
-
-### Video quality change component
-
-Refer to the article on ["how to detect video track qualities"](../media-tracks/detect-video-track-qualities.mdx)
-to know how to detect the available video track qualities. You'll need this article to know which video qualities are part of your stream.
-
-Refer to the article on ["how to select video track quality"](../media-tracks/select-video-track-quality.mdx)
-to know how to enable another video track quality.
-
-Refer to the article on ["how to detect video track quality changes"](../media-tracks/detect-video-track-quality-changes.mdx)
-to know how to detect when a specific video track quality has become active. You'll need this article to correctly annotate your UI.
-
-### Fullscreen and inline button
-
-You cannot use our ['FullscreenManager API`](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/fullscreen/FullScreenManager.html) to switch between
-fullscreen and inline.
-Instead, you need to implement your own fullscreen handling, as well as any associated orientation changes.
-
-Refer to [https://developer.android.com/training/system-ui/immersive](https://developer.android.com/training/system-ui/immersive) for more information on implementing your own fullscreen handling.
-
-### Picture-in-picture button
-
-You should implement your Picture-in-Picture UI and UX independently of THEOplayer,
-regardless of whether you're considering "in-app" picture-in-picture or "out-of-app" picture-in-picture.
-The [THEOplayer Picture-in-Picture API](../miscellaneous/picture-in-picture.mdx) is not available for chromeless players.
-
-Related resources:
-
-- [https://developers.google.com/web/updates/2017/09/picture-in-picture](https://developers.google.com/web/updates/2017/09/picture-in-picture)
-- [https://developer.apple.com/documentation/webkitjs/adding_picture_in_picture_to_your_safari_media_controls](https://developer.apple.com/documentation/webkitjs/adding_picture_in_picture_to_your_safari_media_controls)
-- [https://developer.android.com/guide/topics/ui/picture-in-picture](https://developer.android.com/guide/topics/ui/picture-in-picture)
-- [https://developer.apple.com/documentation/avkit/adopting_picture_in_picture_in_a_custom_player](https://developer.apple.com/documentation/avkit/adopting_picture_in_picture_in_a_custom_player)
-
-### Chromecast button
-
-Refer to our [introduction on Chromecast](../cast/chromecast/introduction.mdx) to know how to track the availability of Chromecast,
-and how to start and stop a Chromecast session.
-
-### AirPlay button
-
-Refer to our [introduction on AirPlay](../../web/cast/airplay/introduction.mdx) to know how to track the availability of AirPlay,
-and how to start and stop an AirPlay session.
-
-### Subtitle cues
-
-You may still leverage THEOplayer's default rendering of subtitles (and closed captions) in your chromeless UI.
-
-So what's the alternative? Instead of using THEOplayer's default rendering,
-you can programmatically detect when a subtitle (and closed captions) cue should appear and disappear,
-as explained in ["how to detect active text track cues"](../text-tracks/detect-active-text-track-cues.mdx).
-You could insert the cue when it should appear, and remove it when it should disappear.
-This alternative makes you fully responsible for the rendering and styling, and gives you total control over it.
-
-### Advertisement metadata
-
-When playing back advertisements, you might want to overlay a countdown, show a skip button after some seconds,
-insert ad markers in the scrub bar, and achieve other use cases.
-
-If you use [Google IMA](../ads/google-ima.mdx) for client-side ad-insertion,
-then this integration might already take care of some default UI customization.
-
-If you are using THEOplayer's [default ad integration](../ads/set-up-vast-and-vmap.mdx) for client-side ad-insertion,
-then you need to [subscribe to the appropriate ad events](../ads/subscribe-to-ad-events.mdx),
-and apply your UI and UX in the callbacks of these events.
-
-Similarly, if you're doing server-side ad-insertion, you also need to apply your UI and UX in the callbacks of your ad events.
-
-## Sample code
-
-The GitHub project at [https://github.com/THEOplayer/samples-android-sdk/tree/master/Custom-UI](https://github.com/THEOplayer/samples-android-sdk/tree/master/Custom-UI)
-provides a basic implementation of a chromeless UI on the Android SDK.
-
-
-
-## Error handling
-
-A UI should also be capable of handling errors and informing the viewer.
-Refer to our [introduction on errors](../miscellaneous/error/introduction.mdx) to further explore this topic.
+## Next steps
+
+
diff --git a/theoplayer/how-to-guides/android/ui/chromeless/error-handling.mdx b/theoplayer/how-to-guides/android/ui/chromeless/error-handling.mdx
new file mode 100644
index 000000000000..257e8a5956d7
--- /dev/null
+++ b/theoplayer/how-to-guides/android/ui/chromeless/error-handling.mdx
@@ -0,0 +1,11 @@
+---
+sidebar_label: Error handling
+---
+
+# Error handling in a chromeless UI on Android
+
+A chromeless UI must present its own error state because the SDK does not render controls or viewer-facing error messages for you.
+
+Decide how to present recoverable and terminal failures, whether viewers can retry, and which details should be retained for diagnostics. Clear loading indicators when an error occurs so the interface does not appear to buffer indefinitely.
+
+See the [Android error-handling guides](../../miscellaneous/error/introduction.mdx) to detect Player errors and map them to messages and recovery actions.
diff --git a/theoplayer/how-to-guides/android/ui/chromeless/introduction.mdx b/theoplayer/how-to-guides/android/ui/chromeless/introduction.mdx
new file mode 100644
index 000000000000..041c499faf1f
--- /dev/null
+++ b/theoplayer/how-to-guides/android/ui/chromeless/introduction.mdx
@@ -0,0 +1,12 @@
+---
+slug: /how-to-guides/android/ui/chromeless/
+sidebar_label: Introduction
+---
+
+# Chromeless UI on Android
+
+A chromeless Android player renders video without playback controls. Your application creates every control with Android UI technologies and connects each interaction to the OptiView Player API.
+
+Choose this approach when you need complete control over the interface or cannot use Open Video UI components. Building from scratch requires an understanding of playback states, tracks, accessibility, errors, casting, and Android lifecycle behavior.
+
+Continue with [Getting started](../build-chromeless-ui.mdx) to create a `THEOplayerView` and access its Player API.
diff --git a/theoplayer/how-to-guides/android/ui/chromeless/mapping-components.mdx b/theoplayer/how-to-guides/android/ui/chromeless/mapping-components.mdx
new file mode 100644
index 000000000000..ac9d1b6d056f
--- /dev/null
+++ b/theoplayer/how-to-guides/android/ui/chromeless/mapping-components.mdx
@@ -0,0 +1,58 @@
+---
+sidebar_label: Mapping components
+---
+
+# Mapping components in a chromeless UI on Android
+
+A chromeless UI is made up of native Android controls and displays that must reflect player state and call the appropriate OptiView Player APIs. This guide maps the most common components to the APIs and supporting guides used to implement them.
+
+
+
+## Play and pause
+
+Show the appropriate control for the current state, as described in [tracking player states](../../player/track-player-states.mdx). Call [`play()`](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#play--) or [`pause()`](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#pause--) when the viewer selects it.
+
+## Mute and volume
+
+Use [`isMuted()`](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#isMuted--) and [`setMuted()`](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#setMuted-boolean-) to implement mute controls.
+
+Android delegates volume level changes to hardware controls, so the application should not provide an independent software volume slider.
+
+## Current time and duration
+
+Use [`requestCurrentTime()`](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#requestCurrentTime-com.theoplayer.android.api.player.RequestCallback-) and [`setCurrentTime()`](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#setCurrentTime-double-) for the playback position. Use [`getDuration()`](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#getDuration--) for duration.
+
+For live streams, `duration` is `Infinity`. You can use `currentProgramDateTime` when the interface needs an absolute program time.
+
+## Scrub bar and buffered ranges
+
+Only seek within [`requestSeekable()`](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#requestSeekable-com.theoplayer.android.api.player.RequestCallback-) ranges. Update the scrubber in response to [`TIMEUPDATE`](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/event/player/PlayerEventTypes.html#TIMEUPDATE), and represent buffered ranges using [`requestBuffered()`](pathname:///theoplayer/v11/api-reference/android/com/theoplayer/android/api/player/Player.html#requestBuffered-com.theoplayer.android.api.player.RequestCallback-).
+
+Display a loading state between seeking and seek completion when appropriate.
+
+## Audio, subtitle, and quality selection
+
+Use the platform guides to build track selectors:
+
+- [Detect audio tracks](../../media-tracks/detect-audio-tracks.mdx)
+- [Enable and disable audio tracks](../../media-tracks/enable-disable-audio-tracks.mdx)
+- [Detect text tracks](../../text-tracks/detect-text-tracks.mdx)
+- [Enable and disable text tracks](../../text-tracks/enable-disable-text-tracks.mdx)
+- [Detect video-track qualities](../../media-tracks/detect-video-track-qualities.mdx)
+- [Select a video-track quality](../../media-tracks/select-video-track-quality.mdx)
+
+## Fullscreen and picture-in-picture
+
+Implement fullscreen handling and orientation changes in the application rather than relying on `FullScreenManager`. See Android's [immersive-mode guidance](https://developer.android.com/training/system-ui/immersive).
+
+Implement picture-in-picture UI independently of the Player SDK. The [Player Picture-in-Picture API](../../miscellaneous/picture-in-picture.mdx) is not available for chromeless players.
+
+## Casting
+
+Use the [Chromecast guide](../../cast/chromecast/introduction.mdx) to detect availability and start or stop a casting session. AirPlay guidance is available in the [Web SDK documentation](../../../web/cast/airplay/introduction.mdx).
+
+## Subtitle and advertisement overlays
+
+You can use the SDK's subtitle rendering or [detect active text-track cues](../../text-tracks/detect-active-text-track-cues.mdx) and render them yourself.
+
+For advertising controls such as countdowns, skip buttons, and scrub-bar markers, subscribe to the relevant [ad events](../../ads/subscribe-to-ad-events.mdx) and update your interface from their callbacks.
diff --git a/theoplayer/how-to-guides/android/ui/chromeless/ux-enhancements.mdx b/theoplayer/how-to-guides/android/ui/chromeless/ux-enhancements.mdx
new file mode 100644
index 000000000000..e95931be0de7
--- /dev/null
+++ b/theoplayer/how-to-guides/android/ui/chromeless/ux-enhancements.mdx
@@ -0,0 +1,16 @@
+---
+sidebar_label: UX enhancements
+---
+
+# UX enhancements for a chromeless UI on Android
+
+A functional player still needs clear feedback and convenient interactions. Plan these experiences alongside the core playback controls:
+
+1. **Loading spinner:** Indicate when the player is waiting for video data.
+2. **Poster:** Show an image before initial playback and after the video ends.
+3. **Up next:** Offer the next stream near the end of playback and optionally start it automatically.
+4. **Skip intro:** Let viewers skip the current introduction.
+5. **Ad countdown:** Display the remaining duration of an ad break.
+6. **Ad markers:** Indicate ad-break positions on the scrub bar.
+
+Drive each enhancement from Player events and state. Start with [tracking player states](../../player/track-player-states.mdx), then account for Android lifecycle transitions and configuration changes.
diff --git a/theoplayer/how-to-guides/android/ui/introduction.mdx b/theoplayer/how-to-guides/android/ui/introduction.mdx
index abbf9896de4a..280377bdf6c5 100644
--- a/theoplayer/how-to-guides/android/ui/introduction.mdx
+++ b/theoplayer/how-to-guides/android/ui/introduction.mdx
@@ -9,23 +9,26 @@ import Intro from '../../shared/ui/_introduction-intro.mdx';
-## Open Video UI for Android
+## Open Video UI
-As of THEOplayer 5, the Android SDK no longer ships a default UI.
-Instead, we recommend using [Open Video UI for Android](/open-video-ui/android/),
-a set of open-source UI components which you can use as is, or compose and style to build your own UI.
+Use [Open Video UI for Android](/theoplayer/ui/android/open-video-ui/) to customize the player with ready-made, open-source components
+that you can use as is or compose and style to match your application.
If you're building a React Native application, use
-[Open Video UI for React Native](/open-video-ui/react-native/) instead.
+[Open Video UI for React Native](/theoplayer/ui/react-native/open-video-ui/) instead.
-## Implement a chromeless UI
+## Chromeless
-Alternatively, you can implement a UI completely on top of THEOplayer through the native technologies
-and programming languages of the platform. The THEOplayer API exposes all the events and properties
-that you need to implement a custom design.
+For complete control, you can start without a UI and build every control and interaction with the native technologies
+and programming languages of the platform. The OptiView Player API exposes all the events and properties
+that you need to implement a custom design from scratch.
Refer to our article on [how to build a chromeless UI](build-chromeless-ui.mdx) for more information.
+## Default UI
+
+As of THEOplayer 5, the Android SDK no longer ships a default UI.
+
## Related articles
- [How to change how a video should fit inside a container](change-video-fit.mdx)
diff --git a/open-video-ui/android/getting-started.mdx b/theoplayer/how-to-guides/android/ui/open-video-ui/getting-started.mdx
similarity index 96%
rename from open-video-ui/android/getting-started.mdx
rename to theoplayer/how-to-guides/android/ui/open-video-ui/getting-started.mdx
index cf62f194ee82..7cb192fbd084 100644
--- a/open-video-ui/android/getting-started.mdx
+++ b/theoplayer/how-to-guides/android/ui/open-video-ui/getting-started.mdx
@@ -1,4 +1,5 @@
---
+slug: /how-to-guides/android/ui/open-video-ui/getting-started/
description: Start building your UI in just a few minutes!
sidebar_position: 1
sidebar_custom_props: { 'icon': '🚀' }
@@ -8,7 +9,7 @@ sidebar_custom_props: { 'icon': '🚀' }
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
-import RebrandingNotice from '../callouts/_rebranding_notice.md';
+import RebrandingNotice from '../../../../callouts/_rebranding_notice.md';
diff --git a/theoplayer/how-to-guides/android/ui/open-video-ui/introduction.mdx b/theoplayer/how-to-guides/android/ui/open-video-ui/introduction.mdx
new file mode 100644
index 000000000000..283c6b238db7
--- /dev/null
+++ b/theoplayer/how-to-guides/android/ui/open-video-ui/introduction.mdx
@@ -0,0 +1,15 @@
+---
+slug: /how-to-guides/android/ui/open-video-ui/
+sidebar_label: Introduction
+---
+
+# Open Video UI for Android
+
+import Intro from '../../../shared/ui/_open-video-ui-intro.mdx';
+import RebrandingNotice from '../../../../callouts/_rebranding_notice.md';
+import DocCardList from '@theme/DocCardList';
+
+
+
+
+
diff --git a/theoplayer/how-to-guides/ios/ui/build-chromeless-ui.mdx b/theoplayer/how-to-guides/ios/ui/build-chromeless-ui.mdx
index c43f480145d1..88d4119d2fc7 100644
--- a/theoplayer/how-to-guides/ios/ui/build-chromeless-ui.mdx
+++ b/theoplayer/how-to-guides/ios/ui/build-chromeless-ui.mdx
@@ -1,279 +1,53 @@
---
sidebar_position: 1
-sidebar_label: Build a chromeless UI
+sidebar_label: Getting started
---
-# How to build a chromeless UI on iOS
+# Getting started with a chromeless UI on iOS and tvOS
+import DocCardList from '@theme/DocCardList';
import Intro from '../../shared/ui/_build-chromeless-ui-intro.mdx';
-import UXEnhancements from '../../shared/ui/_build-chromeless-ui-ux-enhancements.mdx';
-## Creating a chromeless player instance
+## Create a chromeless player instance
-The iOS SDK does not ship a default UI. A
-[`THEOplayer`](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html)
-instance only renders the video itself, so every UI on top of it is a UI of your own making.
+The iOS and tvOS SDKs do not ship a default UI. A [`THEOplayer`](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html) instance renders video, and your application adds native controls on top.
```swift
let config = THEOplayerConfiguration(license: "your_license_string")
let player = THEOplayer(configuration: config)
```
-The rest of this article refers to this `player` variable.
+The following guides refer to this `player` variable.
-## Tracking transitions between states
+## Track player states
-Refer to the article on ["How to track player states"](../player/track-player-states.mdx) to advance your understanding
-on video player states. Understanding the video player lifecycle is a vital part of building a chromeless UI.
+Before adding controls, learn how to [track player states](../player/track-player-states.mdx). Your UI should respond correctly when playback starts, pauses, buffers, ends, or encounters an error.

-This article explains how to track the start of a video and its end, but also how to detect buffering, errors and much more.
-You'll need to implement (some of) these transitions in your chromeless UI in order to render the appropriate components.
-
-## Mapping components
-
-A video player UI can be dissected into different components (or controls).
-A component offers context, and it may also offer an action. The "play button" is an example of an action component,
-but the "current time text" (X in the screenshot below) is a context component.
-
-As a developer, you should understand which controls are out there, and which video player APIs are relevant.
-
-This section addresses the following components:
-
-1. Play button
-2. Pause button
-3. Volume mute button
-4. Volume change button
-5. Current time text
-6. Duration text
-7. Scrub bar
-8. Buffered blocks
-9. Live button
-10. Audio change component
-11. Subtitle change component
-12. Video quality change component
-13. Fullscreen and inline button
-14. Picture-in-picture button
-15. Chromecast button
-16. AirPlay button
-
-Additionally, we'll discuss the following overlays:
-
-1. Subtitle cues
-2. Advertisement metadata
-
-
-
-Instead of providing inline code on this article, we'll refer to other articles as much as possible,
-because linking the THEOplayer API to your custom components is an application of many of the existing how-to guides
-for a specific use-case.
-
-If you know how to navigate our API references, you don't even need this section.
-The graphic below (originally referenced in ["custom analytics integration"](../analytics/custom-analytics-integration.mdx)) gives
-a basic overview of many of the relevant interfaces and events.
-
-
-
-### Play button
-
-You should show your play button when you are in a paused state, as described in ["how to track player states"](../player/track-player-states.mdx).
-If a viewer clicks your play button, you should call the `play()` on your `player` instance as documented in our
-[API reference]().
-
-### Pause button
-
-You should show your pause button when you are in a playing state, as described in ["how to track player states"](../player/track-player-states.mdx).
-If a viewer clicks your pause button, you should call the `pause()` on your `player` instance as documented in our
-[API reference]().
-
-### Volume mute button
-
-You can check whether your volume is muted through the `muted` property (or method) on your `player` instance as documented in
-our [API reference](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html#/s:13THEOplayerSDK0A0C5mutedSbvp).
-You should consider showing a different button depending on whether `muted` returns `true` or `false`.
-If a viewer clicks your mute button, you should set `muted` to `!muted`.
-
-### Volume change button
-
-You can get and set your volume level through the `volume` property (or method) on your `player` instance as documented in
-our [API reference](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html#/s:13THEOplayerSDK0A0C6volumeSfvp).
-You should consider showing a different button depending on the volume level.
-
-Note that you cannot control the volume level on iOS, as this is delegated to the hardware buttons.
-You can only toggle the muted state.
-
-### Current time text
-
-You can get the current time through the `currentTime` property (or method) on your `player` instance as documented in
-our [requestCurrentTime()](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html#/s:13THEOplayerSDK0A0C18requestCurrentTime17completionHandleryySdSg_s5Error_pSgtc_tF) and [setCurrentTime()](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html#/s:13THEOplayerSDK0A0C14setCurrentTime_17completionHandlerySd_yypSg_s5Error_pSgtcSgtF).
-
-Note that `currentTime` returns a relative value in seconds.
-If you are dealing with live streams, you might want to use `currentProgramDateTime` instead, as this returns an absolute value like `"2022-04-01T13:37:42.666Z"`.
-This property (or method) is especially useful when implementing an [EPG](https://en.wikipedia.org/wiki/Electronic_program_guide) experience.
-
-### Duration text
-
-You can get the duration of a stream through the `duration` property (or method) on your `player` instance as documented in our
-[API reference](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html#/s:13THEOplayerSDK0A0C8durationSdSgvp).
-
-The `duration` will return the duration in seconds for VOD streams, and `Infinity` for live streams.
-
-You can calculate the remaining duration by subtracting the `currentTime` from the `duration`.
-
-### Scrub bar
-
-Related to the subsection on "Current time text",
-you can seek to a different playhead position through the `currentTime` property (or `setCurrentTime()` method) on your `player` instance.
-Alternatively, for live streams, you may also use `currentProgramDateTime` to seek to absolute playhead positions.
-
-You can only seek to a playhead position that is within any of the time ranges of your `seekable` property (or method) of your `player` instance as documented in our
-[API reference](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html#/s:13THEOplayerSDK0A0C15requestSeekable17completionHandleryySayAA9TimeRangeCGSg_s5Error_pSgtc_tF).
-
-You subscribe to the `timeupdate` event to periodically update your scrub bar bullet.
-This event is dispatched every ~200ms during playback.
-Refer to our [API reference](pathname:///theoplayer/v11/api-reference/ios/Structs/PlayerEventTypes.html#/s:13THEOplayerSDK16PlayerEventTypesV11TIME_UPDATEAA0D4TypeCyAA010TimeUpdateD0CGvpZ) for more info on this event.
-
-A `seek` event is dispatched when you set a new value for `currentTime` or `currentProgramDateTime`.
-A `seeked` event is dispatched when the seek was successful.
-Refer to our [API reference](pathname:///theoplayer/v11/api-reference/ios/Structs/PlayerEventTypes.html#/s:13THEOplayerSDK16PlayerEventTypesV7SEEKINGAA0D4TypeCyAA07SeekingD0CGvpZ) for more info on these events.
-You should consider displaying a "stalling icon" between these two events.
-
-#### Buffered blocks
-
-You may also want to annotate parts of the scrub bar that have already been buffered.
-When the viewer seeks to a buffered block playback immediately starts.
-
-You can track information on what's being buffered through the `progress` event.
-Refer to our [API reference](pathname:///theoplayer/v11/api-reference/ios/Structs/PlayerEventTypes.html#/s:13THEOplayerSDK16PlayerEventTypesV8PROGRESSAA0D4TypeCyAA08ProgressD0CGvpZ) for more info on this event.
-In the callback of the `progress` event,
-you will want to query the `buffered` property (or method) to iterate through the available buffered time ranges.
-The `buffered` property (or method) is described in our [API reference](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html#/s:13THEOplayerSDK0A0C15requestBuffered17completionHandleryySayAA9TimeRangeCGSg_s5Error_pSgtc_tF).
-
-### Live button
-
-A stream is a live stream when your `duration` property (or method) returns `Infinity`.
-If you want to implement a button that takes you to the "most live point" when clicked,
-then you set `currentTime` to the maximum `seekable` `end` time.
-
-### Audio change component
-
-Refer to the article on ["how to detect audio tracks"](../media-tracks/detect-audio-tracks.mdx)
-to know how to detect the available audio tracks. You'll need this article to know which audio tracks are part of your stream.
-
-Refer to the article on ["how to enable and disable audio tracks"](../media-tracks/enable-disable-audio-tracks.mdx)
-to know how to enable or disable another audio track. You'll need this article to enable another audio track.
-
-Refer to the article on ["how to detect audio track changes"](../media-tracks/detect-audio-track-changes.mdx)
-to know how to detect when an audio track has been enabled or disabled. You'll need this article to correctly annotate your UI.
-
-### Subtitle change component
-
-Refer to the article on ["how to detect text tracks"](../text-tracks/detect-text-tracks.mdx)
-to know how to detect the available text tracks. You'll need this article to know which subtitles and closed captions are part of your stream.
-
-Refer to the article on ["how to enable and disable text tracks"](../text-tracks/enable-disable-text-tracks.mdx)
-to know how to enable or disable another text track.
-
-Refer to the article on ["how to detect text track changes"](../text-tracks/detect-text-track-changes.mdx)
-to know how to detect when a text track has been enabled or disabled. You'll need this article to correctly annotate your UI.
-
-### Video quality change component
-
-Refer to the article on ["how to detect video track qualities"](../media-tracks/detect-video-track-qualities.mdx)
-to know how to detect the available video track qualities. You'll need this article to know which video qualities are part of your stream.
-
-Refer to the article on ["how to select video track quality"](../media-tracks/select-video-track-quality.mdx)
-to know how to enable another video track quality.
-
-Refer to the article on ["how to detect video track quality changes"](../media-tracks/detect-video-track-quality-changes.mdx)
-to know how to detect when a specific video track quality has become active. You'll need this article to correctly annotate your UI.
-
-### Fullscreen and inline button
-
-You may use the [`presentationMode`](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html#/s:13THEOplayerSDK0A0C16presentationModeAA012PresentationD0Ovp) property of the `player` instance, as demonstrated in the snippet below.
-
-```swift
-if (player.presentationMode == PresentationMode.fullscreen) {
- player.presentationMode = PresentationMode.inline
-} else {
- player.presentationMode = PresentationMode.fullscreen
-}
-```
-
-You may also use [`fullscreenOrientationCoupling`](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html#/s:13THEOplayerSDK0A0C29fullscreenOrientationCouplingSbvp)
-to automatically enter fullscreen when the viewer goes into landscape mode.
-
-Forcing the video player to rotate into landscape when you hit the fullscreen button in portrait mode is something
-that you need to implement on top of THEOplayer. (For example through a combination of [`UIDevice`](https://developer.apple.com/documentation/uikit/uidevice) and [`UIInterfaceOrientation`](https://developer.apple.com/documentation/uikit/uiinterfaceorientation).)
-
-Do note that when you leverage our `presentationMode` you must add your custom components as subviews of the `THEOplayerView`,
-because your components won't remain visible otherwise.
-In other words, you'll have to identify the appropriate subview X of the view Y to which you have (indirectly) added your `player` instance as a subview X.
-(You do this by querying the subviews of view Y.)
-
-You may also implement fullscreen management on top of THEOplayer.
-This is worth considering if you want more control and flexibility.
-
-### Picture-in-picture button
-
-You should implement your Picture-in-Picture UI and UX independently of THEOplayer,
-regardless of whether you're considering "in-app" picture-in-picture or "out-of-app" picture-in-picture.
-The [THEOplayer Picture-in-Picture API](../miscellaneous/picture-in-picture.mdx) is not available for chromeless players.
-
-Related resources:
-
-- [https://developers.google.com/web/updates/2017/09/picture-in-picture](https://developers.google.com/web/updates/2017/09/picture-in-picture)
-- [https://developer.apple.com/documentation/webkitjs/adding_picture_in_picture_to_your_safari_media_controls](https://developer.apple.com/documentation/webkitjs/adding_picture_in_picture_to_your_safari_media_controls)
-- [https://developer.android.com/guide/topics/ui/picture-in-picture](https://developer.android.com/guide/topics/ui/picture-in-picture)
-- [https://developer.apple.com/documentation/avkit/adopting_picture_in_picture_in_a_custom_player](https://developer.apple.com/documentation/avkit/adopting_picture_in_picture_in_a_custom_player)
-
-Note that it might not be possible to implement out-of-app Picture-in-Picture on the THEOplayer iOS SDK.
-
-### Chromecast button
-
-Refer to our [introduction on Chromecast](../cast/chromecast/introduction.mdx) to know how to track the availability of Chromecast,
-and how to start and stop a Chromecast session.
-
-### AirPlay button
-
-Refer to our [introduction on AirPlay](../cast/airplay/introduction.mdx) to know how to track the availability of AirPlay,
-and how to start and stop an AirPlay session.
-
-### Subtitle cues
-
-You may still leverage THEOplayer's default rendering of subtitles (and closed captions) in your chromeless UI.
-
-So what's the alternative? Instead of using THEOplayer's default rendering,
-you can programmatically detect when a subtitle (and closed captions) cue should appear and disappear,
-as explained in ["how to detect active text track cues"](../text-tracks/detect-active-text-track-cues.mdx).
-You could insert the cue when it should appear, and remove it when it should disappear.
-This alternative makes you fully responsible for the rendering and styling, and gives you total control over it.
-
-### Advertisement metadata
-
-When playing back advertisements, you might want to overlay a countdown, show a skip button after some seconds,
-insert ad markers in the scrub bar, and achieve other use cases.
-
-If you use [Google IMA](../ads/google-ima.mdx) for client-side ad-insertion,
-then this integration might already take care of some default UI customization.
-
-If you are using THEOplayer's [default ad integration](../ads/set-up-vast-and-vmap.mdx) for client-side ad-insertion,
-then you need to [subscribe to the appropriate ad events](../ads/subscribe-to-ad-events.mdx),
-and apply your UI and UX in the callbacks of these events.
-
-Similarly, if you're doing server-side ad-insertion, you also need to apply your UI and UX in the callbacks of your ad events.
-
-## Sample code
-
-The GitHub project at [https://github.com/THEOplayer/samples-ios-sdk/tree/master/Custom-UI](https://github.com/THEOplayer/samples-ios-sdk/tree/master/Custom-UI)
-provides a basic implementation of a chromeless UI on the iOS SDK.
-
-
-
-## Error handling
-
-A UI should also be capable of handling errors and informing the viewer.
-Refer to our [introduction on errors](../miscellaneous/error/introduction.mdx) to further explore this topic.
+## Next steps
+
+
diff --git a/theoplayer/how-to-guides/ios/ui/chromeless/error-handling.mdx b/theoplayer/how-to-guides/ios/ui/chromeless/error-handling.mdx
new file mode 100644
index 000000000000..946bef296292
--- /dev/null
+++ b/theoplayer/how-to-guides/ios/ui/chromeless/error-handling.mdx
@@ -0,0 +1,11 @@
+---
+sidebar_label: Error handling
+---
+
+# Error handling in a chromeless UI on iOS and tvOS
+
+A chromeless UI must present its own error state because the SDK does not render controls or viewer-facing error messages for you.
+
+Decide how to present recoverable and terminal failures, whether viewers can retry, and which details should be retained for diagnostics. Clear loading indicators when an error occurs so the interface does not appear to buffer indefinitely.
+
+See the [iOS and tvOS error-handling guides](../../miscellaneous/error/introduction.mdx) to detect Player errors and map them to messages and recovery actions.
diff --git a/theoplayer/how-to-guides/ios/ui/chromeless/introduction.mdx b/theoplayer/how-to-guides/ios/ui/chromeless/introduction.mdx
new file mode 100644
index 000000000000..06ea429ce072
--- /dev/null
+++ b/theoplayer/how-to-guides/ios/ui/chromeless/introduction.mdx
@@ -0,0 +1,12 @@
+---
+slug: /how-to-guides/ios/ui/chromeless/
+sidebar_label: Introduction
+---
+
+# Chromeless UI on iOS and tvOS
+
+A chromeless player renders video without playback controls. Your application creates every control with native Apple UI technologies and connects each interaction to the OptiView Player API.
+
+Choose this approach when you need complete control over the interface. Building from scratch requires an understanding of playback states, tracks, accessibility, errors, casting, presentation modes, and application lifecycle behavior.
+
+Continue with [Getting started](../build-chromeless-ui.mdx) to create a Player instance and connect it to your interface.
diff --git a/theoplayer/how-to-guides/ios/ui/chromeless/mapping-components.mdx b/theoplayer/how-to-guides/ios/ui/chromeless/mapping-components.mdx
new file mode 100644
index 000000000000..331d29b48f7a
--- /dev/null
+++ b/theoplayer/how-to-guides/ios/ui/chromeless/mapping-components.mdx
@@ -0,0 +1,56 @@
+---
+sidebar_label: Mapping components
+---
+
+# Mapping components in a chromeless UI on iOS and tvOS
+
+A chromeless UI is made up of native controls and displays that must reflect player state and call the appropriate OptiView Player APIs. This guide maps common components to the APIs and supporting guides used to implement them.
+
+
+
+## Play and pause
+
+Show the appropriate control for the current state, as described in [tracking player states](../../player/track-player-states.mdx). Call [`play()`]() or [`pause()`]() when the viewer selects it.
+
+## Mute and volume
+
+Use the Player's [`muted`](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html#/s:13THEOplayerSDK0A0C5mutedSbvp) property for mute controls. Apple platforms delegate volume-level changes to hardware controls, so the application should not provide an independent software volume slider.
+
+## Current time and duration
+
+Use [`requestCurrentTime()`](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html#/s:13THEOplayerSDK0A0C18requestCurrentTime17completionHandleryySdSg_s5Error_pSgtc_tF) and [`setCurrentTime()`](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html#/s:13THEOplayerSDK0A0C14setCurrentTime_17completionHandlerySd_yypSg_s5Error_pSgtcSgtF) for the playback position. Use [`duration`](pathname:///theoplayer/v11/api-reference/ios/Classes/THEOplayer.html#/s:13THEOplayerSDK0A0C8durationSdSgvp) for duration.
+
+For live streams, `duration` is `Infinity`. Use `currentProgramDateTime` when the interface needs an absolute program time.
+
+## Scrub bar and buffered ranges
+
+Only seek within the ranges exposed by `seekable`. Update the scrubber in response to [`TIME_UPDATE`](pathname:///theoplayer/v11/api-reference/ios/Structs/PlayerEventTypes.html#/s:13THEOplayerSDK16PlayerEventTypesV11TIME_UPDATEAA0D4TypeCyAA010TimeUpdateD0CGvpZ), and represent downloaded portions using the Player's buffered ranges.
+
+Display a loading state between seeking and seek completion when appropriate.
+
+## Audio, subtitle, and quality selection
+
+Use the platform guides to build track selectors:
+
+- [Detect audio tracks](../../media-tracks/detect-audio-tracks.mdx)
+- [Enable and disable audio tracks](../../media-tracks/enable-disable-audio-tracks.mdx)
+- [Detect text tracks](../../text-tracks/detect-text-tracks.mdx)
+- [Enable and disable text tracks](../../text-tracks/enable-disable-text-tracks.mdx)
+- [Detect video-track qualities](../../media-tracks/detect-video-track-qualities.mdx)
+- [Select a video-track quality](../../media-tracks/select-video-track-quality.mdx)
+
+## Fullscreen and picture-in-picture
+
+Use `presentationMode` to switch between inline and fullscreen modes. Keep custom controls within the Player view hierarchy so they remain visible during presentation changes. Use `fullscreenOrientationCoupling` when fullscreen should follow device orientation.
+
+You can also implement presentation handling independently when the application needs more control. Picture-in-picture availability and behavior depend on the target Apple platform; see the [picture-in-picture guide](../../miscellaneous/picture-in-picture.mdx).
+
+## Casting
+
+Use the [Chromecast guide](../../cast/chromecast/introduction.mdx) and [AirPlay guide](../../cast/airplay/introduction.mdx) to detect availability and start or stop casting sessions.
+
+## Subtitle and advertisement overlays
+
+You can use the SDK's subtitle rendering or [detect active text-track cues](../../text-tracks/detect-active-text-track-cues.mdx) and render them yourself.
+
+For advertising controls such as countdowns, skip buttons, and scrub-bar markers, subscribe to the relevant [ad events](../../ads/subscribe-to-ad-events.mdx) and update your interface from their callbacks.
diff --git a/theoplayer/how-to-guides/ios/ui/chromeless/ux-enhancements.mdx b/theoplayer/how-to-guides/ios/ui/chromeless/ux-enhancements.mdx
new file mode 100644
index 000000000000..c878a8a55d3a
--- /dev/null
+++ b/theoplayer/how-to-guides/ios/ui/chromeless/ux-enhancements.mdx
@@ -0,0 +1,16 @@
+---
+sidebar_label: UX enhancements
+---
+
+# UX enhancements for a chromeless UI on iOS and tvOS
+
+A functional player still needs clear feedback and convenient interactions. Plan these experiences alongside the core playback controls:
+
+1. **Loading spinner:** Indicate when the player is waiting for video data.
+2. **Poster:** Show an image before initial playback and after the video ends.
+3. **Up next:** Offer the next stream near the end of playback and optionally start it automatically.
+4. **Skip intro:** Let viewers skip the current introduction.
+5. **Ad countdown:** Display the remaining duration of an ad break.
+6. **Ad markers:** Indicate ad-break positions on the scrub bar.
+
+Drive each enhancement from Player events and state. Start with [tracking player states](../../player/track-player-states.mdx), then account for application lifecycle and presentation-mode transitions.
diff --git a/theoplayer/how-to-guides/ios/ui/introduction.mdx b/theoplayer/how-to-guides/ios/ui/introduction.mdx
index 6439dcf7a3ee..6ba6e50cdb05 100644
--- a/theoplayer/how-to-guides/ios/ui/introduction.mdx
+++ b/theoplayer/how-to-guides/ios/ui/introduction.mdx
@@ -9,17 +9,22 @@ import Intro from '../../shared/ui/_introduction-intro.mdx';
-## Implement a chromeless UI
+## Open Video UI
-As of THEOplayer 5, the iOS SDK no longer ships a default UI.
-You implement your UI on top of THEOplayer through the native technologies and programming languages
-of the platform. The THEOplayer API exposes all the events and properties that you need to implement a custom design.
+If you're building a React Native application, you can customize the player with
+[Open Video UI for React Native](/theoplayer/ui/react-native/open-video-ui/),
+a set of ready-made, open-source components which you can use as is or compose and style to match your application.
+
+## Chromeless
+
+For complete control, use the chromeless player and build every control and interaction with the native technologies
+and programming languages of the platform. The OptiView Player API exposes all the events and properties that you need to implement a custom design from scratch.
Refer to our article on [how to build a chromeless UI](build-chromeless-ui.mdx) for more information.
-If you're building a React Native application, you can use
-[Open Video UI for React Native](/open-video-ui/react-native/),
-a set of open-source UI components which you can use as is, or compose and style to build your own UI.
+## Default UI
+
+As of THEOplayer 5, the iOS SDK no longer ships a default UI.
## Related articles
diff --git a/theoplayer/how-to-guides/react-native/ui/chromeless/getting-started.mdx b/theoplayer/how-to-guides/react-native/ui/chromeless/getting-started.mdx
new file mode 100644
index 000000000000..4f42d8fa8b7d
--- /dev/null
+++ b/theoplayer/how-to-guides/react-native/ui/chromeless/getting-started.mdx
@@ -0,0 +1,19 @@
+---
+sidebar_label: Getting started
+---
+
+# Getting started with a chromeless UI on React Native
+
+First, follow the [React Native SDK getting-started guide](/theoplayer/getting-started/frameworks/react-native/getting-started/) to install `react-native-theoplayer` and render a minimal `THEOplayerView`.
+
+Do not add `@theoplayer/react-native-ui` when you want a chromeless implementation. Instead:
+
+1. Obtain the Player instance exposed by `THEOplayerView`.
+2. Subscribe to playback events and store the state required by your interface.
+3. Render your own React Native controls over or around the video view.
+4. Call Player methods from those controls.
+5. Handle loading, errors, accessibility, and platform lifecycle changes in your application.
+
+Start with play and pause controls, then add seeking, tracks, fullscreen behavior, casting, and advertising controls as your product requires.
+
+If you prefer ready-made components, use [Open Video UI for React Native](../open-video-ui/introduction.mdx).
diff --git a/theoplayer/how-to-guides/react-native/ui/chromeless/introduction.mdx b/theoplayer/how-to-guides/react-native/ui/chromeless/introduction.mdx
new file mode 100644
index 000000000000..51d0692d0528
--- /dev/null
+++ b/theoplayer/how-to-guides/react-native/ui/chromeless/introduction.mdx
@@ -0,0 +1,12 @@
+---
+slug: /how-to-guides/react-native/ui/chromeless/
+sidebar_label: Introduction
+---
+
+# Chromeless UI on React Native
+
+A chromeless React Native integration renders the `THEOplayerView` without adding the Open Video UI package. Your application creates the controls and connects them directly to the Player exposed by the view.
+
+Choose this approach when you need complete control over the interface or cannot use the ready-made React Native components. Your implementation must account for playback state, platform differences, accessibility, lifecycle changes, and errors.
+
+Continue with [Getting started](getting-started.mdx) for the basic setup.
diff --git a/theoplayer/how-to-guides/react-native/ui/introduction.mdx b/theoplayer/how-to-guides/react-native/ui/introduction.mdx
new file mode 100644
index 000000000000..b7730bfcd35d
--- /dev/null
+++ b/theoplayer/how-to-guides/react-native/ui/introduction.mdx
@@ -0,0 +1,22 @@
+---
+sidebar_position: 0
+sidebar_label: Introduction
+---
+
+# UI on React Native
+
+import Intro from '../../shared/ui/_introduction-intro.mdx';
+
+
+
+## Open Video UI
+
+Use [Open Video UI for React Native](open-video-ui/introduction.mdx) to customize the player with ready-made, open-source components that you can compose and style to match your application.
+
+## Chromeless
+
+For complete control, build every control and interaction with React Native components and connect them directly to the OptiView Player API.
+
+## Default UI
+
+The React Native SDK does not ship a default UI.
diff --git a/theoplayer/how-to-guides/react-native/ui/open-video-ui/introduction.mdx b/theoplayer/how-to-guides/react-native/ui/open-video-ui/introduction.mdx
new file mode 100644
index 000000000000..df15f5641445
--- /dev/null
+++ b/theoplayer/how-to-guides/react-native/ui/open-video-ui/introduction.mdx
@@ -0,0 +1,15 @@
+---
+slug: /how-to-guides/react-native/ui/open-video-ui/
+sidebar_label: Introduction
+---
+
+# Open Video UI for React Native
+
+import Intro from '../../../shared/ui/_open-video-ui-intro.mdx';
+import RebrandingNotice from '../../../../callouts/_rebranding_notice.md';
+import DocCardList from '@theme/DocCardList';
+
+
+
+
+
diff --git a/theoplayer/how-to-guides/roku/ui/build-chromeless-ui.mdx b/theoplayer/how-to-guides/roku/ui/build-chromeless-ui.mdx
index c0a861b1bd4f..40581e61b677 100644
--- a/theoplayer/how-to-guides/roku/ui/build-chromeless-ui.mdx
+++ b/theoplayer/how-to-guides/roku/ui/build-chromeless-ui.mdx
@@ -10,7 +10,7 @@ import UXEnhancements from '../../shared/ui/_build-chromeless-ui-ux-enhancements
-This section will give you an overview on how custom controls can be integrated with THEOplayer API and also a brief introduction to BrightScript and SceneGraph.
+This section will give you an overview on how custom controls can be integrated with the OptiView Player API and also a brief introduction to BrightScript and SceneGraph.
We will create play, pause, stop buttons, add audio and text tracks management menu and create a simple timeline.
## Display chromeless player
diff --git a/theoplayer/how-to-guides/roku/ui/chromeless/introduction.mdx b/theoplayer/how-to-guides/roku/ui/chromeless/introduction.mdx
new file mode 100644
index 000000000000..081ae4ea9f1f
--- /dev/null
+++ b/theoplayer/how-to-guides/roku/ui/chromeless/introduction.mdx
@@ -0,0 +1,12 @@
+---
+slug: /how-to-guides/roku/ui/chromeless/
+sidebar_label: Introduction
+---
+
+# Chromeless UI on Roku
+
+A chromeless Roku player disables the native video controls and implements the complete interface with BrightScript and SceneGraph components.
+
+Choose this approach when the native Roku controls do not meet your layout, branding, focus-management, or track-selection requirements. Your application becomes responsible for all controls, playback feedback, remote interactions, and errors.
+
+Continue with [Getting started](../build-chromeless-ui.mdx) for the Roku implementation walkthrough.
diff --git a/theoplayer/how-to-guides/roku/ui/default-ui/getting-started.mdx b/theoplayer/how-to-guides/roku/ui/default-ui/getting-started.mdx
new file mode 100644
index 000000000000..53465e1fc55c
--- /dev/null
+++ b/theoplayer/how-to-guides/roku/ui/default-ui/getting-started.mdx
@@ -0,0 +1,15 @@
+---
+sidebar_label: Getting started
+---
+
+# Getting started with the default UI on Roku
+
+The Roku SDK displays native controls when the `controls` field on the `THEOplayer` node is enabled. It is enabled by default, or you can set it explicitly:
+
+```xml
+
+```
+
+Configure the Player and set a source as described in the [Roku SDK getting-started guide](/theoplayer/getting-started/sdks/roku/getting-started/). Roku renders its native playback controls when playback begins.
+
+Use the [default UI how-to guide](../remove-ui-element.mdx) to remove individual controls. Set `controls` to `false` if you want to build a [chromeless UI](../chromeless/introduction.mdx).
diff --git a/theoplayer/how-to-guides/roku/ui/default-ui/introduction.mdx b/theoplayer/how-to-guides/roku/ui/default-ui/introduction.mdx
new file mode 100644
index 000000000000..d16b3c491a8f
--- /dev/null
+++ b/theoplayer/how-to-guides/roku/ui/default-ui/introduction.mdx
@@ -0,0 +1,12 @@
+---
+slug: /how-to-guides/roku/ui/default-ui/
+sidebar_label: Introduction
+---
+
+# Default UI on Roku
+
+The OptiView Player Roku SDK uses the controls provided by Roku's native video node. Use this UI when the platform-native playback experience meets your requirements.
+
+You can show the complete control set, remove individual native elements, or disable the controls and build a chromeless SceneGraph interface.
+
+Continue with [Getting started](getting-started.mdx) to enable the native controls.
diff --git a/theoplayer/how-to-guides/roku/ui/introduction.mdx b/theoplayer/how-to-guides/roku/ui/introduction.mdx
index b1ca32f03bb5..683af27b9cc7 100644
--- a/theoplayer/how-to-guides/roku/ui/introduction.mdx
+++ b/theoplayer/how-to-guides/roku/ui/introduction.mdx
@@ -9,12 +9,14 @@ import Intro from '../../shared/ui/_introduction-intro.mdx';
-## Default UI versus chromeless UI
+## Open Video UI
-The Roku SDK ships a default UI, which renders the controls of the `THEOplayer` node.
-You may use this UI as is, hide individual elements of it, or hide it entirely and build your own chromeless UI.
+Open Video UI does not currently provide a Roku component library.
-## Related articles
+## Chromeless
-- [How to remove an element from the UI](remove-ui-element.mdx)
-- [How to build a chromeless UI](build-chromeless-ui.mdx)
+Disable the native controls and build a complete interface with BrightScript and SceneGraph when you need full control over the experience.
+
+## Default UI
+
+The Roku SDK uses the native controls of the `THEOplayer` node. You can use these controls as they are or hide individual elements.
diff --git a/theoplayer/how-to-guides/shared/ads/_customizing-the-ad-overlay-text-remarks.mdx b/theoplayer/how-to-guides/shared/ads/_customizing-the-ad-overlay-text-remarks.mdx
index f60ad79a0e7d..d6c655536b97 100644
--- a/theoplayer/how-to-guides/shared/ads/_customizing-the-ad-overlay-text-remarks.mdx
+++ b/theoplayer/how-to-guides/shared/ads/_customizing-the-ad-overlay-text-remarks.mdx
@@ -1,2 +1,2 @@
-- If you are using [THEOplayer Open Video UI](https://www.theoplayer.com/product/open-video-ui), there could be alternative ways to edit certain elements depending on the platform and the ad integration kind used. For reference, you can find a demo for the `csai` ad integration on Web SDK [here](https://www.theoplayer.com/docs/open-video-ui/web/examples/ads/).
+- If you customize OptiView Player with [Open Video UI](/theoplayer/ui/web/open-video-ui/), there may be other ways to edit certain elements depending on the platform and ad integration. See the [Web SDK CSAI example](/theoplayer/ui/web/open-video-ui/examples/ads/) for reference.
- The `Why this ad?` text or the `?` (question mark) icon that may appear while using the Google IMA/DAI integration is inserted by the IMA SDK itself and is required to be displayed with any ad that was not manually selected. The icon is rendered as a VAST icon and is automatically generated by Ad Manager where required.
diff --git a/theoplayer/how-to-guides/shared/ui/_introduction-intro.mdx b/theoplayer/how-to-guides/shared/ui/_introduction-intro.mdx
index 093a61188218..19e4e91becfd 100644
--- a/theoplayer/how-to-guides/shared/ui/_introduction-intro.mdx
+++ b/theoplayer/how-to-guides/shared/ui/_introduction-intro.mdx
@@ -1,8 +1,15 @@
-THEOplayer lets you build the video player UI that fits your application.
-You can use a ready-made UI and customize it, or build a brand-new chromeless UI from scratch.
+Choose the approach that fits your requirements:
-Building a chromeless UI means building a new UI from scratch using the THEOplayer API and custom application code.
-In other words: you are responsible for inserting your own controls (e.g. a play button),
-and connecting them with the THEOplayer API (e.g. `player.play()`).
-A chromeless UI gives you total control over your UI and UX,
-but it requires an understanding of video playback and of the THEOplayer API.
+- Use Open Video UI when you want a custom experience without building common player components yourself.
+- Use the chromeless player when you want to start with no UI and build every control and interaction from scratch.
+- Use the basic default UI when its ready-made controls meet your needs and one is available.
+
+| Approach | Starting point | Flexibility | Development effort |
+| ------------- | ------------------------------ | ----------- | ------------------ |
+| Open Video UI | Ready-made, modular components | High | Moderate |
+| Chromeless | Player API without a UI | Complete | Highest |
+| Default UI | Complete basic player UI | Basic | Lowest |
+
+Building a chromeless UI means using the OptiView Player API and your own application code without a ready-made UI.
+You are responsible for adding every control, such as a play button, and connecting it to the player API, such as `player.play()`.
+This approach gives you total control over the UI and UX, but requires an understanding of video playback and the OptiView Player API.
diff --git a/theoplayer/how-to-guides/shared/ui/_open-video-ui-intro.mdx b/theoplayer/how-to-guides/shared/ui/_open-video-ui-intro.mdx
new file mode 100644
index 000000000000..079b820e4c54
--- /dev/null
+++ b/theoplayer/how-to-guides/shared/ui/_open-video-ui-intro.mdx
@@ -0,0 +1,3 @@
+Open Video UI is the OptiView Player customization toolkit. It provides open-source, out-of-the-box components that you can compose and style to create a player UI that matches your product and brand.
+
+Open Video UI has dedicated libraries for each supported platform, so your customized player feels native in your app. These pages explain how to get started and tailor the components to your requirements.
diff --git a/theoplayer/how-to-guides/web/text-tracks/preview-thumbnails.mdx b/theoplayer/how-to-guides/web/text-tracks/preview-thumbnails.mdx
index 82932aaea319..07965735d507 100644
--- a/theoplayer/how-to-guides/web/text-tracks/preview-thumbnails.mdx
+++ b/theoplayer/how-to-guides/web/text-tracks/preview-thumbnails.mdx
@@ -28,7 +28,7 @@ player.source = {
};
```
-If you use the [Open Video UI for Web](/open-video-ui/web/)
+If you use the [Open Video UI for Web](/theoplayer/ui/web/open-video-ui/)
or [THEOplayer's default UI](../ui/introduction.mdx),
the thumbnails are shown automatically when hovering or scrubbing the seek bar.
diff --git a/theoplayer/how-to-guides/web/ui/build-chromeless-ui.mdx b/theoplayer/how-to-guides/web/ui/build-chromeless-ui.mdx
index 8299ab5d8921..2fef1b145458 100644
--- a/theoplayer/how-to-guides/web/ui/build-chromeless-ui.mdx
+++ b/theoplayer/how-to-guides/web/ui/build-chromeless-ui.mdx
@@ -1,21 +1,18 @@
---
sidebar_position: 1
-sidebar_label: Build a chromeless UI
+sidebar_label: Getting started
---
-# How to build a chromeless UI on Web
+# Getting started with a chromeless UI on Web
-import styles from './shared.module.css';
+import DocCardList from '@theme/DocCardList';
import Intro from '../../shared/ui/_build-chromeless-ui-intro.mdx';
-import UXEnhancements from '../../shared/ui/_build-chromeless-ui-ux-enhancements.mdx';
-## Creating a chromeless player instance
+## Create a chromeless player instance
-Create a [`ChromelessPlayer`](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#constructor)
-instead of a `Player`. Unlike `Player`, a `ChromelessPlayer` doesn't come with a default UI,
-so you can build your own UI on top of it.
+Create a [`ChromelessPlayer`](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#constructor) instead of a `Player`. Unlike `Player`, a `ChromelessPlayer` doesn't render a default UI, so you can build your own UI on top of it.
```javascript
const element = document.querySelector('.theoplayer-container');
@@ -25,261 +22,41 @@ const player = new THEOplayer.ChromelessPlayer(element, {
});
```
-The rest of this article refers to this `player` variable.
+The following guides refer to this `player` variable.
-## Tracking transitions between states
+## Track player states
-Refer to the article on ["How to track player states"](../player/track-player-states.mdx) to advance your understanding
-on video player states. Understanding the video player lifecycle is a vital part of building a chromeless UI.
+Before adding controls, learn how to [track player states](../player/track-player-states.mdx). Understanding the playback lifecycle lets your UI respond correctly when playback starts, pauses, buffers, ends, or encounters an error.

-This article explains how to track the start of a video and its end, but also how to detect buffering, errors and much more.
-You'll need to implement (some of) these transitions in your chromeless UI in order to render the appropriate components.
-
-## Mapping components
-
-A video player UI can be dissected into different components (or controls).
-A component offers context, and it may also offer an action. The "play button" is an example of an action component,
-but the "current time text" (X in the screenshot below) is a context component.
-
-As a developer, you should understand which controls are out there, and which video player APIs are relevant.
-
-This section addresses the following components:
-
-1. Play button
-2. Pause button
-3. Volume mute button
-4. Volume change button
-5. Current time text
-6. Duration text
-7. Scrub bar
-8. Buffered blocks
-9. Live button
-10. Audio change component
-11. Subtitle change component
-12. Video quality change component
-13. Fullscreen and inline button
-14. Picture-in-picture button
-15. Chromecast button
-16. AirPlay button
-
-Additionally, we'll discuss the following overlays:
-
-1. Subtitle cues
-2. Advertisement metadata
-
-
-
-Instead of providing inline code on this article, we'll refer to other articles as much as possible,
-because linking the THEOplayer API to your custom components is an application of many of the existing how-to guides
-for a specific use-case.
-
-If you know how to navigate our API references, you don't even need this section.
-The graphic below (originally referenced in ["custom analytics integration"](../analytics/custom-analytics-integration.mdx)) gives
-a basic overview of many of the relevant interfaces and events.
-
-
-
-### Play button
-
-You should show your play button when you are in a paused state, as described in ["how to track player states"](../player/track-player-states.mdx).
-If a viewer clicks your play button, you should call the `play()` on your `player` instance as documented in our
-[API reference](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#play).
-
-### Pause button
-
-You should show your pause button when you are in a playing state, as described in ["how to track player states"](../player/track-player-states.mdx).
-If a viewer clicks your pause button, you should call the `pause()` on your `player` instance as documented in our
-[API reference](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#pause).
-
-### Volume mute button
-
-You can check whether your volume is muted through the `muted` property (or method) on your `player` instance as documented in
-our [API reference](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#muted).
-You should consider showing a different button depending on whether `muted` returns `true` or `false`.
-If a viewer clicks your mute button, you should set `muted` to `!muted`.
-
-### Volume change button
-
-You can get and set your volume level through the `volume` property (or method) on your `player` instance as documented in
-our [API reference](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#volume).
-You should consider showing a different button depending on the volume level.
-
-### Current time text
-
-You can get the current time through the `currentTime` property (or method) on your `player` instance as documented in
-our [API reference](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#currentTime).
-
-Note that `currentTime` returns a relative value in seconds.
-If you are dealing with live streams, you might want to use `currentProgramDateTime` instead, as this returns an absolute value like `"2022-04-01T13:37:42.666Z"`.
-This property (or method) is especially useful when implementing an [EPG](https://en.wikipedia.org/wiki/Electronic_program_guide) experience.
-
-### Duration text
-
-You can get the duration of a stream through the `duration` property (or method) on your `player` instance as documented in our
-[API reference](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#duration).
-
-The `duration` will return the duration in seconds for VOD streams, and `Infinity` for live streams.
-
-You can calculate the remaining duration by subtracting the `currentTime` from the `duration`.
-
-### Scrub bar
-
-Related to the subsection on "Current time text",
-you can seek to a different playhead position through the `currentTime` property (or `setCurrentTime()` method) on your `player` instance.
-Alternatively, for live streams, you may also use `currentProgramDateTime` to seek to absolute playhead positions.
-
-You can only seek to a playhead position that is within any of the time ranges of your `seekable` property (or method) of your `player` instance as documented in our
-[API reference](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#seekable).
-For example, on the Web SDK, this means that you'll stay between `player.seekable.start(0)` and `player.seekable.end(player.seekable.length-1)`.
-
-You subscribe to the `timeupdate` event to periodically update your scrub bar bullet.
-This event is dispatched every ~200ms during playback.
-Refer to our [API reference](pathname:///theoplayer/v11/api-reference/web/interfaces/PlayerEventMap.html#timeupdate) for more info on this event.
-
-A `seek` event is dispatched when you set a new value for `currentTime` or `currentProgramDateTime`.
-A `seeked` event is dispatched when the seek was successful.
-Refer to our [API reference](pathname:///theoplayer/v11/api-reference/web/interfaces/PlayerEventMap.html#seeking) for more info on these events.
-You should consider displaying a "stalling icon" between these two events.
-
-#### Buffered blocks
-
-You may also want to annotate parts of the scrub bar that have already been buffered.
-When the viewer seeks to a buffered block playback immediately starts.
-
-You can track information on what's being buffered through the `progress` event.
-Refer to our [API reference](pathname:///theoplayer/v11/api-reference/web/interfaces/PlayerEventMap.html#progress) for more info on this event.
-In the callback of the `progress` event,
-you will want to query the `buffered` property (or method) to iterate through the available buffered time ranges.
-The `buffered` property (or method) is described in our [API reference](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#buffered).
-
-### Live button
-
-A stream is a live stream when your `duration` property (or method) returns `Infinity`.
-If you want to implement a button that takes you to the "most live point" when clicked,
-then you set `currentTime` to the maximum `seekable` `end` time.
-For example, on the Web SDK, you would call `player.currentTime = player.seekable.end(player.seekable.length-1)`.
-
-### Audio change component
-
-Refer to the article on ["how to detect audio tracks"](../media-tracks/detect-audio-tracks.mdx)
-to know how to detect the available audio tracks. You'll need this article to know which audio tracks are part of your stream.
-
-Refer to the article on ["how to enable and disable audio tracks"](../media-tracks/enable-disable-audio-tracks.mdx)
-to know how to enable or disable another audio track. You'll need this article to enable another audio track.
-
-Refer to the article on ["how to detect audio track changes"](../media-tracks/detect-audio-track-changes.mdx)
-to know how to detect when an audio track has been enabled or disabled. You'll need this article to correctly annotate your UI.
-
-### Subtitle change component
-
-Refer to the article on ["how to detect text tracks"](../text-tracks/detect-text-tracks.mdx)
-to know how to detect the available text tracks. You'll need this article to know which subtitles and closed captions are part of your stream.
-
-Refer to the article on ["how to enable and disable text tracks"](../text-tracks/enable-disable-text-tracks.mdx)
-to know how to enable or disable another text track.
-
-Refer to the article on ["how to detect text track changes"](../text-tracks/detect-text-track-changes.mdx)
-to know how to detect when a text track has been enabled or disabled. You'll need this article to correctly annotate your UI.
-
-### Video quality change component
-
-Refer to the article on ["how to detect video track qualities"](../media-tracks/detect-video-track-qualities.mdx)
-to know how to detect the available video track qualities. You'll need this article to know which video qualities are part of your stream.
-
-Refer to the article on ["how to select video track quality"](../media-tracks/select-video-track-quality.mdx)
-to know how to enable another video track quality.
-
-Refer to the article on ["how to detect video track quality changes"](../media-tracks/detect-video-track-quality-changes.mdx)
-to know how to detect when a specific video track quality has become active. You'll need this article to correctly annotate your UI.
-
-### Fullscreen and inline button
-
-Getting your video player in and out fullscreen requires some getting used to, and differs a bit across SDKs.
-
-You cannot use our [`Presentation API`](pathname:///theoplayer/v11/api-reference/web/interfaces/Presentation.html) to switch between fullscreen, inline and picture-in-picture.
-Instead, you need to implement your own fullscreen handling.
-
-One approach to achieve this is by using the `Fullscreen API` as described at [https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API).
-Additionally, to deal with iOS browsers, you can leverage [`webkitEnterFullscreen()`](https://developer.apple.com/documentation/webkitjs/htmlvideoelement/1633500-webkitenterfullscreen),
-or resize your video player container to a 100% width and height.
-
-### Picture-in-picture button
-
-You should implement your Picture-in-Picture UI and UX independently of THEOplayer,
-regardless of whether you're considering "in-app" picture-in-picture or "out-of-app" picture-in-picture.
-The [THEOplayer Picture-in-Picture API](../miscellaneous/picture-in-picture.mdx) is not available for chromeless players.
-
-To get the active video element on the THEOplayer Web SDK you may query `player.element.querySelectorAll('video[src]')[0]`.
-
-Related resources:
-
-- [https://developers.google.com/web/updates/2017/09/picture-in-picture](https://developers.google.com/web/updates/2017/09/picture-in-picture)
-- [https://developer.apple.com/documentation/webkitjs/adding_picture_in_picture_to_your_safari_media_controls](https://developer.apple.com/documentation/webkitjs/adding_picture_in_picture_to_your_safari_media_controls)
-- [https://developer.android.com/guide/topics/ui/picture-in-picture](https://developer.android.com/guide/topics/ui/picture-in-picture)
-- [https://developer.apple.com/documentation/avkit/adopting_picture_in_picture_in_a_custom_player](https://developer.apple.com/documentation/avkit/adopting_picture_in_picture_in_a_custom_player)
-
-### Chromecast button
-
-Refer to our [introduction on Chromecast](../cast/chromecast/introduction.mdx) to know how to track the availability of Chromecast,
-and how to start and stop a Chromecast session.
-
-### AirPlay button
-
-Refer to our [introduction on AirPlay](../cast/airplay/introduction.mdx) to know how to track the availability of AirPlay,
-and how to start and stop an AirPlay session.
-
-### Subtitle cues
-
-You may still leverage THEOplayer's default rendering of subtitles (and closed captions) in your chromeless UI.
-This may require some extra styling though, depending on your SDK.
-For example, on the Web SDK, you may have to set a default `font-size` through CSS, as demonstrated in the snippet below.
-
-```css
-.theoplayer-texttracks * {
- font-size: 1em !important;
-}
-```
-
-So what's the alternative? Instead of using THEOplayer's default rendering,
-you can programmatically detect when a subtitle (and closed captions) cue should appear and disappear,
-as explained in ["how to detect active text track cues"](../text-tracks/detect-active-text-track-cues.mdx).
-You could insert the cue when it should appear, and remove it when it should disappear.
-This alternative makes you fully responsible for the rendering and styling, and gives you total control over it.
-
-### Advertisement metadata
-
-When playing back advertisements, you might want to overlay a countdown, show a skip button after some seconds,
-insert ad markers in the scrub bar, and achieve other use cases.
-
-If you use [Google IMA](../ads/google-ima.mdx) for client-side ad-insertion,
-then this integration might already take care of some default UI customization.
-
-If you are using THEOplayer's [default ad integration](../ads/set-up-vast-and-vmap.mdx) for client-side ad-insertion,
-then you need to [subscribe to the appropriate ad events](../ads/subscribe-to-ad-events.mdx),
-and apply your UI and UX in the callbacks of these events.
-
-Similarly, if you're doing server-side ad-insertion, you also need to apply your UI and UX in the callbacks of your ad events.
-
-## Sample code
-
-The sample code at [https://jsfiddle.net/thijsl/1xbk9csq/1/](https://jsfiddle.net/thijsl/1xbk9csq/1/) may help you get bootstrapped on our Web SDK.
-(Note that this sample code doesn't necessarily demonstrate best practices.)
-
-
-
-
-
-## Error handling
-
-A UI should also be capable of handling errors and informing the viewer.
-Refer to our [introduction on errors](../miscellaneous/error/introduction.mdx) to further explore this topic.
+## Next steps
+
+
diff --git a/theoplayer/how-to-guides/web/ui/chromeless/error-handling.mdx b/theoplayer/how-to-guides/web/ui/chromeless/error-handling.mdx
new file mode 100644
index 000000000000..3bfb3df97dea
--- /dev/null
+++ b/theoplayer/how-to-guides/web/ui/chromeless/error-handling.mdx
@@ -0,0 +1,11 @@
+---
+sidebar_label: Error handling
+---
+
+# Error handling in a chromeless UI
+
+A chromeless UI must display its own error state because there is no default interface to inform the viewer when playback fails.
+
+Decide how your UI will present recoverable and terminal errors, whether viewers can retry, and which technical details should remain available for diagnostics. Clear any loading state when an error occurs so the player does not appear to buffer indefinitely.
+
+See the [error-handling guides](../../miscellaneous/error/introduction.mdx) to detect Player errors and map them to messages and recovery actions in your interface.
diff --git a/theoplayer/how-to-guides/web/ui/chromeless/introduction.mdx b/theoplayer/how-to-guides/web/ui/chromeless/introduction.mdx
new file mode 100644
index 000000000000..3d627f1fb659
--- /dev/null
+++ b/theoplayer/how-to-guides/web/ui/chromeless/introduction.mdx
@@ -0,0 +1,16 @@
+---
+slug: /how-to-guides/web/ui/chromeless/
+sidebar_label: Introduction
+---
+
+# Chromeless UI on Web
+
+A chromeless player provides playback capabilities without rendering a user interface. Your application is responsible for creating every control, displaying player state, and connecting interactions to the OptiView Player API.
+
+Choose this approach when you need complete control over the UI and UX, cannot use Open Video UI components, or are targeting an environment that requires a fully bespoke implementation.
+
+Building from scratch requires a solid understanding of playback states, events, media tracks, accessibility, error handling, and platform-specific behavior.
+
+Some features are implemented on top of the default UI and are unavailable in a chromeless player. For example, the [Up Next](../../miscellaneous/up-next.mdx) feature and API depend on the default UI.
+
+Continue with [Getting started](../build-chromeless-ui.mdx) to create a `ChromelessPlayer` and map the first controls to the Player API.
diff --git a/theoplayer/how-to-guides/web/ui/chromeless/mapping-components.mdx b/theoplayer/how-to-guides/web/ui/chromeless/mapping-components.mdx
new file mode 100644
index 000000000000..eb916192c8c5
--- /dev/null
+++ b/theoplayer/how-to-guides/web/ui/chromeless/mapping-components.mdx
@@ -0,0 +1,144 @@
+---
+sidebar_label: Mapping components
+---
+
+# Mapping components in a chromeless UI
+
+A chromeless UI is made up of controls and displays that must reflect player state and call the appropriate OptiView Player APIs. This guide maps common interface components to the properties, methods, events, and supporting guides needed to implement them.
+
+A component can provide context, perform an action, or do both. For example, a play button performs an action, while a current-time display provides context.
+
+This guide covers:
+
+1. Play and pause
+2. Volume mute and level
+3. Current time and duration
+4. Scrubbing and buffered ranges
+5. Live playback
+6. Audio, subtitle, and quality selection
+7. Fullscreen and picture-in-picture
+8. Chromecast and AirPlay
+9. Subtitle and advertisement overlays
+
+
+
+The [Player API interfaces and events](../../analytics/custom-analytics-integration.mdx) provide the underlying state and actions used by these components.
+
+
+
+## Play button
+
+Show the play button while the player is paused, as described in [tracking player states](../../player/track-player-states.mdx). When a viewer selects it, call [`player.play()`](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#play).
+
+## Pause button
+
+Show the pause button while the player is playing, as described in [tracking player states](../../player/track-player-states.mdx). When a viewer selects it, call [`player.pause()`](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#pause).
+
+## Volume mute button
+
+Read and update the [`muted`](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#muted) property. Reflect the current value in the button and toggle it with `player.muted = !player.muted`.
+
+## Volume control
+
+Read and update the [`volume`](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#volume) property. Reflect the current level and muted state in the control.
+
+## Current-time display
+
+Read [`currentTime`](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#currentTime) to display the relative playback position in seconds.
+
+For live streams, you may prefer `currentProgramDateTime`, which provides an absolute value such as `"2022-04-01T13:37:42.666Z"`. This is also useful when implementing an electronic program guide.
+
+## Duration display
+
+Read [`duration`](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#duration). It returns the duration in seconds for video-on-demand streams and `Infinity` for live streams.
+
+Calculate the remaining duration by subtracting `currentTime` from `duration` for finite streams.
+
+## Scrub bar
+
+Seek by setting `currentTime`. For live streams, you can use `currentProgramDateTime` to seek to absolute playback positions.
+
+Only seek within the ranges exposed by [`seekable`](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#seekable). On Web, valid values remain between `player.seekable.start(0)` and `player.seekable.end(player.seekable.length - 1)`.
+
+Subscribe to [`timeupdate`](pathname:///theoplayer/v11/api-reference/web/interfaces/PlayerEventMap.html#timeupdate) to update the scrubber position during playback. The event is dispatched approximately every 200 milliseconds.
+
+The player dispatches `seeking` when a seek starts and `seeked` when it completes. Consider showing a loading state between these events.
+
+### Buffered ranges
+
+Use the `progress` event and [`buffered`](pathname:///theoplayer/v11/api-reference/web/classes/ChromelessPlayer.html#buffered) ranges to indicate which portions of the stream are already available for immediate playback.
+
+## Live button
+
+A stream is live when `duration` is `Infinity`. To move to the live edge, set `currentTime` to `player.seekable.end(player.seekable.length - 1)`.
+
+## Audio selection
+
+Use these guides to implement an audio-track selector:
+
+- [Detect audio tracks](../../media-tracks/detect-audio-tracks.mdx)
+- [Enable and disable audio tracks](../../media-tracks/enable-disable-audio-tracks.mdx)
+- [Detect audio-track changes](../../media-tracks/detect-audio-track-changes.mdx)
+
+## Subtitle selection
+
+Use these guides to implement a subtitle and closed-caption selector:
+
+- [Detect text tracks](../../text-tracks/detect-text-tracks.mdx)
+- [Enable and disable text tracks](../../text-tracks/enable-disable-text-tracks.mdx)
+- [Detect text-track changes](../../text-tracks/detect-text-track-changes.mdx)
+
+## Video quality selection
+
+Use these guides to implement a quality selector:
+
+- [Detect video-track qualities](../../media-tracks/detect-video-track-qualities.mdx)
+- [Select a video-track quality](../../media-tracks/select-video-track-quality.mdx)
+- [Detect video-track quality changes](../../media-tracks/detect-video-track-quality-changes.mdx)
+
+## Fullscreen button
+
+The [`Presentation API`](pathname:///theoplayer/v11/api-reference/web/interfaces/Presentation.html) is not available for switching a chromeless player between fullscreen, inline, and picture-in-picture modes. Implement fullscreen behavior with the browser [Fullscreen API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API).
+
+For iOS browsers, you can use [`webkitEnterFullscreen()`](https://developer.apple.com/documentation/webkitjs/htmlvideoelement/1633500-webkitenterfullscreen) or resize the player container to fill the viewport.
+
+## Picture-in-picture button
+
+Implement picture-in-picture UI and behavior independently of the Player SDK. The [Player Picture-in-Picture API](../../miscellaneous/picture-in-picture.mdx) is not available for chromeless players.
+
+On Web, you can locate the active video element with `player.element.querySelectorAll('video[src]')[0]`.
+
+Related resources:
+
+- [Picture-in-Picture for the Web](https://developers.google.com/web/updates/2017/09/picture-in-picture)
+- [Safari picture-in-picture controls](https://developer.apple.com/documentation/webkitjs/adding_picture_in_picture_to_your_safari_media_controls)
+- [Android picture-in-picture](https://developer.android.com/guide/topics/ui/picture-in-picture)
+- [Apple platform picture-in-picture](https://developer.apple.com/documentation/avkit/adopting_picture_in_picture_in_a_custom_player)
+
+## Chromecast button
+
+Use the [Chromecast guide](../../cast/chromecast/introduction.mdx) to detect availability and start or stop a casting session.
+
+## AirPlay button
+
+Use the [AirPlay guide](../../cast/airplay/introduction.mdx) to detect availability and start or stop an AirPlay session.
+
+## Subtitle cues
+
+You can retain the Player SDK's default subtitle and closed-caption rendering in a chromeless UI. Depending on your design, additional styling may be required:
+
+```css
+.theoplayer-texttracks * {
+ font-size: 1em !important;
+}
+```
+
+For complete rendering control, [detect active text-track cues](../../text-tracks/detect-active-text-track-cues.mdx), then insert and remove each cue in your own interface.
+
+## Advertisement metadata
+
+During advertisements, your UI may need to display a countdown, skip button, or ad markers on the scrub bar.
+
+When using [Google IMA](../../ads/google-ima.mdx), the integration may provide some interface elements. When using the Player SDK's [default client-side ad integration](../../ads/set-up-vast-and-vmap.mdx), subscribe to the relevant [ad events](../../ads/subscribe-to-ad-events.mdx) and update your UI in their callbacks.
+
+Apply the same event-driven approach to server-side ad insertion.
diff --git a/theoplayer/how-to-guides/web/ui/chromeless/sample-code.mdx b/theoplayer/how-to-guides/web/ui/chromeless/sample-code.mdx
new file mode 100644
index 000000000000..715d38b5fc58
--- /dev/null
+++ b/theoplayer/how-to-guides/web/ui/chromeless/sample-code.mdx
@@ -0,0 +1,23 @@
+---
+sidebar_label: Sample code
+---
+
+# Chromeless UI sample code on Web
+
+import styles from '../shared.module.css';
+
+This sample provides a small working chromeless player that you can use to explore the relationship between custom HTML controls and the OptiView Player API. Use it as a learning aid rather than a production-ready implementation.
+
+
+
+You can also [open the sample directly in JSFiddle](https://jsfiddle.net/thijsl/1xbk9csq/1/).
+
+Before extending the sample, review how to [map common UI components](mapping-components.mdx) and consider the recommended [UX enhancements](ux-enhancements.mdx).
diff --git a/theoplayer/how-to-guides/web/ui/chromeless/ux-enhancements.mdx b/theoplayer/how-to-guides/web/ui/chromeless/ux-enhancements.mdx
new file mode 100644
index 000000000000..80149dc9a08e
--- /dev/null
+++ b/theoplayer/how-to-guides/web/ui/chromeless/ux-enhancements.mdx
@@ -0,0 +1,18 @@
+---
+sidebar_label: UX enhancements
+---
+
+# UX enhancements for a chromeless UI
+
+A functional player still needs clear feedback and convenient interactions. Plan these experiences alongside the core playback controls so viewers always understand the current state and available actions.
+
+Common enhancements include:
+
+1. **Loading spinner:** Indicate when the player is waiting for video data.
+2. **Poster:** Show an image before initial playback and after the video ends.
+3. **Up next:** Near the end of playback, offer a way to open the next stream and optionally start it automatically.
+4. **Skip intro:** Let viewers skip the current introduction.
+5. **Ad countdown:** Display the remaining duration of the current ad break.
+6. **Ad markers:** Indicate ad-break positions on the scrub bar.
+
+Each enhancement should respond to Player events and state rather than relying on timers or visual state alone. Start with [tracking player states](../../player/track-player-states.mdx), then use the relevant playback and advertising APIs for each interaction.
diff --git a/theoplayer/how-to-guides/web/ui/default-ui/getting-started.mdx b/theoplayer/how-to-guides/web/ui/default-ui/getting-started.mdx
new file mode 100644
index 000000000000..0ab057429eb6
--- /dev/null
+++ b/theoplayer/how-to-guides/web/ui/default-ui/getting-started.mdx
@@ -0,0 +1,25 @@
+---
+sidebar_label: Getting started
+---
+
+# Getting started with the default UI on Web
+
+The default UI is included with the OptiView Player Web SDK. Follow the [Web SDK getting-started guide](../../../../getting-started/01-sdks/01-web/00-getting-started.mdx) to install the SDK and include its JavaScript and CSS files.
+
+Create a `Player` instance to enable the default UI:
+
+```javascript
+const element = document.querySelector('.theoplayer-container');
+const player = new THEOplayer.Player(element, {
+ libraryLocation: '/path/to/your-theoplayer-folder/',
+ license: 'your_license_string',
+});
+
+player.source = {
+ sources: [{ src: 'https://example.com/stream.m3u8' }],
+};
+```
+
+Use `THEOplayer.Player`, rather than `THEOplayer.ChromelessPlayer`, when you want the SDK to render its default controls.
+
+Next, explore the default UI how-to guides in the sidebar to change its appearance and behavior.
diff --git a/theoplayer/how-to-guides/web/ui/default-ui/introduction.mdx b/theoplayer/how-to-guides/web/ui/default-ui/introduction.mdx
new file mode 100644
index 000000000000..3facbf4d3c58
--- /dev/null
+++ b/theoplayer/how-to-guides/web/ui/default-ui/introduction.mdx
@@ -0,0 +1,20 @@
+---
+slug: /how-to-guides/web/ui/default-ui/
+sidebar_label: Introduction
+---
+
+# Default UI on Web
+
+The OptiView Player Web SDK includes a responsive default UI with standard playback controls such as play and pause, volume, seeking, language and quality selection, picture-in-picture, and fullscreen.
+
+Use the default UI when its existing layout and controls meet your requirements. You can adapt its appearance with CSS, hide controls, and add small extensions without implementing common player interactions yourself.
+
+The default UI is not optimized for big-screen devices such as Samsung Tizen, LG webOS, and Android TV. For those environments, use Open Video UI where supported or consider a chromeless implementation.
+
+:::note[Default UI terminology]
+
+The Player SDK default UI is different from the ready-made `` layout provided by Open Video UI. Open Video UI uses its own component library on top of the chromeless Player SDK.
+
+:::
+
+For more extensive control over layout and components, use [Open Video UI](../open-video-ui/introduction.mdx). To implement every control yourself, use the [chromeless player](../chromeless/introduction.mdx).
diff --git a/theoplayer/how-to-guides/web/ui/introduction.mdx b/theoplayer/how-to-guides/web/ui/introduction.mdx
index cd8ed6f431c7..0d907d1b6c02 100644
--- a/theoplayer/how-to-guides/web/ui/introduction.mdx
+++ b/theoplayer/how-to-guides/web/ui/introduction.mdx
@@ -5,88 +5,37 @@ sidebar_label: Introduction
# UI on Web
+import DocCardList from '@theme/DocCardList';
import Intro from '../../shared/ui/_introduction-intro.mdx';
-## Default UI versus chromeless UI
-
-The Web SDK ships a default UI. The default UI is responsive and optimized for browsers, mobile devices and tablets,
-and it has all the basic controls you'd expect from a video player, ranging from a scrub bar to a fullscreen button.
-
-
-
-As a developer, you may use this UI as is, customize it, or create a brand-new chromeless UI,
-as depicted in the screenshot below.
-
-
-
-It's possible that the envisioned design of your video player looks different from THEOplayer's default UI.
-When that happens, your team has to decide whether to customize THEOplayer's default UI, or to implement a chromeless UI.
-
-The default UI has all the basic functionality you expect from a video player, but it might be missing some more exotic UI (or UX) features.
-Changing the colors of the default UI is relatively straightforward, as is hiding a default control item (e.g. the fullscreen button),
-as is inserting a new button in the default control bar.
-However, truly transforming the default UI, such as repositioning elements, using all new icons, and more complex operations,
-can be quite challenging.
-
-Implementing a chromeless UI gives you total control of your UI and UX.
-However, this requires an understanding of video and the THEOplayer API, and you might feel like you're reinventing the wheel.
-
-So what to pick: modify the default UI or implement a chromeless UI?
-
-If the envisioned design looks "quite different" from the default UI, we encourage people to implement a chromeless UI.
-Alternatively, if that isn't an option, we advise people to compromise, and to adapt their envisioned design to look "quite similar" to the default UI.
-
-Our default UI is not optimized for big screen devices like Samsung Tizen, LG webOS and Android TV.
-If you're targeting those (and similar devices), you should consider implementing a chromeless UI,
-as demonstrated on our [Tizen](https://github.com/THEOplayer/samples-tizen) and [webOS](https://github.com/THEOplayer/samples-webos)
-GitHub repositories.
-
-Note that some features are dependent on our default UI, because they are built on top of our default UI.
-For example, the [Up Next](../miscellaneous/up-next.mdx) feature (and API) wouldn't work when you build a chromeless UI.
-
-Alternatively, you can also use [Open Video UI for Web](/open-video-ui/web/),
-a set of UI components which you can compose and style to build your own UI.
-
-## Modify the default UI
-
-You can modify the default UI through JavaScript and CSS.
-
-Changing the colors is quite easy. You can use the tool at [https://demo.theoplayer.com/ui-skinning](https://demo.theoplayer.com/ui-skinning)
-to interactively change the colors and generate the matching CSS.
-More information on changing the colors is available at our article on [UI skinning](ui-skinning.mdx).
-
-The default UI is a fork of Video.js 5, so you may also use the Video.js 5 API to modify the UI, as demonstrated in some of our articles.
-This may - for example - simplify the process of [adding a new button](insert-a-button.mdx) to the default control bar.
-
-Removing a button is a matter of identifying the appropriate CSS selector, and configuring `display: none!important`.
-
-Overlaying text and images is a matter of overlaying a custom `` on top of the THEOplayer container.
-
-### Related articles
-
-Below are some articles related to modifying our default UI:
-
-- [How to remove an element from the UI](remove-ui-element.mdx)
-- [How to align the timeline in the middle](align-timeline.mdx)
-- [How to change the big play button](change-big-play-button.mdx)
-- [How to keep the control bar always visible](keep-control-bar-visible.mdx)
-- [How to detect the visibility of the control bar](detect-control-bar-visibility.mdx)
-- [How to hide or disable the Google IMA UI](hide-google-ima-ui.mdx)
-- [How to insert a button](insert-a-button.mdx)
-- [How to change the UI language](change-ui-language.mdx)
-- [How to customize the UI during ad playback](customize-ui-during-ad-playback.mdx)
-- [How to change how a video should fit inside a container](change-video-fit.mdx)
-- [How to make an audio-only player](audio-only-player.mdx)
-- [How to customize the volume slider](vertical-volume-slider.mdx)
-- [How to disable click to pause](disable-click-to-pause.mdx)
-- [UI skinning](ui-skinning.mdx)
-
-## Implement a chromeless UI
-
-Building a chromeless UI may be daunting at first, but it's rewarding.
-A chromeless UI gives you full control over your UI and UX,
-but you must understand the flow of a video, its API and its events.
-
-Refer to our article on [how to build a chromeless UI](build-chromeless-ui.mdx) for more information.
+## Choose your UI approach
+
+The Web SDK supports three approaches, depending on how much you want to customize:
+
+
diff --git a/theoplayer/how-to-guides/web/ui/open-video-ui/introduction.mdx b/theoplayer/how-to-guides/web/ui/open-video-ui/introduction.mdx
new file mode 100644
index 000000000000..946cf9e3d0cb
--- /dev/null
+++ b/theoplayer/how-to-guides/web/ui/open-video-ui/introduction.mdx
@@ -0,0 +1,15 @@
+---
+slug: /how-to-guides/web/ui/open-video-ui/
+sidebar_label: Introduction
+---
+
+# Open Video UI for Web
+
+import Intro from '../../../shared/ui/_open-video-ui-intro.mdx';
+import RebrandingNotice from '../../../../callouts/_rebranding_notice.md';
+import DocCardList from '@theme/DocCardList';
+
+
+
+
+
diff --git a/theoplayer/how-to-guides/web/ui/open-video-ui/react/introduction.mdx b/theoplayer/how-to-guides/web/ui/open-video-ui/react/introduction.mdx
new file mode 100644
index 000000000000..c4263417a433
--- /dev/null
+++ b/theoplayer/how-to-guides/web/ui/open-video-ui/react/introduction.mdx
@@ -0,0 +1,15 @@
+---
+slug: /how-to-guides/web/ui/open-video-ui/react/
+sidebar_label: Introduction
+---
+
+# Open Video UI for React
+
+import Intro from '../../../../shared/ui/_open-video-ui-intro.mdx';
+import RebrandingNotice from '../../../../../callouts/_rebranding_notice.md';
+import DocCardList from '@theme/DocCardList';
+
+
+
+
+
diff --git a/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/00-getting-started.mdx b/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/00-getting-started.mdx
index bec37eb3f1e5..a5959c46963a 100644
--- a/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/00-getting-started.mdx
+++ b/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/00-getting-started.mdx
@@ -211,7 +211,7 @@ The JavaScript library exposes the THEOplayer API and the CSS library contains t
:::tip[Open Video UI]
The Open Video UI is our new Web UI. It provides component libraries for building a world-class video player experience powered by the THEOplayer SDK.
-[See our Getting Started guide to start using the Open Video UI.](/open-video-ui/web/getting-started/)
+[See our Getting Started guide to start using the Open Video UI.](/theoplayer/ui/web/open-video-ui/getting-started/)
:::
diff --git a/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/01-getting-started-accessibility.mdx b/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/01-getting-started-accessibility.mdx
index 255560a33084..c24670b4a30d 100644
--- a/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/01-getting-started-accessibility.mdx
+++ b/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/01-getting-started-accessibility.mdx
@@ -61,11 +61,11 @@ Common roles are:
### Focus Style
-Focus Style allows the buttons on the video player (the control bar, menu items, close buttons, etc.) to be outlined in order to make them more visible when they are clicked or hovered over. This feature makes it easier for all viewers to see and understand which buttons are in use and which one they have selected. Also while hovered over, the Tooltips feature can make it easier for users by giving them a text description of the button on the UI. For example, when hovered over the mute button, it is outlined and a readers also see the word "Mute" appear on their UI. You can change the look of the default UI with our [UI Skinning Guide](../../../how-to-guides/11-ui/13-ui-skinning.md) or fully customize every element of your video player with our [Open Video UI](/open-video-ui/web/).
+Focus Style allows the buttons on the video player (the control bar, menu items, close buttons, etc.) to be outlined in order to make them more visible when they are clicked or hovered over. This feature makes it easier for all viewers to see and understand which buttons are in use and which one they have selected. Also while hovered over, the Tooltips feature can make it easier for users by giving them a text description of the button on the UI. For example, when hovered over the mute button, it is outlined and a readers also see the word "Mute" appear on their UI. You can change the look of the default UI with our [UI Skinning Guide](../../../how-to-guides/11-ui/13-ui-skinning.md) or fully customize every element of your video player with our [Open Video UI](/theoplayer/ui/web/open-video-ui/).
### User Interface Customization
-User Interface, or UI, is the aspect of the video content that the viewer engages with. For viewers with disabilities, it is important that colors have sufficient contrast with the text and its background. The contrast is not limited to captions, but also includes the text on images, buttons and icons. This feature is especially helpful for viewers with color blindness or low contrast visibility, which is common in aging viewers, as well as viewers in difficult light conditions. It is also important for the video player to have a clear layout and design, to make it as easy and accessible to all viewers as possible. You can change the look of the default UI with our [UI Skinning Guide](../../../how-to-guides/11-ui/13-ui-skinning.md) or fully customize every element of your video player with our [Open Video UI](/open-video-ui/web/).
+User Interface, or UI, is the aspect of the video content that the viewer engages with. For viewers with disabilities, it is important that colors have sufficient contrast with the text and its background. The contrast is not limited to captions, but also includes the text on images, buttons and icons. This feature is especially helpful for viewers with color blindness or low contrast visibility, which is common in aging viewers, as well as viewers in difficult light conditions. It is also important for the video player to have a clear layout and design, to make it as easy and accessible to all viewers as possible. You can change the look of the default UI with our [UI Skinning Guide](../../../how-to-guides/11-ui/13-ui-skinning.md) or fully customize every element of your video player with our [Open Video UI](/theoplayer/ui/web/open-video-ui/).
### Keyboard Compatibility
diff --git a/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md b/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
index 61526266011d..886ee397e66b 100644
--- a/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
+++ b/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
@@ -77,7 +77,7 @@ selectQuality(resolutions[0]);
##### Android SDK
-Android SDK does not have a built-in UI. It also does not support JavaScript injection. However, you can implement a similar custom quality selection menu using [Open Video UI for Android](/open-video-ui/android/) and following the same logic for Web SDK.
+Android SDK does not have a built-in UI. It also does not support JavaScript injection. However, you can implement a similar custom quality selection menu using [Open Video UI for Android](/theoplayer/ui/android/open-video-ui/) and following the same logic for Web SDK.
##### iOS SDK
diff --git a/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-10.md b/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-10.md
index 131136320631..dabe5a62b6df 100644
--- a/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-10.md
+++ b/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-10.md
@@ -11,7 +11,7 @@ Run the following command to install THEOplayer Web SDK version 10:
npm install theoplayer@10
```
-If you're using the [Open Video UI for Web](/open-video-ui/web/) or one
+If you're using the [Open Video UI for Web](/theoplayer/ui/web/open-video-ui/) or one
of [our connectors](/theoplayer/connectors/web/),
make sure to update them to the latest version too to ensure proper support for THEOplayer version 10.
diff --git a/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-10.md b/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-10.md
index bada21089554..cbd4c80a864d 100644
--- a/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-10.md
+++ b/theoplayer_versioned_docs/version-v10/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-10.md
@@ -13,7 +13,7 @@ dependencies {
}
```
-If you're using the [Open Video UI for Android](/open-video-ui/android/) or one of [our connectors](/theoplayer/connectors/android/),
+If you're using the [Open Video UI for Android](/theoplayer/ui/android/open-video-ui/) or one of [our connectors](/theoplayer/connectors/android/),
make sure to update them to the latest version too to ensure proper support for THEOplayer version 10.
## Update `minSdkVersion` to API 23 or higher
diff --git a/theoplayer_versioned_docs/version-v10/how-to-guides/11-ui/00-introduction.md b/theoplayer_versioned_docs/version-v10/how-to-guides/11-ui/00-introduction.md
index ec94b8458d31..f08bbd18d2da 100644
--- a/theoplayer_versioned_docs/version-v10/how-to-guides/11-ui/00-introduction.md
+++ b/theoplayer_versioned_docs/version-v10/how-to-guides/11-ui/00-introduction.md
@@ -73,7 +73,7 @@ Overlaying text and images is a matter of overlaying a custom `
` (or native
#### iOS and Android SDK
As of THEOplayer version 5, the iOS and Android SDKs no longer ship a default UI.
-We recommend switching to our [Open Video UI](/open-video-ui/android/) (for Android)
+We recommend switching to our [Open Video UI](/theoplayer/ui/android/open-video-ui/) (for Android)
or our [React Native UI](https://github.com/THEOplayer/react-native-theoplayer-ui) (for Android and iOS).
For THEOplayer version 4 and lower, the default UI is the same UI as our Web SDK.
diff --git a/theoplayer_versioned_docs/version-v6/how-to-guides/11-ui/00-introduction.md b/theoplayer_versioned_docs/version-v6/how-to-guides/11-ui/00-introduction.md
index ec94b8458d31..f08bbd18d2da 100644
--- a/theoplayer_versioned_docs/version-v6/how-to-guides/11-ui/00-introduction.md
+++ b/theoplayer_versioned_docs/version-v6/how-to-guides/11-ui/00-introduction.md
@@ -73,7 +73,7 @@ Overlaying text and images is a matter of overlaying a custom `
` (or native
#### iOS and Android SDK
As of THEOplayer version 5, the iOS and Android SDKs no longer ship a default UI.
-We recommend switching to our [Open Video UI](/open-video-ui/android/) (for Android)
+We recommend switching to our [Open Video UI](/theoplayer/ui/android/open-video-ui/) (for Android)
or our [React Native UI](https://github.com/THEOplayer/react-native-theoplayer-ui) (for Android and iOS).
For THEOplayer version 4 and lower, the default UI is the same UI as our Web SDK.
diff --git a/theoplayer_versioned_docs/version-v7/getting-started/01-sdks/01-web/00-getting-started.mdx b/theoplayer_versioned_docs/version-v7/getting-started/01-sdks/01-web/00-getting-started.mdx
index 87908ad7f9fa..649e5e6f8f0b 100644
--- a/theoplayer_versioned_docs/version-v7/getting-started/01-sdks/01-web/00-getting-started.mdx
+++ b/theoplayer_versioned_docs/version-v7/getting-started/01-sdks/01-web/00-getting-started.mdx
@@ -211,7 +211,7 @@ The JavaScript library exposes the THEOplayer API and the CSS library contains t
:::tip[Open Video UI]
The Open Video UI is our new Web UI. It provides component libraries for building a world-class video player experience powered by the THEOplayer SDK.
-[See our Getting Started guide to start using the Open Video UI.](/open-video-ui/web/getting-started/)
+[See our Getting Started guide to start using the Open Video UI.](/theoplayer/ui/web/open-video-ui/getting-started/)
:::
diff --git a/theoplayer_versioned_docs/version-v7/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md b/theoplayer_versioned_docs/version-v7/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
index 61526266011d..886ee397e66b 100644
--- a/theoplayer_versioned_docs/version-v7/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
+++ b/theoplayer_versioned_docs/version-v7/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
@@ -77,7 +77,7 @@ selectQuality(resolutions[0]);
##### Android SDK
-Android SDK does not have a built-in UI. It also does not support JavaScript injection. However, you can implement a similar custom quality selection menu using [Open Video UI for Android](/open-video-ui/android/) and following the same logic for Web SDK.
+Android SDK does not have a built-in UI. It also does not support JavaScript injection. However, you can implement a similar custom quality selection menu using [Open Video UI for Android](/theoplayer/ui/android/open-video-ui/) and following the same logic for Web SDK.
##### iOS SDK
diff --git a/theoplayer_versioned_docs/version-v7/how-to-guides/11-ui/00-introduction.md b/theoplayer_versioned_docs/version-v7/how-to-guides/11-ui/00-introduction.md
index ec94b8458d31..f08bbd18d2da 100644
--- a/theoplayer_versioned_docs/version-v7/how-to-guides/11-ui/00-introduction.md
+++ b/theoplayer_versioned_docs/version-v7/how-to-guides/11-ui/00-introduction.md
@@ -73,7 +73,7 @@ Overlaying text and images is a matter of overlaying a custom `
` (or native
#### iOS and Android SDK
As of THEOplayer version 5, the iOS and Android SDKs no longer ship a default UI.
-We recommend switching to our [Open Video UI](/open-video-ui/android/) (for Android)
+We recommend switching to our [Open Video UI](/theoplayer/ui/android/open-video-ui/) (for Android)
or our [React Native UI](https://github.com/THEOplayer/react-native-theoplayer-ui) (for Android and iOS).
For THEOplayer version 4 and lower, the default UI is the same UI as our Web SDK.
diff --git a/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/01-web/00-getting-started.mdx b/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/01-web/00-getting-started.mdx
index 2f67ac51dfbb..6c9d6b4cfa2b 100644
--- a/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/01-web/00-getting-started.mdx
+++ b/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/01-web/00-getting-started.mdx
@@ -211,7 +211,7 @@ The JavaScript library exposes the THEOplayer API and the CSS library contains t
:::tip[Open Video UI]
The Open Video UI is our new Web UI. It provides component libraries for building a world-class video player experience powered by the THEOplayer SDK.
-[See our Getting Started guide to start using the Open Video UI.](/open-video-ui/web/getting-started/)
+[See our Getting Started guide to start using the Open Video UI.](/theoplayer/ui/web/open-video-ui/getting-started/)
:::
diff --git a/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md b/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
index 61526266011d..886ee397e66b 100644
--- a/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
+++ b/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
@@ -77,7 +77,7 @@ selectQuality(resolutions[0]);
##### Android SDK
-Android SDK does not have a built-in UI. It also does not support JavaScript injection. However, you can implement a similar custom quality selection menu using [Open Video UI for Android](/open-video-ui/android/) and following the same logic for Web SDK.
+Android SDK does not have a built-in UI. It also does not support JavaScript injection. However, you can implement a similar custom quality selection menu using [Open Video UI for Android](/theoplayer/ui/android/open-video-ui/) and following the same logic for Web SDK.
##### iOS SDK
diff --git a/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-8.md b/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-8.md
index fe55f2df096d..b0d02a6ad721 100644
--- a/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-8.md
+++ b/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-8.md
@@ -11,7 +11,7 @@ Run the following command to install THEOplayer Web SDK version 8:
npm install theoplayer@8
```
-If you're using the [Open Video UI for Web](/open-video-ui/web/) or one of [our connectors](/theoplayer/connectors/web/),
+If you're using the [Open Video UI for Web](/theoplayer/ui/web/open-video-ui/) or one of [our connectors](/theoplayer/connectors/web/),
make sure to update them to the latest version too to ensure proper support for THEOplayer version 8.
```bash
diff --git a/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-8.md b/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-8.md
index 0072b8607033..184339f332e3 100644
--- a/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-8.md
+++ b/theoplayer_versioned_docs/version-v8/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-8.md
@@ -42,5 +42,5 @@ dependencies {
}
```
-If you're using the [Open Video UI for Android](/open-video-ui/android/) or one of [our connectors](/theoplayer/connectors/android/),
+If you're using the [Open Video UI for Android](/theoplayer/ui/android/open-video-ui/) or one of [our connectors](/theoplayer/connectors/android/),
make sure to update them to the latest version too to ensure proper support for THEOplayer version 8.
diff --git a/theoplayer_versioned_docs/version-v8/how-to-guides/11-ui/00-introduction.md b/theoplayer_versioned_docs/version-v8/how-to-guides/11-ui/00-introduction.md
index ec94b8458d31..f08bbd18d2da 100644
--- a/theoplayer_versioned_docs/version-v8/how-to-guides/11-ui/00-introduction.md
+++ b/theoplayer_versioned_docs/version-v8/how-to-guides/11-ui/00-introduction.md
@@ -73,7 +73,7 @@ Overlaying text and images is a matter of overlaying a custom `
` (or native
#### iOS and Android SDK
As of THEOplayer version 5, the iOS and Android SDKs no longer ship a default UI.
-We recommend switching to our [Open Video UI](/open-video-ui/android/) (for Android)
+We recommend switching to our [Open Video UI](/theoplayer/ui/android/open-video-ui/) (for Android)
or our [React Native UI](https://github.com/THEOplayer/react-native-theoplayer-ui) (for Android and iOS).
For THEOplayer version 4 and lower, the default UI is the same UI as our Web SDK.
diff --git a/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/01-web/00-getting-started.mdx b/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/01-web/00-getting-started.mdx
index 8ec10dc6e785..6d7771e8b72f 100644
--- a/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/01-web/00-getting-started.mdx
+++ b/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/01-web/00-getting-started.mdx
@@ -211,7 +211,7 @@ The JavaScript library exposes the THEOplayer API and the CSS library contains t
:::tip[Open Video UI]
The Open Video UI is our new Web UI. It provides component libraries for building a world-class video player experience powered by the THEOplayer SDK.
-[See our Getting Started guide to start using the Open Video UI.](/open-video-ui/web/getting-started/)
+[See our Getting Started guide to start using the Open Video UI.](/theoplayer/ui/web/open-video-ui/getting-started/)
:::
diff --git a/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md b/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
index 61526266011d..886ee397e66b 100644
--- a/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
+++ b/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/01-web/07-how-to-customize-quality-selection.md
@@ -77,7 +77,7 @@ selectQuality(resolutions[0]);
##### Android SDK
-Android SDK does not have a built-in UI. It also does not support JavaScript injection. However, you can implement a similar custom quality selection menu using [Open Video UI for Android](/open-video-ui/android/) and following the same logic for Web SDK.
+Android SDK does not have a built-in UI. It also does not support JavaScript injection. However, you can implement a similar custom quality selection menu using [Open Video UI for Android](/theoplayer/ui/android/open-video-ui/) and following the same logic for Web SDK.
##### iOS SDK
diff --git a/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-9.md b/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-9.md
index b5e0fc8c4112..5216d70f77f8 100644
--- a/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-9.md
+++ b/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/01-web/13-migrating-to-theoplayer-9.md
@@ -11,7 +11,7 @@ Run the following command to install THEOplayer Web SDK version 9:
npm install theoplayer@9
```
-If you're using the [Open Video UI for Web](/open-video-ui/web/) or one
+If you're using the [Open Video UI for Web](/theoplayer/ui/web/open-video-ui/) or one
of [our connectors](/theoplayer/connectors/web/),
make sure to update them to the latest version too to ensure proper support for THEOplayer version 9.
diff --git a/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-9.md b/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-9.md
index 8b330b308fe6..b04a695f48b7 100644
--- a/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-9.md
+++ b/theoplayer_versioned_docs/version-v9/getting-started/01-sdks/02-android/03-migrating-to-theoplayer-9.md
@@ -13,7 +13,7 @@ dependencies {
}
```
-If you're using the [Open Video UI for Android](/open-video-ui/android/) or one of [our connectors](/theoplayer/connectors/android/),
+If you're using the [Open Video UI for Android](/theoplayer/ui/android/open-video-ui/) or one of [our connectors](/theoplayer/connectors/android/),
make sure to update them to the latest version too to ensure proper support for THEOplayer version 9.
## Update compile SDK to API 35 or higher
diff --git a/theoplayer_versioned_docs/version-v9/how-to-guides/11-ui/00-introduction.md b/theoplayer_versioned_docs/version-v9/how-to-guides/11-ui/00-introduction.md
index ec94b8458d31..f08bbd18d2da 100644
--- a/theoplayer_versioned_docs/version-v9/how-to-guides/11-ui/00-introduction.md
+++ b/theoplayer_versioned_docs/version-v9/how-to-guides/11-ui/00-introduction.md
@@ -73,7 +73,7 @@ Overlaying text and images is a matter of overlaying a custom `
` (or native
#### iOS and Android SDK
As of THEOplayer version 5, the iOS and Android SDKs no longer ship a default UI.
-We recommend switching to our [Open Video UI](/open-video-ui/android/) (for Android)
+We recommend switching to our [Open Video UI](/theoplayer/ui/android/open-video-ui/) (for Android)
or our [React Native UI](https://github.com/THEOplayer/react-native-theoplayer-ui) (for Android and iOS).
For THEOplayer version 4 and lower, the default UI is the same UI as our Web SDK.
diff --git a/tsconfig.json b/tsconfig.json
index eb8f999f8a26..acfa8c18387e 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -10,6 +10,6 @@
"@site/*": ["./*"]
}
},
- "include": ["sidebars*.ts", "src/", "theoplayer/", "ads/", "adengine/", "open-video-ui/", "contributing/", "theolive/", "millicast/"],
- "exclude": ["theoplayer/external/", "open-video-ui/external/", "theoplayer_versioned_docs/"]
+ "include": ["sidebars*.ts", "src/", "theoplayer/", "ads/", "adengine/", "contributing/", "theolive/", "millicast/"],
+ "exclude": ["theoplayer/external/", "theoplayer_versioned_docs/"]
}