or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

canvas.mdcore-framework.mddevice.mddom-query.mdindex.mdlocation.mdmedia.mdnavigation.mdnetwork.mdstorage.mdsystem-info.mdui-interactions.md

navigation.mddocs/

0

# Route Navigation APIs

1

2

Page navigation and routing capabilities integrated with @tarojs/router for single-page application navigation, providing programmatic control over page transitions and history management.

3

4

## Capabilities

5

6

### Page Navigation

7

8

Navigate between pages in the application with various navigation modes and parameter passing.

9

10

```typescript { .api }

11

/**

12

* Navigate to a new page, keeping current page in history stack

13

* @param options - Navigation configuration

14

* @returns Promise that resolves when navigation completes

15

*/

16

function navigateTo(options: NavigateOption): Promise<void>;

17

18

/**

19

* Replace current page with a new page (no history stack change)

20

* @param options - Redirect configuration

21

* @returns Promise that resolves when redirect completes

22

*/

23

function redirectTo(options: RedirectOption): Promise<void>;

24

25

/**

26

* Navigate back in the page history stack

27

* @param options - Navigation back configuration

28

* @returns Promise that resolves when navigation completes

29

*/

30

function navigateBack(options?: NavigateBackOption): Promise<void>;

31

32

/**

33

* Switch to a tab page (for tab-based applications)

34

* @param options - Tab switch configuration

35

* @returns Promise that resolves when tab switch completes

36

*/

37

function switchTab(options: SwitchTabOption): Promise<void>;

38

39

/**

40

* Restart the application with a new page as the root

41

* @param options - Relaunch configuration

42

* @returns Promise that resolves when relaunch completes

43

*/

44

function reLaunch(options: ReLaunchOption): Promise<void>;

45

46

interface NavigateOption extends CallbackOptions {

47

/** Target page URL path (required) */

48

url: string;

49

/** Event handlers for cross-page communication */

50

events?: Record<string, Function>;

51

/** Animation type for transition */

52

animationType?: 'slide-in-right' | 'slide-in-left' | 'slide-in-top' | 'slide-in-bottom' | 'fade-in' | 'zoom-in' | 'zoom-fade-in' | 'none';

53

/** Animation duration in milliseconds */

54

animationDuration?: number;

55

}

56

57

interface RedirectOption extends CallbackOptions {

58

/** Target page URL path (required) */

59

url: string;

60

}

61

62

interface NavigateBackOption extends CallbackOptions {

63

/** Number of pages to go back (default: 1) */

64

delta?: number;

65

/** Animation type for back transition */

66

animationType?: 'slide-out-right' | 'slide-out-left' | 'slide-out-top' | 'slide-out-bottom' | 'fade-out' | 'zoom-out' | 'zoom-fade-out' | 'none';

67

/** Animation duration in milliseconds */

68

animationDuration?: number;

69

}

70

71

interface SwitchTabOption extends CallbackOptions {

72

/** Tab page URL path (required) */

73

url: string;

74

}

75

76

interface ReLaunchOption extends CallbackOptions {

77

/** New root page URL path (required) */

78

url: string;

79

}

80

```

81

82

**Usage Examples:**

83

84

```typescript

85

import { navigateTo, redirectTo, navigateBack, switchTab, reLaunch } from "@tarojs/taro-h5";

86

87

// Basic navigation to a new page

88

await navigateTo({

89

url: '/pages/profile/index'

90

});

91

92

// Navigation with query parameters

93

await navigateTo({

94

url: '/pages/product/detail?id=123&category=electronics'

95

});

96

97

// Navigation with custom animation

98

await navigateTo({

99

url: '/pages/settings/index',

100

animationType: 'slide-in-left',

101

animationDuration: 300

102

});

103

104

// Navigate with event handlers for communication

105

await navigateTo({

106

url: '/pages/editor/index',

107

events: {

108

// Listen for events from the target page

109

acceptDataFromOpenedPage: (data) => {

110

console.log('Received data from editor:', data);

111

},

112

someEvent: (eventData) => {

113

console.log('Custom event received:', eventData);

114

}

115

}

116

});

117

118

// Redirect (replace current page)

119

await redirectTo({

120

url: '/pages/login/index'

121

});

122

123

// Navigate back one page

124

await navigateBack();

125

126

// Navigate back multiple pages

127

await navigateBack({

128

delta: 3 // Go back 3 pages

129

});

130

131

// Navigate back with animation

132

await navigateBack({

133

delta: 1,

134

animationType: 'slide-out-right',

135

animationDuration: 250

136

});

137

138

// Switch to tab page

139

await switchTab({

140

url: '/pages/home/index'

141

});

142

143

// Restart app with new root page

144

await reLaunch({

145

url: '/pages/welcome/index'

146

});

147

```

