How to add deep links to an ReactJS Ionic Android Project

Issue

I’ve got a basic ReactJS Project and I followed this guide to turn it into an android project with my output in the build directory.

I’ve successfully generated a working APK file. however now I wish to point https://example.com/ URL opened by any browser on mobile to open my app once it’s been installed. any help would be greatly apperiacted.

I’m not sure where to register this url to open my app, TIA

Update

<intent-filter android:label="@string/title_activity_main">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="https"
        android:host="m.clipdrop.io"
        android:pathPrefix="/" />
</intent-filter>
<intent-filter android:label="@string/title_activity_main">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="http"
        android:host="m.clipdrop.io"
        android:pathPrefix="/" />
</intent-filter>
<!-- Accepts URIs that begin with "clipdrop://login” -->
<intent-filter android:label="@string/title_activity_main">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="clipdrop"
        android:host="login" />
</intent-filter>

The link clicked would look like this

https://m.clipdrop.io/login?b=datahere

then i have this code which handles the open url event

import React, { useEffect } from 'react';
import { useHistory } from 'react-router-dom';
import { App, URLOpenListenerEvent } from '@capacitor/app';

export default function AppUrlListener(){
    let history = useHistory();
    useEffect(() => {
      App.addListener('appUrlOpen', (event) => {
        var url = new URL(event.url);
        var benc = url.searchParams.get("b")?.replace("%3D", "=");
        if(benc){
          window.location.href = "/login?b=" + benc; 
        }
        // If no match, do nothing - let regular routing
        // logic take over
      });
    }, []);
  
    return null;
  };

Update 2

File: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="io.clipdrop.clipdrop">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
            android:name="io.clipdrop.clipdrop.MainActivity"
            android:label="@string/title_activity_main"
            android:theme="@style/AppTheme.NoActionBarLaunch"
            android:launchMode="singleTask"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <!-- Accepts URIs that begin with "http(s)://m.clipdrop.io -->
            <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="http" />
                <data android:scheme="https" />
                <data android:host="m.clipdrop.io" />
            </intent-filter>
        </activity>
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths"></meta-data>
        </provider>
    </application>
    <!-- Permissions -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.MICROPHONE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-feature android:name="android.hardware.camera" android:required="true" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-feature android:name="android.hardware.microphone"/>
    <uses-permission android:name="android.permission.AUDIO_CAPTURE" />
</manifest>

I have setup the assetlinks.json

when clicking the link it opens in the browser instead, but there is this icon in the corner when it opens in the browser:

enter image description here

Solution

If you are using Capacitor, for adding deeplinks to your project, follow the native procedure. just like explained in android docs, you should have this in your manifest file (located in android/app/src/main/AndroidManifest.xml):

<activity
    android:name="com.example.android.GizmosActivity"
    android:label="@string/title_gizmos" >
    <intent-filter android:label="@string/filter_view_http_gizmos">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <!-- **** -->
        <!-- This is where you put your deeplinks with the 'data' tag:  -->
        <!-- **** -->

        <!-- Accepts URIs that begin with "http://www.example.com/gizmos” -->
        <data android:scheme="http"
              android:host="www.example.com"
              android:pathPrefix="/gizmos" />
        <!-- note that the leading "/" is required for pathPrefix-->

        <!-- **** -->
        <!-- **** -->

    </intent-filter>
    <intent-filter android:label="@string/filter_view_example_gizmos">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- Accepts URIs that begin with "example://gizmos” -->
        <data android:scheme="example"
              android:host="gizmos" />
    </intent-filter>
</activity>

for handling deeplink requests and it’s data inside of your app after it has been opened, use the appUrlOpen event as explained in capacitor docs

UPDATE

answer for your update:

Since android 12, deeplinks in android would directly open browser unless you verify your applink. follow this instructions for verifying app links.

Answered By – AmirAli Saghaei

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published