1# Developing User-Agent 2<!--RP1--> 3User-Agent (UA) is a special string that contains key information such as the device type, operating system, and version. In web development, UA is used by the server to identify the source device of the request and its features, so that the server can provide custom content and services. If UAs cannot be correctly identified on a page, multiple exceptions may occur. For example, a page layout optimized for a mobile device may be displayed in disorder on a desktop device, and vice versa. In addition, some browser functionalities or CSS attributes are supported only in specific browser versions. If a page cannot successfully identify the UA, rendering problems or logic errors may occur. 4 5## Default User-Agent Structure 6 7- String format 8 9 ```ts 10 Mozilla/5.0 ({DeviceType}; {OSName} {OSVersion}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{ChromeCompatibleVersion}.0.0.0 Safari/537.36 ArkWeb/{ArkWeb VersionCode} {DeviceCompat} {Extension} 11 ``` 12 13- Example 14 15 ```ts 16 Mozilla/5.0 (Phone; OpenHarmony 5.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 ArkWeb/4.1.6.1 Mobile 17 ``` 18 19- Fields 20 21 | Field | Description | 22 | --------------------- | ------------------------------------------------------------ | 23 | DeviceType | Device type.<br>The value can be:<br>- **Phone**<br>- **Tablet**<br>- **PC** (2-in-1 device)| 24 | OSName | OS name.<br>Default value: **OpenHarmony** | 25 | OSVersion | OS version. The value is a two-digit number, in M.S format.<br>You can obtain the value by extracting the first two digits of the version number from the system parameter **const.ohos.fullname**.<br>Default value: **5.0** | 26 | ChromeCompatibleVersion | The version that is compatible with the main Chrome version. The earliest version is 114.<br>Default value: **114** | 27 | ArkWeb | Web kernel name of the OpenHarmony version.<br>Default value: **ArkWeb** | 28 | ArkWeb VersionCode | ArkWeb version number, in the format of a.b.c.d.<br>Default value: **4.1.6.1** | 29 | DeviceCompat | Forward compatibility settings.<br>Default value: **Mobile** | 30 | Extension | Field that can be extended by a third-party application.<br>When a third-party application uses the **Web** component, UA can be extended. For example, an application information identifier can be added.| 31 32> **NOTE** 33> 34> - Currently, there are two spaces before the **ArkWeb** field of the default **User-Agent**. 35> 36> - The **viewport** parameter of the **meta** tag on the frontend HTML page is enabled or disabled based on whether **User-Agent** contains the **Mobile** field. If **User-Agent** does not contain the **Mobile** field, the **viewport** attribute in the **meta** tag is disabled by default. In this case, you can explicitly set [metaViewport](../reference/apis-arkweb/arkts-basic-components-web-attributes.md#metaviewport12) to **true** to enable the **viewport** attribute. 37> 38> - You are advised to use the **OpenHarmony** keyword to identify whether a device is an OpenHarmony device, and use the **DeviceType** keyword to identify the device type for page display on different devices. (The **ArkWeb** keyword indicates the web kernel of the device, and the **OpenHarmony** keyword indicates the operating system of the device.) 39> 40> - The **{DistributionOSName}** and **{DistributionOSVersion}** fields are not supported in versions earlier than API version 15. Since API version 15, they are not displayed in the default **User-Agent**. 41 42## Custom User-Agent Structure 43 44In the following example, [getUserAgent()](../reference/apis-arkweb/arkts-apis-webview-WebviewController.md#getuseragent) is used to obtain the default **User-Agent** string, which you can modify or extend as needed. 45 46```ts 47// xxx.ets 48import { webview } from '@kit.ArkWeb'; 49import { BusinessError } from '@kit.BasicServicesKit'; 50 51@Entry 52@Component 53struct WebComponent { 54 controller: webview.WebviewController = new webview.WebviewController(); 55 56 build() { 57 Column() { 58 Button('getUserAgent') 59 .onClick(() => { 60 try { 61 let userAgent = this.controller.getUserAgent(); 62 console.log("userAgent: " + userAgent); 63 } catch (error) { 64 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 65 } 66 }) 67 Web({ src: 'www.example.com', controller: this.controller }) 68 } 69 } 70} 71``` 72 73In the following example, [setCustomUserAgent()](../reference/apis-arkweb/arkts-apis-webview-WebviewController.md#setcustomuseragent10) is used to set a custom user agent, which overwrites the default user agent. Therefore, you are advised to add the extension field to the end of the default user agent. For example, to develop a third-party application, you can add a specific application identifier while maintaining the original user agent information. 74 75When **src** of the **Web** component is set to a URL, set **User-Agent** in **onControllerAttached**. For details, see the following example. Avoid setting the user agent in **onLoadIntercept**. Otherwise, the setting may fail occasionally. If **User-Agent** is not set in **onControllerAttached**, calling **setCustomUserAgent** may cause mismatches between the loaded page and the intended user agent. 76 77When **src** of the **Web** component is set to an empty string, call **setCustomUserAgent** to set **User-Agent** and then use **loadUrl** to load a specific page. 78 79```ts 80// xxx.ets 81import { webview } from '@kit.ArkWeb'; 82import { BusinessError } from '@kit.BasicServicesKit'; 83 84@Entry 85@Component 86struct WebComponent { 87 controller: webview.WebviewController = new webview.WebviewController(); 88 // Third-party application information identifier 89 @State customUserAgent: string = ' DemoApp'; 90 91 build() { 92 Column() { 93 Web({ src: 'www.example.com', controller: this.controller }) 94 .onControllerAttached(() => { 95 console.log("onControllerAttached"); 96 try { 97 let userAgent = this.controller.getUserAgent() + this.customUserAgent; 98 this.controller.setCustomUserAgent(userAgent); 99 } catch (error) { 100 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 101 } 102 }) 103 } 104 } 105} 106``` 107 108Since API version 20, you can use the [setAppCustomUserAgent()](../reference/apis-arkweb/arkts-apis-webview-WebviewController.md#setappcustomuseragent20) API to set an application-level custom user agent or use the [setUserAgentForHosts()](../reference/apis-arkweb/arkts-apis-webview-WebviewController.md#setuseragentforhosts20) API to set an application-level custom user agent for a specific website. The custom user agent overwrites the system user agent and takes effect for all **Web** components in the application. 109 110You are advised to call the **setAppCustomUserAgent** and **setUserAgentForHosts** methods to set **User-Agent** before creating a **Web** component, and then create a **Web** component with a specified **src** or use **loadUrl** to load a specific page. 111 112```ts 113// xxx.ets 114import { webview } from '@kit.ArkWeb'; 115import { BusinessError } from '@kit.BasicServicesKit'; 116 117@Entry 118@Component 119struct WebComponent { 120 controller: webview.WebviewController = new webview.WebviewController(); 121 122 aboutToAppear(): void { 123 try { 124 webview.WebviewController.initializeWebEngine(); 125 let defaultUserAgent = webview.WebviewController.getDefaultUserAgent(); 126 let appUA = " appUA"; 127 webview.WebviewController.setUserAgentForHosts( 128 appUA, 129 [ 130 "www.example.com", 131 "www.baidu.com" 132 ] 133 ); 134 } catch (error) { 135 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 136 } 137 } 138 139 build() { 140 Column() { 141 Web({ src: 'www.example.com', controller: this.controller }) 142 } 143 } 144} 145``` 146 147In the following example, [getCustomUserAgent()](../reference/apis-arkweb/arkts-apis-webview-WebviewController.md#getcustomuseragent10) is used to obtain the custom user agent. 148 149```ts 150// xxx.ets 151import { webview } from '@kit.ArkWeb'; 152import { BusinessError } from '@kit.BasicServicesKit'; 153 154@Entry 155@Component 156struct WebComponent { 157 controller: webview.WebviewController = new webview.WebviewController(); 158 @State userAgent: string = ''; 159 160 build() { 161 Column() { 162 Button('getCustomUserAgent') 163 .onClick(() => { 164 try { 165 this.userAgent = this.controller.getCustomUserAgent(); 166 console.log("userAgent: " + this.userAgent); 167 } catch (error) { 168 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 169 } 170 }) 171 Web({ src: 'www.example.com', controller: this.controller }) 172 } 173 } 174} 175``` 176 177## User-Agent API Priority 178 179| API| Priority| Description| 180| -------- | -------- | -------- | 181| setCustomUserAgent | Highest| Takes effect for the called **Web** component.| 182| setUserAgentForHosts | Lower than **setCustomUserAgent**| Takes effect for all **Web** components in the application to access the specified website.| 183| setAppCustomUserAgent | Lower than **setUserAgentForHosts**| Takes effect for all **Web** components in the application.| 184| Default UA of ArkWeb| Lowest| Takes effect for all **Web** components in the application. This parameter is read-only and can be obtained using **getDefaultUserAgent**.| 185 186## FAQs 187 188### How do I use User-Agent to identify different OpenHarmony devices? 189 190OpenHarmony devices can be identified based on the OS name, OS version, and device type in **User-Agent**. You are advised to check all of them to ensure accurate device identification. 191 1921. Identification based on the OS name 193 194 Use the **{OSName}** field. 195 196 ```ts 197 const isOpenHarmony = () => /OpenHarmony/i.test(navigator.userAgent); 198 ``` 199 2002. Identification based on the OS version 201 202 Use the **{OSName}** and **{OSVersion}** fields. The format is **OpenHarmony + Version number**. 203 204 ```ts 205 const matches = navigator.userAgent.match(/OpenHarmony (\d+\.?\d*)/); 206 matches?.length && Number(matches[1]) >= 5; 207 ``` 208 2093. Identification based on the device type 210 211 Use the **deviceType** field. 212 213 ```ts 214 // Check whether the device is a mobile phone. 215 const isPhone = () => /Phone/i.test(navigator.userAgent); 216 217 // Check whether the device is a tablet. 218 const isTablet = () => /Tablet/i.test(navigator.userAgent); 219 220 // Check whether the device is a 2-in-1 device. 221 const is2in1 = () => /PC/i.test(navigator.userAgent); 222 ``` 223 224### How do I simulate the User-Agent of OpenHarmony for frontend debugging? 225 226In Windows, macOS, and Linux, you can use the **User-Agent** rewriting capability provided by DevTools to simulate the OpenHarmony **User-Agent** in Chrome, Edge, and Firefox. 227<!--RP1End--> 228