148

149

### Router Information

150

151

Access current routing information and page context.

152

153

```typescript { .api }

154

/**

155

* Router object providing navigation utilities

156

* Note: Limited functionality in H5 environment

157

*/

158

interface Router {

159

/** Add route builder (not supported in H5) */

160

addRouteBuilder(): never;

161

/** Get route context (not supported in H5) */

162

getRouteContext(): never;

163

/** Remove route builder (not supported in H5) */

164

removeRouteBuilder(): never;

165

}

166

167

/**

168

* Current router information from @tarojs/router

169

*/

170

interface RouterInfo {

171

/** Current page path */

172

path: string;

173

/** Query parameters object */

174

params: Record<string, string>;

175

/** Route configuration */

176

$taroPath?: string;

177

/** Route index in stack */

178

$taroTimestamp?: number;

179

}

180

```

181

182

### Advanced Navigation Patterns

183

184

Complex navigation scenarios and best practices for application flow management.

185

186

```typescript

187

// Navigation service for complex routing logic

188

class NavigationService {

189

private static instance: NavigationService;

190

private navigationHistory: string[] = [];

191

private maxHistorySize = 50;

192

193

static getInstance(): NavigationService {

194

if (!NavigationService.instance) {

195

NavigationService.instance = new NavigationService();

196

}

197

return NavigationService.instance;

198

}

199

200

async goToPage(url: string, options?: Partial<NavigateOption>): Promise<void> {

201

try {

202

await navigateTo({

203

url,

204

...options

205

});

206

207

// Track navigation history

208

this.navigationHistory.push(url);

209

if (this.navigationHistory.length > this.maxHistorySize) {

210

this.navigationHistory.shift();

211

}

212

213

console.log('Navigated to:', url);

214

} catch (error) {

215

console.error('Navigation failed:', error);

216

throw error;

217

}

218

}

219

220

async replacePage(url: string, options?: Partial<RedirectOption>): Promise<void> {

221

try {

222

await redirectTo({

223

url,

224

...options

225

});

226

227

// Update last entry in history instead of adding

228

if (this.navigationHistory.length > 0) {

229

this.navigationHistory[this.navigationHistory.length - 1] = url;

230

} else {

231

this.navigationHistory.push(url);

232

}

233

234

console.log('Redirected to:', url);

235

} catch (error) {

236

console.error('Redirect failed:', error);

237

throw error;

238

}

239

}

240

241

async goBack(pages: number = 1): Promise<void> {

242

try {

243

await navigateBack({ delta: pages });

244

245

// Update navigation history

246

for (let i = 0; i < pages && this.navigationHistory.length > 0; i++) {

247

this.navigationHistory.pop();

248

}

249

250

console.log(`Navigated back ${pages} page(s)`);

251

} catch (error) {

252

console.error('Navigate back failed:', error);

253

throw error;

254

}

255

}

256

257

async restartApp(rootUrl: string): Promise<void> {

258

try {

259

await reLaunch({ url: rootUrl });

260

261

// Clear navigation history

262

this.navigationHistory = [rootUrl];

263

264

console.log('App restarted with root:', rootUrl);

265

} catch (error) {

266

console.error('App restart failed:', error);

267

throw error;

268

}

269

}

270

271

getNavigationHistory(): string[] {

272

return [...this.navigationHistory];

273

}

274

275

getPreviousPage(): string | null {

276

return this.navigationHistory.length > 1

277

? this.navigationHistory[this.navigationHistory.length - 2]

278

: null;

279

}

280

281

getCurrentPage(): string | null {

282

return this.navigationHistory.length > 0

283

? this.navigationHistory[this.navigationHistory.length - 1]

284

: null;

285

}

286

}

287

288

// Route parameter handling

289

class RouteParams {

290

static parse(url: string): { path: string; params: Record<string, string> } {

291

const [path, queryString] = url.split('?');

292

const params: Record<string, string> = {};

293

294

if (queryString) {

295

queryString.split('&').forEach(param => {

296

const [key, value] = param.split('=');

297

if (key && value) {

298

params[decodeURIComponent(key)] = decodeURIComponent(value);

299

}

300

});

301

}

302

303

return { path, params };

304

}

305

306

static stringify(path: string, params: Record<string, any>): string {

307

const queryParams = Object.entries(params)

308

.filter(([_, value]) => value != null)

309

.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)

310

.join('&');

311

312

return queryParams ? `${path}?${queryParams}` : path;

313

}

314

315

static getCurrentParams(): Record<string, string> {

316

const instance = getCurrentInstance();

317

return instance?.router?.params || {};

318

}

319

}

320

321

// Tab navigation manager

322

class TabNavigationManager {

323

private activeTabIndex = 0;

324

private tabs: TabConfig[] = [];

325

326

constructor(tabs: TabConfig[]) {

327

this.tabs = tabs;

328

}

329

330

async switchToTab(index: number): Promise<void> {

331

if (index < 0 || index >= this.tabs.length) {

332

throw new Error('Invalid tab index');

333

}

334

335

const tab = this.tabs[index];

336

await switchTab({ url: tab.pagePath });

337

338

this.activeTabIndex = index;

339

console.log('Switched to tab:', tab.text);

340

}

341

342

async switchToTabByPath(path: string): Promise<void> {

343

const tabIndex = this.tabs.findIndex(tab => tab.pagePath === path);

344

if (tabIndex === -1) {

345

throw new Error('Tab not found for path: ' + path);

346

}

347

348

await this.switchToTab(tabIndex);

349

}

350

351

getCurrentTab(): TabConfig | null {

352

return this.tabs[this.activeTabIndex] || null;

353

}

354

355

getTabByIndex(index: number): TabConfig | null {

356

return this.tabs[index] || null;

357

}

358

359

getAllTabs(): TabConfig[] {

360

return [...this.tabs];

361

}

362

}

363

364

interface TabConfig {

365

pagePath: string;

366

text: string;

367

iconPath?: string;

368

selectedIconPath?: string;

369

}

370

371

// Authentication-aware navigation

372

class AuthNavigationGuard {

373

private static redirectAfterLogin: string | null = null;

374

375

static async navigateWithAuth(url: string, options?: Partial<NavigateOption>): Promise<void> {

376

const isAuthenticated = await this.checkAuthentication();

377

378

if (!isAuthenticated) {

379

// Store intended destination

380

this.redirectAfterLogin = url;

381

382

// Redirect to login

383

await redirectTo({ url: '/pages/login/index' });

384

return;

385

}

386

387

// User is authenticated, proceed with navigation

388

await navigateTo({ url, ...options });

389

}

390

391

static async handleLoginSuccess(): Promise<void> {

392

if (this.redirectAfterLogin) {

393

const destination = this.redirectAfterLogin;

394

this.redirectAfterLogin = null;

395

396

await redirectTo({ url: destination });

397

} else {

398

await switchTab({ url: '/pages/home/index' });

399

}

400

}

401

402

static async logout(): Promise<void> {

403

// Clear authentication

404

removeStorageSync('authToken');

405

removeStorageSync('userInfo');

406

407

// Clear redirect destination

408

this.redirectAfterLogin = null;

409

410

// Restart app with login page

411

await reLaunch({ url: '/pages/login/index' });

412

}

413

414

private static async checkAuthentication(): Promise<boolean> {

415

const token = getStorageSync('authToken');

416

if (!token) return false;

417

418

try {

419

// Verify token with server

420

const response = await request({

421

url: '/api/auth/verify',

422

method: 'POST',

423

header: { Authorization: `Bearer ${token}` }

424

});

425

426

return response.statusCode === 200;

427

} catch {

428

return false;

429

}

430

}

431

}

432

433

// Usage examples

434

const nav = NavigationService.getInstance();

435

const params = RouteParams;

436

const authGuard = AuthNavigationGuard;

437

438

// Complex navigation with parameters

439

async function navigateToProductDetail(productId: string, category: string) {

440

const url = params.stringify('/pages/product/detail', {

441

id: productId,

442

category,

443

timestamp: Date.now()

444

});

445

446

await nav.goToPage(url, {

447

animationType: 'slide-in-right'

448

});

449

}

450

451

// Navigate with authentication check

452

async function navigateToSecurePage() {

453

await authGuard.navigateWithAuth('/pages/account/settings', {

454

animationType: 'fade-in'

455

});

456

}

457

458

// Tab navigation setup

459

const tabManager = new TabNavigationManager([

460

{ pagePath: '/pages/home/index', text: 'Home' },

461

{ pagePath: '/pages/discover/index', text: 'Discover' },

462

{ pagePath: '/pages/profile/index', text: 'Profile' }

463

]);

464

465

await tabManager.switchToTab(1); // Switch to Discover tab

466

```

