WebView Navigation and History Tracking in HarmonyOS
Web navigation enables users to move between different pages within a WebView component. This functionality enocmpasses history traverasl, programmatic page transitions, and cross-application linking. The following sections demonstrate implementation patterns using HarmonyOS ArkUI TypeScript API.
- Session History Traversal
The WebView controller maintains an inetrnal navigation stack that allows backward and forward movement through visited pages. The following implementation shows how to check navigation feasibility and trigger history traversal:
// NavigationController.ets
import webView from '@ohos.web.webview';
@Entry
@Component
struct NavigationContainer {
private browserEngine: webView.WebviewController = new webView.WebviewController();
build() {
Column({ space: 12 }) {
Button('Go Back')
.onClick(() => {
if (this.browserEngine.accessBackward()) {
this.browserEngine.backward();
}
})
Button('Go Forward')
.onClick(() => {
if (this.browserEngine.accessForward()) {
this.browserEngine.forward();
}
})
Web({ src: 'https://developer.harmonyos.com', controller: this.browserEngine })
.domStorageAccess(true)
.javaScriptAccess(true)
}
.padding(16)
}
}
- Custom URL Scheme Handling
WebView supports intercepting navigation requests to implement custom routing logic. This pattern enables bridging web content to native application pages through specialized URL schemes.
Main Application File
// AppNavigation.ets
import webView from '@ohos.web.webview';
import systemRouter from '@ohos.router';
@Entry
@Component
struct WebNavigationHost {
private webController: webView.WebviewController = new webView.WebviewController();
build() {
Column() {
Web({ src: $rawfile('app.html'), controller: this.webController })
.onLoadIntercept((event: webView.LoadInterceptEvent) => {
const targetUrl: string = event.data.toString();
const nativeScheme = 'myapp://';
if (targetUrl.startsWith(nativeScheme)) {
const routePath = targetUrl.slice(nativeScheme.length);
systemRouter.pushUrl({ url: routePath });
return true; // Prevent WebView from loading
}
return false; // Allow normal navigation
})
}
}
}
Web Content
<!-- app.html -->
<html>
<head>
<meta charset="UTF-8">
<title>Navigation Bridge</title>
</head>
<body>
<nav>
<a href="myapp://pages/UserDashboard">Open User Dashboard</a>
<a href="myapp://pages/SettingsPanel">Open Settings</a>
<a href="https://external-site.com">External Link</a>
</nav>
</body>
</html>
Target Page
// UserDashboard.ets
@Entry
@Component
struct UserDashboard {
@State private welcomeText: string = 'Welcome to Native Page';
build() {
Column({ space: 20 }) {
Text(this.welcomeText)
.fontSize(24)
.fontWeight(FontWeight.Bold)
Button('Return to WebView')
.onClick(() => {
systemRouter.back();
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
- Cross-Application Deep Linking
HarmonyOS WebView can trigger navigation to external applications using system-defined URI schemes. The following example demonstrates initiating a phone call from web content:
// ExternalAppLauncher.ets
import webView from '@ohos.web.webview';
import telephony from '@ohos.telephony.call';
@Entry
@Component
struct CrossAppNavigator {
private externalController: webView.WebviewController = new webView.WebviewController();
build() {
Column() {
Web({ src: $rawfile('actions.html'), controller: this.externalController })
.onLoadIntercept((event: webView.LoadInterceptEvent) => {
const actionUrl: string = event.data.toString();
if (actionUrl.startsWith('tel:')) {
const phoneNumber = actionUrl.substring(4);
telephony.makeCall(phoneNumber, (err) => {
if (err) {
console.error('Call failed:', JSON.stringify(err));
}
});
return true;
}
if (actionUrl.startsWith('mailto:')) {
// Email handling logic
return true;
}
return false;
})
}
}
}
Action Triggers
<!-- actions.html -->
<html>
<body>
<h2>Contact Options</h2>
<a href="tel:+8613800138000">Call Support</a>
<a href="mailto:support@example.com">Email Support</a>
</body>
</html>