1# Redirecting to an Application Page (router Event) 2 3The **router** capability of the [postCardAction](../reference/apis-arkui/js-apis-postCardAction.md#postcardaction-1) API can be used in a dynamic widget to quickly start a specific UIAbility of the widget provider. By leveraging this capability, an application can provide in the widget multiple buttons, each of which targets a different target UIAbility. For example, a camera widget can provide the buttons that redirect the user to the UIAbility for taking a photo and the UIAbility for recording a video. 4 5 6 7> **NOTE** 8> 9> This topic describes development for dynamic widgets. For static widgets, see [FormLink](../reference/apis-arkui/arkui-ts/ts-container-formlink.md). 10 11## How to Develop 121. Create a dynamic widget. 13 14 In the **entry** module of the project, create an ArkTS widget named WidgetEventRouterCard. 15 162. Build the code for the ArkTS widget page layout. 17 18 Design two buttons on the widget page. When one of the buttons is clicked, **postCardAction** is called to send a router event to the specified UIAbility, with the content to be transferred defined in the event. 19 20 ```ts 21 //src/main/ets/widgeteventroutercard/pages/WidgetEventRouterCard.ets 22 @Entry 23 @Component 24 struct WidgetEventRouterCard { 25 build() { 26 Column() { 27 Text($r('app.string.JumpLabel')) 28 .fontColor('#FFFFFF') 29 .opacity(0.9) 30 .fontSize(14) 31 .margin({ top: '8%', left: '10%' }) 32 Row() { 33 Column() { 34 Button() { 35 Text($r('app.string.ButtonA_label')) 36 .fontColor('#45A6F4') 37 .fontSize(12) 38 } 39 .width(120) 40 .height(32) 41 .margin({ top: '20%' }) 42 .backgroundColor('#FFFFFF') 43 .borderRadius(16) 44 .onClick(() => { 45 postCardAction(this, { 46 action: 'router', 47 abilityName: 'EntryAbility', 48 params: { targetPage: 'funA' } 49 }); 50 }) 51 52 Button() { 53 Text($r('app.string.ButtonB_label')) 54 .fontColor('#45A6F4') 55 .fontSize(12) 56 } 57 .width(120) 58 .height(32) 59 .margin({ top: '8%', bottom: '15vp' }) 60 .backgroundColor('#FFFFFF') 61 .borderRadius(16) 62 .onClick(() => { 63 postCardAction(this, { 64 action: 'router', 65 abilityName: 'EntryAbility', 66 params: { targetPage: 'funB' } 67 }); 68 }) 69 } 70 }.width('100%').height('80%') 71 .justifyContent(FlexAlign.Center) 72 } 73 .width('100%') 74 .height('100%') 75 .alignItems(HorizontalAlign.Start) 76 .backgroundImage($r('app.media.CardEvent')) 77 .backgroundImageSize(ImageSize.Cover) 78 } 79 } 80 ``` 81 824. Process the router event. 83 84 The UIAbility receives the router event and obtains parameters. It then starts the page specified by **params**. 85 86 ```ts 87 //src/main/ets/entryability/EntryAbility.ets 88 import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 89 import { window } from '@kit.ArkUI'; 90 import { hilog } from '@kit.PerformanceAnalysisKit'; 91 92 const TAG: string = 'EntryAbility'; 93 const DOMAIN_NUMBER: number = 0xFF00; 94 95 export default class EntryAbility extends UIAbility { 96 private selectPage: string = ''; 97 private currentWindowStage: window.WindowStage | null = null; 98 99 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 100 // Obtain the targetPage parameter passed in the router event. 101 hilog.info(DOMAIN_NUMBER, TAG, `Ability onCreate: ${JSON.stringify(want?.parameters)}`); 102 if (want?.parameters?.params) { 103 // want.parameters.params corresponds to params in postCardAction(). 104 let params: Record<string, Object> = JSON.parse(want.parameters.params as string); 105 this.selectPage = params.targetPage as string; 106 hilog.info(DOMAIN_NUMBER, TAG, `onCreate selectPage: ${this.selectPage}`); 107 } 108 } 109 110 // If the UIAbility is running in the background, the onNewWant lifecycle callback is triggered after the router event is received. 111 onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { 112 hilog.info(DOMAIN_NUMBER, TAG, `Ability onNewWant: ${JSON.stringify(want?.parameters)}`); 113 if (want?.parameters?.params) { 114 // want.parameters.params corresponds to params in postCardAction(). 115 let params: Record<string, Object> = JSON.parse(want.parameters.params as string); 116 this.selectPage = params.targetPage as string; 117 hilog.info(DOMAIN_NUMBER, TAG, `onNewWant selectPage: ${this.selectPage}`); 118 } 119 if (this.currentWindowStage !== null) { 120 this.onWindowStageCreate(this.currentWindowStage); 121 } 122 } 123 124 onWindowStageCreate(windowStage: window.WindowStage): void { 125 // Main window is created, set main page for this ability 126 let targetPage: string; 127 // Start the page specified by targetPage. 128 switch (this.selectPage) { 129 case 'funA': 130 targetPage = 'pages/FunA'; // Use the actual UIAbility page path. 131 break; 132 case 'funB': 133 targetPage = 'pages/FunB'; // Use the actual UIAbility page path. 134 break; 135 default: 136 targetPage = 'pages/Index'; // Use the actual UIAbility page path. 137 } 138 if (this.currentWindowStage === null) { 139 this.currentWindowStage = windowStage; 140 } 141 windowStage.loadContent(targetPage, (err, data) => { 142 if (err.code) { 143 hilog.error(DOMAIN_NUMBER, TAG, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); 144 return; 145 } 146 hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); 147 }); 148 } 149 } 150 ``` 1515. Create the UIAbility page, which is the target of the redirection. 152 153 Create **FunA.ets** and **FunB.ets** in the **pages** folder to build the page layout. 154 155 ```ts 156 //src/main/ets/pages/FunA.ets 157 @Entry 158 @Component 159 struct FunA { 160 @State message: string = 'Hello World'; 161 162 build() { 163 RelativeContainer() { 164 Text(this.message) 165 .id('HelloWorld') 166 .fontSize(50) 167 .fontWeight(FontWeight.Bold) 168 .alignRules({ 169 center: { anchor: '__container__', align: VerticalAlign.Center }, 170 middle: { anchor: '__container__', align: HorizontalAlign.Center } 171 }) 172 } 173 .height('100%') 174 .width('100%') 175 } 176 } 177 ``` 178 1796. Register the UIAbility pages. 180 181 Open the **main_pages.json** file and register **FunA.ets** and **FunB.ets** in the **src** array. 182 ```ts 183 //src/main/resources/base/profile/main_pages.json 184 { 185 "src": [ 186 "pages/Index", 187 "pages/FunA", 188 "pages/FunB" 189 ] 190 } 191 ``` 192