The deferred link capability is supported since API version 5.0.3(15).
If a user to whom an app link is shared has not installed the app, the deferred link capability enables the system to obtain the previously tapped link when the app is opened for the first time by calling the deferred link API. Once the link is obtained, the corresponding app details page, instead of the app home screen, will be directly displayed, enhancing user experience and the link conversion rate.
The deferred link can be obtained only once. After it is obtained, the system deletes the link from the cache. Subsequent calls will return an empty response.
Validity period: The maximum cache duration of a link is 10 minutes. The link will be automatically deleted once this period expires.
Maximum number of cached links: The system can cache up to 50 links. The earliest cached link will be automatically deleted once this limit is exceeded.
The target app has been configured with a link based on App Linking.
This capability applies only to HarmonyOS apps with API version 5.0.3(15) or later.
This capability is supported on phones and tablets. Starting from version 6.1.0(23), it is also supported on PCs/2-in-1 devices.
Only app links that pass the domain verification of App Linking are supported. For details, please refer to Creating an Associated Website Domain Name for Your App in AppGallery Connect. It is advised that the deferred link API be called after the privacy agreement is signed upon the first launch. This ensures that the domain verification is successful at that time.
Obtain the deferred link.
In the Constants.ets file within the entry/src/main/ets/constants directory, configure the link to a details page in the target app for other entry page files to reference.
export class Constants {
/**
* Replace it with your own app link.
**/
static readonly APP_LINK_PAGE: string = 'https://linking.xiaobingtang.cn/path1?dst=DetailPage';
} Specify the details in the Page1.ets file within the entry/src/main/ets/pages directory. When the link is triggered by the caller app, the device redirects users to the corresponding details page in the target app.
import { Constants } from '../constants/Constants';
@Component
export struct Page1 {
@Consume('pageInfos') pageInfos: NavPathStack;
private desc: string = '';
aboutToAppear(): void {
this.desc = this.pageInfos.getParamByIndex(0) as string;
}
build() {
NavDestination() {
Column() {
Column() {
Text(`This is detail Page\n\n AppLinking is ${Constants.APP_LINK_PAGE}\n\n${this.desc}.`)
.fontColor($r('sys.color.font_primary'))
.fontSize(24)
.fontWeight(FontWeight.Bold)
.padding(16)
}
.alignItems(HorizontalAlign.Start)
.width('100%')
.margin({ top: 12 })
.foregroundColor($r('sys.color.ohos_id_color_component_normal_dark'))
}
.width('100%')
.height('100%')
.foregroundColor($r('sys.color.comp_background_secondary'))
}.title('Page1')
}
} Add the following code to the entry page file Index.ets. When the app is opened for the first time, the deferredLink.popDeferredLink() API is called to obtain the app link tapped previously by the user.
import { deferredLink } from '@kit.AppLinkingKit';
import { Constants } from '../constants/Constants';
import { Page1 } from './Page1';
// ...
@Entry
@Component
struct Index {
@State message: string = 'App Link target APP';
@Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack();
async aboutToAppear(): Promise<void> {
// ...
let curDeferredLink: string = await deferredLink.popDeferredLink();
if (curDeferredLink === Constants.APP_LINK_PAGE) {
this.pageInfos.pushPath({
name: 'Page1',
param: 'Pull up the Page1 through deferred link when the app has not be installed'
});
}
}
build() {
// ...
}
// ...
@Builder
pageMap(name: string) {
if (name === 'Page1') {
Page1()
}
}
} Verify the effect of app launch.
The caller app passes the link of the target app through the UIAbilityContext.openLink() API to start the target app.
The UIAbilityContext.openLink() API provides two methods for starting the target app.
Method 1: Open the app only in App Linking mode.
In this method, appLinkingOnly is set to true. If a matching app is found, that app is directly opened. If no app matches, an exception is thrown.
This method applies to scenarios where you have made configurations to handle target app launch failure. For example, if the caller app integrates ArkWeb, the link can be opened through ArkWeb when the target app is unavailable.
Method 2: Preferentially open the app in App Linking mode.
In this method, appLinkingOnly is set to false or not set. If a matching app is found, that app is directly opened. If no app matches, the system attempts to open the app in a browser.
This method applies to scenarios where you have made no configurations to handle target app launch failure. If the target app is unavailable, the link is opened through the system browser.
This section describes method 1, in order to check whether the App Linking configuration is correct. The following is an example.
Add the GlobalContext.ets file to the entry/src/main/ets/common directory to implement the APIs for initializing and obtaining the app context.
import { common } from '@kit.AbilityKit';
export class GlobalContext {
private static context: common.UIAbilityContext;
public static initContext(context: common.UIAbilityContext): void {
GlobalContext.context = context;
}
public static getContext(): common.UIAbilityContext {
return GlobalContext.context;
}
} Import GlobalContext to the entry/src/main/ets/entryability/EntryAbility.ets file and use GlobalContext.initContext(this.context) in the onCreate method to initialize the global app context.
In the entry/src/main/ets/pages/Index.ets file, use the UIAbilityContext.openLink() API to open the app.
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { GlobalContext } from '../common/GlobalContext';
// ...
@Entry
@Component
struct Index {
// ...
build() {
// ...
Button('start link deferred', { type: ButtonType.Capsule, stateEffect: true })
.width('100%')
.height(40)
.margin({ top: '20vp' })
.onClick(() => {
let context = GlobalContext.getContext();
let link: string = 'https://www.example.com/product?pageName=productDetail';
// Open the app only in App Linking mode.
context.openLink(link, { appLinkingOnly: true })
.then(() => {
hilog.info(0x0000, 'testTag', `Succeeded in opening link.`);
})
.catch((error: BusinessError) => {
hilog.error(0x0000, 'testTag', `Failed to open link, code: ${error.code}, message: ${error.message}`);
})
})
// ...
}
// ...
} Install the caller app and tap the redirection button in the app.
If the target app is not installed, the system throws an exception.
Install the target app. The details page of the app will be displayed based on the deferred link obtained.