467

468

### Page Communication

469

470

Cross-page communication patterns for data sharing and event handling.

471

472

```typescript

473

// Event-based page communication

474

class PageCommunication {

475

private static eventBus = new Map<string, Function[]>();

476

477

static emit(event: string, data: any): void {

478

const listeners = this.eventBus.get(event) || [];

479

listeners.forEach(callback => {

480

try {

481

callback(data);

482

} catch (error) {

483

console.error('Page communication error:', error);

484

}

485

});

486

}

487

488

static on(event: string, callback: Function): void {

489

const listeners = this.eventBus.get(event) || [];

490

listeners.push(callback);

491

this.eventBus.set(event, listeners);

492

}

493

494

static off(event: string, callback?: Function): void {

495

if (!callback) {

496

this.eventBus.delete(event);

497

return;

498

}

499

500

const listeners = this.eventBus.get(event) || [];

501

const filtered = listeners.filter(cb => cb !== callback);

502

this.eventBus.set(event, filtered);

503

}

504

505

static once(event: string, callback: Function): void {

506

const onceCallback = (data: any) => {

507

callback(data);

508

this.off(event, onceCallback);

509

};

510

this.on(event, onceCallback);

511

}

512

}

513

514

// Usage in page components

515

function navigateWithCallback() {

516

// Listen for data from target page

517

PageCommunication.once('editor:save', (savedData) => {

518

console.log('Editor saved data:', savedData);

519

updateLocalData(savedData);

520

});

521

522

// Navigate to editor

523

navigateTo({

524

url: '/pages/editor/index?mode=create',

525

events: {

526

// Alternative event handling via navigateTo options

527

editorComplete: (data) => {

528

console.log('Editor completed:', data);

529

}

530

}

531

});

532

}

533

534

// In editor page

535

function saveAndReturn(data: any) {

536

// Emit event to parent page

537

PageCommunication.emit('editor:save', data);

538

539

// Navigate back

540

navigateBack();

541

}

542

```

