diff --git a/contributing-guide/mobile-app/setup-guide.mdx b/contributing-guide/mobile-app/setup-guide.mdx
index 0dc94cee..a7f46e79 100644
--- a/contributing-guide/mobile-app/setup-guide.mdx
+++ b/contributing-guide/mobile-app/setup-guide.mdx
@@ -115,241 +115,9 @@ pnpm install package-name
## Push notifications
-Chatwoot supports mobile push notifications through Firebase Cloud Messaging (FCM). There are two delivery paths depending on your setup:
+If you are using the community edition of Chatwoot with the [official mobile app](https://www.chatwoot.com/mobile-apps), push notifications work out of the box with no additional configuration.
-- **Relay server (default)**: Self-hosted instances without Firebase credentials route notifications through the Chatwoot relay server, which forwards them to the **official Chatwoot mobile app**.
-- **Direct FCM**: Instances with Firebase configured send notifications directly to your **custom-built mobile app**.
-
-
-You must use either the official apps for both platforms or custom builds for both — mixing is not supported. For more details, refer to the [push notification documentation](https://www.chatwoot.com/hc/handbook/articles/1687935909-push-notification).
-
-
-### Using the official mobile app
-
-If you are using the community edition of Chatwoot with the [official mobile app](https://www.chatwoot.com/mobile-apps), push notifications work out of the box with no additional configuration. The relay server is enabled by default (`ENABLE_PUSH_RELAY_SERVER=true`).
-
-### Setting up Firebase for custom builds
-
-If you are building a custom-branded mobile app, you need to configure Firebase on both the mobile app and the Chatwoot server.
-
-#### Step 1: Create a Firebase project
-
-1. Go to the [Firebase Console](https://console.firebase.google.com/) and create a new project (or use an existing one).
-2. Register your Android app with your package name (e.g., `com.yourcompany.app`).
-3. Register your iOS app with your bundle identifier (e.g., `com.yourcompany.app`).
-
-#### Step 2: Download Firebase config files
-
-Download the platform-specific configuration files from your Firebase project settings:
-
-
-
-1. In **Project Settings > General**, find your Android app and click **Download google-services.json**.
-2. Place the file in the root of the mobile app repository.
-
-
-1. In **Project Settings > General**, find your iOS app and click **Download GoogleService-Info.plist**.
-2. Place the file in the root of the mobile app repository.
-
-
-
-#### Step 3: Configure mobile app environment variables
-
-Update your `.env` file to point to the Firebase config files:
-
-```bash
-EXPO_PUBLIC_ANDROID_GOOGLE_SERVICES_FILE=./google-services.json
-EXPO_PUBLIC_IOS_GOOGLE_SERVICES_FILE=./GoogleService-Info.plist
-```
-
-Then regenerate the native code so the new config is picked up:
-
-```bash
-pnpm generate
-```
-
-#### Step 4: Generate a Firebase service account
-
-The Chatwoot server needs a service account to send push notifications via the FCM v1 API.
-
-1. In the Firebase Console, go to **Project Settings > Service accounts**.
-2. Click **Generate new private key** to download a JSON credentials file.
-
-
-Keep this file secure. It grants access to send push notifications on behalf of your Firebase project.
-
-
-#### Step 5: Configure the Chatwoot server
-
-In your Chatwoot installation, navigate to **Super Admin > App Config** and set the following:
-
-| Config key | Value |
-| ----------------------- | --------------------------------------------------------- |
-| `FIREBASE_PROJECT_ID` | Your Firebase project ID (e.g., `my-project-12345`) |
-| `FIREBASE_CREDENTIALS` | The full contents of the service account JSON file |
-
-Once both values are set, the server will send push notifications directly to FCM instead of using the relay server.
-
-#### Verifying the setup
-
-1. Build and install the custom app on a device (`pnpm run:ios` or `pnpm run:android`).
-2. Log in to your Chatwoot instance from the mobile app.
-3. From another browser session, send a message to a conversation assigned to the logged-in agent.
-4. The device should receive a push notification.
-
-
-Push notifications do not work on iOS simulators. You must use a physical device to test.
-
-
-## Deep linking
-
-Deep linking allows users to tap a Chatwoot conversation URL (or a push notification) and be taken directly to that conversation in the mobile app. The app supports two mechanisms:
-
-- **Custom URL scheme**: `chatwootapp://` — used for SSO callbacks and internal routing.
-- **Universal Links (iOS) / App Links (Android)**: `https:///app/accounts/*/conversations/*` — used for opening web URLs directly in the app.
-
-### How it works
-
-When the app receives a deep link, React Navigation matches it against the configured path pattern and navigates to the conversation screen:
-
-```
-https:///app/accounts/{accountId}/conversations/{conversationId}
-```
-
-This works across all app states — whether the app is in the foreground, backgrounded, or was terminated. Push notification taps also use this same flow to navigate to the relevant conversation.
-
-### Configuring deep links for custom builds
-
-If you are building a custom-branded app with your own domain, you need to configure both the mobile app and the Chatwoot server so that deep links resolve correctly.
-
-#### Mobile app configuration
-
-The app uses Expo's built-in deep linking support. In `app.config.ts`, update the following to match your domain and bundle identifiers:
-
-
-
-
-Update the [associated domain](https://docs.expo.dev/linking/ios-universal-links/) to your Chatwoot installation URL:
-
-```typescript
-ios: {
- associatedDomains: ['applinks:your-domain.com'],
-}
-```
-
-Expo prebuild writes this into the `.entitlements` file automatically.
-
-
-
-
-Update the [intent filter](https://docs.expo.dev/linking/android-app-links/) host to your Chatwoot installation URL:
-
-```typescript
-android: {
- intentFilters: [
- {
- action: 'VIEW',
- autoVerify: true,
- data: [
- {
- scheme: 'https',
- host: 'your-domain.com',
- pathPrefix: '/app/accounts/',
- },
- ],
- category: ['BROWSABLE', 'DEFAULT'],
- },
- ],
-}
-```
-
-Expo prebuild writes this into the `AndroidManifest.xml` automatically.
-
-
-
-
-After making changes, regenerate the native code:
-
-```bash
-pnpm generate
-```
-
-#### Server configuration
-
-The Chatwoot server dynamically serves the verification files that Android and iOS require to confirm your app owns the domain. Configure the following environment variables on your Chatwoot installation:
-
-
-
-
-The server serves an `apple-app-site-association` file at `https:///.well-known/apple-app-site-association`. No additional configuration is needed beyond ensuring your Chatwoot installation is accessible at the domain specified in `associatedDomains`.
-
-
-
-
-Set the following environment variables with your app's package name and signing certificate fingerprint:
-
-```bash
-ANDROID_BUNDLE_ID=com.yourcompany.app
-ANDROID_SHA256_CERT_FINGERPRINT=YOUR:SHA256:CERT:FINGERPRINT
-```
-
-This is served at `https:///.well-known/assetlinks.json` and tells Android to open matching URLs in your app.
-
-To obtain your SHA-256 certificate fingerprint, run:
-
-```bash
-keytool -list -v -keystore your-keystore.jks -alias your-alias
-```
-
-
-
-
-
-If you are using the official Chatwoot mobile app with `app.chatwoot.com`, deep linking works out of the box with no additional configuration.
-
-
-## Build & Submit using EAS
-
-We use Expo Application Services (EAS) for building, deploying, and submitting the app to app stores. EAS Build and Submit is available to anyone with an Expo account, regardless of whether you pay for EAS or use our Free plan.
-
-You can sign up at [Expo EAS](https://expo.dev/eas).
-
-### Build the app
-
-#### iOS Build
-
-```bash
-pnpm run build:ios:local
-```
-
-#### Android Build
-
-```bash
-pnpm run build:android:local
-```
-
-### Submit the app
-
-#### iOS Submission
-
-```bash
-pnpm submit:ios
-```
-
-#### Android Submission
-
-```bash
-pnpm submit:android
-```
-
-When you run the above command, you will be prompted to provide a path to a local app binary file. Please select the file that you built in the previous step:
-
-- **iOS**: `.ipa` file
-- **Android**: `.aab` file
-
-
-It may take a while to complete the submission process. You will see the status of the submission on your terminal.
-
+If you are building a custom-branded app, refer to the [custom mobile app guide](/self-hosted/custom-mobile-app) for Firebase, deep linking, and build setup.
## Troubleshooting
diff --git a/docs.json b/docs.json
index 1c17666e..9579af14 100644
--- a/docs.json
+++ b/docs.json
@@ -32,9 +32,7 @@
{
"anchor": "Introduction",
"icon": "house",
- "pages": [
- "introduction"
- ]
+ "pages": ["introduction"]
},
{
"anchor": "Installation & Setup",
@@ -42,9 +40,7 @@
"pages": [
{
"group": "Getting Started",
- "pages": [
- "self-hosted"
- ]
+ "pages": ["self-hosted"]
},
{
"group": "Deployment Methods",
@@ -127,9 +123,7 @@
},
{
"group": "Help Center",
- "pages": [
- "self-hosted/configuration/help-center"
- ]
+ "pages": ["self-hosted/configuration/help-center"]
}
]
},
@@ -170,7 +164,8 @@
"self-hosted/supported-features",
"self-hosted/restricted-instances",
"self-hosted/instagram-app-review",
- "self-hosted/faq"
+ "self-hosted/faq",
+ "self-hosted/custom-mobile-app"
]
}
]
@@ -181,9 +176,7 @@
"pages": [
{
"group": "Getting Started",
- "pages": [
- "contributing-guide"
- ]
+ "pages": ["contributing-guide"]
},
{
"group": "Environment Setup",
@@ -208,9 +201,7 @@
},
{
"group": "Testing",
- "pages": [
- "contributing-guide/tests/cypress"
- ]
+ "pages": ["contributing-guide/tests/cypress"]
},
{
"group": "Others",
@@ -235,9 +226,7 @@
{
"group": "Getting Started",
"description": "Learn about Chatwoot APIs and how to use them",
- "pages": [
- "api-reference/introduction"
- ]
+ "pages": ["api-reference/introduction"]
},
{
"group": "Application APIs",
@@ -268,12 +257,7 @@
{
"group": "Platform APIs",
"description": "APIs for managing platform aspects of Chatwoot",
- "includeTags": [
- "Accounts",
- "Account Users",
- "AgentBots",
- "Users"
- ],
+ "includeTags": ["Accounts", "Account Users", "AgentBots", "Users"],
"openapi": "https://raw.githubusercontent.com/chatwoot/chatwoot/develop/swagger/tag_groups/platform_swagger.json"
},
{
@@ -289,9 +273,7 @@
{
"group": "Other APIs",
"description": "Additional Chatwoot APIs",
- "includeTags": [
- "CSAT Survey Page"
- ],
+ "includeTags": ["CSAT Survey Page"],
"openapi": "https://raw.githubusercontent.com/chatwoot/chatwoot/develop/swagger/tag_groups/other_swagger.json"
}
]
diff --git a/self-hosted/custom-mobile-app.mdx b/self-hosted/custom-mobile-app.mdx
new file mode 100644
index 00000000..41c0e591
--- /dev/null
+++ b/self-hosted/custom-mobile-app.mdx
@@ -0,0 +1,235 @@
+---
+title: Custom Mobile App Build
+description: Guide to building a custom-branded Chatwoot mobile app with push notifications and deep linking
+sidebarTitle: Custom Mobile App Build
+---
+
+# Custom mobile app build
+
+Guide to building a custom-branded Chatwoot mobile app with push notifications, deep linking, and app store submission.
+
+## Push notifications
+
+Chatwoot supports mobile push notifications through Firebase Cloud Messaging (FCM). There are two delivery paths depending on your setup:
+
+- **Relay server (default)**: Self-hosted instances without Firebase credentials route notifications through the Chatwoot relay server, which forwards them to the **official Chatwoot mobile app**.
+- **Direct FCM**: Instances with Firebase configured send notifications directly to your **custom-built mobile app**.
+
+
+You must use either the official apps for both platforms or custom builds for both — mixing is not supported. For more details, refer to the [push notification documentation](https://www.chatwoot.com/hc/handbook/articles/1687935909-push-notification).
+
+
+### Setting up Firebase
+
+To send push notifications to your custom-branded app, you need to configure Firebase on both the mobile app and the Chatwoot server.
+
+#### Step 1: Create a Firebase project
+
+1. Go to the [Firebase Console](https://console.firebase.google.com/) and create a new project (or use an existing one).
+2. Register your Android app with your package name (e.g., `com.yourcompany.app`).
+3. Register your iOS app with your bundle identifier (e.g., `com.yourcompany.app`).
+
+#### Step 2: Download Firebase config files
+
+Download the platform-specific configuration files from your Firebase project settings:
+
+
+
+1. In **Project Settings > General**, find your Android app and click **Download google-services.json**.
+2. Place the file in the root of the mobile app repository.
+
+
+1. In **Project Settings > General**, find your iOS app and click **Download GoogleService-Info.plist**.
+2. Place the file in the root of the mobile app repository.
+
+
+
+#### Step 3: Configure mobile app environment variables
+
+Update your `.env` file to point to the Firebase config files:
+
+```bash
+EXPO_PUBLIC_ANDROID_GOOGLE_SERVICES_FILE=./google-services.json
+EXPO_PUBLIC_IOS_GOOGLE_SERVICES_FILE=./GoogleService-Info.plist
+```
+
+Then regenerate the native code so the new config is picked up:
+
+```bash
+pnpm generate
+```
+
+#### Step 4: Generate a Firebase service account
+
+The Chatwoot server needs a service account to send push notifications via the FCM v1 API.
+
+1. In the Firebase Console, go to **Project Settings > Service accounts**.
+2. Click **Generate new private key** to download a JSON credentials file.
+
+
+Keep this file secure. It grants access to send push notifications on behalf of your Firebase project.
+
+
+#### Step 5: Configure the Chatwoot server
+
+In your Chatwoot installation, navigate to **Super Admin > App Config** and set the following:
+
+| Config key | Value |
+| ----------------------- | --------------------------------------------------------- |
+| `FIREBASE_PROJECT_ID` | Your Firebase project ID (e.g., `my-project-12345`) |
+| `FIREBASE_CREDENTIALS` | The full contents of the service account JSON file |
+
+Once both values are set, the server will send push notifications directly to FCM instead of using the relay server.
+
+#### Verifying the setup
+
+1. Build and install the custom app on a device (`pnpm run:ios` or `pnpm run:android`).
+2. Log in to your Chatwoot instance from the mobile app.
+3. From another browser session, send a message to a conversation assigned to the logged-in agent.
+4. The device should receive a push notification.
+
+
+Push notifications do not work on iOS simulators. You must use a physical device to test.
+
+
+## Deep linking
+
+Deep linking allows users to tap a Chatwoot conversation URL (or a push notification) and be taken directly to that conversation in the mobile app. The app supports two mechanisms:
+
+- **Custom URL scheme**: `chatwootapp://` — used for SSO callbacks and internal routing.
+- **Universal Links (iOS) / App Links (Android)**: `https:///app/accounts/*/conversations/*` — used for opening web URLs directly in the app.
+
+### How it works
+
+When the app receives a deep link, React Navigation matches it against the configured path pattern and navigates to the conversation screen:
+
+```
+https:///app/accounts/{accountId}/conversations/{conversationId}
+```
+
+This works across all app states — whether the app is in the foreground, backgrounded, or was terminated. Push notification taps also use this same flow to navigate to the relevant conversation.
+
+### Mobile app configuration
+
+The app uses Expo's built-in deep linking support. In `app.config.ts`, update the following to match your domain:
+
+
+
+
+Update the [associated domain](https://docs.expo.dev/linking/ios-universal-links/) to your Chatwoot installation URL:
+
+```typescript
+ios: {
+ associatedDomains: ['applinks:your-domain.com'],
+}
+```
+
+Expo prebuild writes this into the `.entitlements` file automatically.
+
+
+
+
+Update the [intent filter](https://docs.expo.dev/linking/android-app-links/) host to your Chatwoot installation URL:
+
+```typescript
+android: {
+ intentFilters: [
+ {
+ action: 'VIEW',
+ autoVerify: true,
+ data: [
+ {
+ scheme: 'https',
+ host: 'your-domain.com',
+ pathPrefix: '/app/accounts/',
+ },
+ ],
+ category: ['BROWSABLE', 'DEFAULT'],
+ },
+ ],
+}
+```
+
+Expo prebuild writes this into the `AndroidManifest.xml` automatically.
+
+
+
+
+After making changes, regenerate the native code:
+
+```bash
+pnpm generate
+```
+
+### Server configuration
+
+The Chatwoot server dynamically serves the verification files that Android and iOS require to confirm your app owns the domain. Configure the following environment variables on your Chatwoot installation:
+
+
+
+
+The server serves an `apple-app-site-association` file at `https:///.well-known/apple-app-site-association`. No additional configuration is needed beyond ensuring your Chatwoot installation is accessible at the domain specified in `associatedDomains`.
+
+
+
+
+Set the following environment variables with your app's package name and signing certificate fingerprint:
+
+```bash
+ANDROID_BUNDLE_ID=com.yourcompany.app
+ANDROID_SHA256_CERT_FINGERPRINT=YOUR:SHA256:CERT:FINGERPRINT
+```
+
+This is served at `https:///.well-known/assetlinks.json` and tells Android to open matching URLs in your app.
+
+To obtain your SHA-256 certificate fingerprint, run:
+
+```bash
+keytool -list -v -keystore your-keystore.jks -alias your-alias
+```
+
+
+
+
+## Build & Submit using EAS
+
+We use Expo Application Services (EAS) for building, deploying, and submitting the app to app stores. EAS Build and Submit is available to anyone with an Expo account, regardless of whether you pay for EAS or use our Free plan.
+
+You can sign up at [Expo EAS](https://expo.dev/eas).
+
+### Build the app
+
+#### iOS Build
+
+```bash
+pnpm run build:ios:local
+```
+
+#### Android Build
+
+```bash
+pnpm run build:android:local
+```
+
+### Submit the app
+
+#### iOS Submission
+
+```bash
+pnpm submit:ios
+```
+
+#### Android Submission
+
+```bash
+pnpm submit:android
+```
+
+When you run the above command, you will be prompted to provide a path to a local app binary file. Please select the file that you built in the previous step:
+
+- **iOS**: `.ipa` file
+- **Android**: `.aab` file
+
+
+It may take a while to complete the submission process. You will see the status of the submission on your terminal.
+