543

544

## Error Handling

545

546

Navigation operations can fail due to invalid URLs, missing pages, or system restrictions.

547

548

```typescript

549

// Comprehensive navigation error handling

550

async function safeNavigate(url: string, options?: Partial<NavigateOption>): Promise<boolean> {

551

try {

552

await navigateTo({ url, ...options });

553

return true;

554

} catch (error: any) {

555

console.error('Navigation error:', error);

556

557

// Handle specific error types

558

if (error.message?.includes('page not found')) {

559

await showModal({

560

title: 'Page Not Found',

561

content: 'The requested page does not exist.',

562

showCancel: false

563

});

564

} else if (error.message?.includes('too many pages')) {

565

await showModal({

566

title: 'Too Many Pages',

567

content: 'Too many pages open. Please close some pages and try again.',

568

showCancel: false

569

});

570

} else {

571

await showToast({

572

title: 'Navigation failed',

573

icon: 'error'

574

});

575

}

576

577

return false;

578

}

579

}

580

581

// Safe back navigation with fallback

582

async function safeNavigateBack(delta: number = 1, fallbackUrl?: string): Promise<void> {

583

try {

584

const pages = getCurrentPages();

585

586

if (pages.length <= delta) {

587

// Not enough pages to go back, use fallback or redirect to home

588

const target = fallbackUrl || '/pages/home/index';

589

await redirectTo({ url: target });

590

} else {

591

await navigateBack({ delta });

592

}

593

} catch (error) {

594

console.error('Navigate back failed:', error);

595

596

// Fallback to home page

597

await reLaunch({ url: '/pages/home/index' });

598

}

599

}

600

```

601

602

## Types

603

604

```typescript { .api }

605

interface CallbackOptions {

606

success?: (res: any) => void;

607

fail?: (err: any) => void;

608

complete?: (res: any) => void;

609

}

610

611

type AnimationType =

612

| 'slide-in-right' | 'slide-in-left' | 'slide-in-top' | 'slide-in-bottom'

613

| 'slide-out-right' | 'slide-out-left' | 'slide-out-top' | 'slide-out-bottom'

614

| 'fade-in' | 'fade-out'

615

| 'zoom-in' | 'zoom-out'

616

| 'zoom-fade-in' | 'zoom-fade-out'

617

| 'none';

618

619

interface NavigationError extends Error {

620

code?: string;

621

type?: 'page_not_found' | 'too_many_pages' | 'invalid_url' | 'permission_denied';

622

}

623

```