or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

components.mdcomposables.mdindex.mdnavigation-guards.mdroute-configuration.mdrouter-instance.md

navigation-guards.mddocs/

0

# Navigation Guards

1

2

Comprehensive guard system for controlling route transitions with global, per-route, and component-level hooks. Guards provide fine-grained control over navigation flow with support for authentication, authorization, and custom logic.

3

4

## Capabilities

5

6

### Global Guards

7

8

Router-wide navigation guards that apply to all route transitions.

9

10

```javascript { .api }

11

/**

12

* Global before guard - runs before every route transition

13

* @param guard - Navigation guard function

14

* @returns Function to remove the guard

15

*/

16

beforeEach(guard: NavigationGuard): () => void;

17

18

/**

19

* Global before resolve guard - runs after all component guards and async components are resolved

20

* @param guard - Navigation guard function

21

* @returns Function to remove the guard

22

*/

23

beforeResolve(guard: NavigationGuard): () => void;

24

25

/**

26

* Global after hook - runs after every route transition (cannot affect navigation)

27

* @param hook - After navigation hook function

28

* @returns Function to remove the hook

29

*/

30

afterEach(hook: (to: Route, from: Route) => any): () => void;

31

32

/**

33

* Navigation guard function signature

34

* @param to - Target route being navigated to

35

* @param from - Current route being navigated away from

36

* @param next - Function to call to resolve the hook

37

*/

38

type NavigationGuard = (to: Route, from: Route, next: NavigationGuardNext) => any;

39

40

/**

41

* Next function for controlling navigation flow

42

* @param to - Optional navigation target or false to abort

43

*/

44

type NavigationGuardNext = (to?: RawLocation | false | ((vm: Vue) => any) | void) => void;

45

```

46

47

**Usage Examples:**

48

49

```javascript

50

// Authentication guard

51

const removeGuard = router.beforeEach((to, from, next) => {

52

if (to.meta.requiresAuth && !isAuthenticated()) {

53

next('/login');

54

} else {

55

next();

56

}

57

});

58

59

// Authorization guard

60

router.beforeEach((to, from, next) => {

61

if (to.meta.roles && !hasRequiredRole(to.meta.roles)) {

62

next('/unauthorized');

63

} else {

64

next();

65

}

66

});

67

68

// Loading state management

69

router.beforeEach((to, from, next) => {

70

showLoadingSpinner();

71

next();

72

});

73

74

router.afterEach((to, from) => {

75

hideLoadingSpinner();

76

77

// Analytics tracking

78

trackPageView(to.path);

79

80

// Update page title

81

document.title = to.meta.title || 'My App';

82

});

83

84

// Remove guard when no longer needed

85

removeGuard();

86

```

87

88

### Route-Level Guards

89

90

Guards defined directly on route configurations.

91

92

```javascript { .api }

93

/**

94

* Route-level guard in route configuration

95

*/

96

interface RouteConfig {

97

beforeEnter?: NavigationGuard;

98

}

99

```

100

101

**Usage Examples:**

102

103

```javascript

104

const routes = [

105

{

106

path: '/admin',

107

component: AdminPanel,

108

beforeEnter: (to, from, next) => {

109

if (!hasAdminAccess()) {

110

next('/dashboard');

111

} else {

112

next();

113

}

114

}

115

},

116

{

117

path: '/user/:id',

118

component: UserProfile,

119

beforeEnter: async (to, from, next) => {

120

try {

121

// Validate user exists and is accessible

122

await validateUserAccess(to.params.id);

123

next();

124

} catch (error) {

125

next('/not-found');

126

}

127

}

128

}

129

];

130

```

131

132

### Component Guards

133

134

Guards defined within Vue component definitions.

135

136

```javascript { .api }

137

/**

138

* Component-level navigation guards (defined in component options)

139

*/

140

interface ComponentGuards {

141

/** Called when route is about to change but component is reused */

142

beforeRouteUpdate?: NavigationGuard;

143

/** Called before navigating away from this component */

144

beforeRouteLeave?: NavigationGuard;

145

/** Called when this route is confirmed (after all guards pass) */

146

beforeRouteEnter?: (to: Route, from: Route, next: (callback?: (vm: any) => any) => void) => any;

147

}

148

```

149

150

**Usage Examples:**

151

152

```javascript

153

// In component definition

154

export default {

155

name: 'UserProfile',

156

157

beforeRouteEnter(to, from, next) {

158

// Component instance not yet created, so no access to `this`

159

getUserData(to.params.id).then(user => {

160

next(vm => {

161

// Access component instance via callback

162

vm.setUser(user);

163

});

164

});

165

},

166

167

beforeRouteUpdate(to, from, next) {

168

// Component is reused, so `this` is available

169

this.loadUser(to.params.id);

170

next();

171

},

172

173

beforeRouteLeave(to, from, next) {

174

if (this.hasUnsavedChanges) {

175

const confirmed = confirm('You have unsaved changes. Are you sure you want to leave?');

176

if (confirmed) {

177

next();

178

} else {

179

next(false); // Cancel navigation

180

}

181

} else {

182

next();

183

}

184

}

185

};

186

```

187

188

### Composition API Guards

189

190

Guards for use with composition API (Vue 2.7+ or @vue/composition-api).

191

192

```javascript { .api }

193

/**

194

* Composition API guard for route updates

195

* @param guard - Navigation guard to register

196

*/

197

function onBeforeRouteUpdate(guard: NavigationGuard): void;

198

199

/**

200

* Composition API guard for route leave

201

* @param guard - Navigation guard to register

202

*/

203

function onBeforeRouteLeave(guard: NavigationGuard): void;

204

```

205

206

**Usage Examples:**

207

208

```javascript

209

import { onBeforeRouteUpdate, onBeforeRouteLeave } from 'vue-router/composables';

210

211

export default {

212

setup() {

213

const hasUnsavedChanges = ref(false);

214

215

onBeforeRouteUpdate((to, from, next) => {

216

// Handle route parameter changes

217

if (to.params.id !== from.params.id) {

218

loadUserData(to.params.id);

219

}

220

next();

221

});

222

223

onBeforeRouteLeave((to, from, next) => {

224

if (hasUnsavedChanges.value) {

225

const confirmed = confirm('Leave without saving?');

226

next(confirmed);

227

} else {

228

next();

229

}

230

});

231

232

return {

233

hasUnsavedChanges

234

};

235

}

236

};

237

```

238

239

### Navigation Flow Control

240

241

Control navigation behavior using the next function.

242

243

```javascript { .api }

244

/**

245

* Navigation control options for next() function

246

*/

247

type NavigationGuardNext = (

248

/** Continue navigation normally */

249

to?: void |

250

/** Abort current navigation */

251

false |

252

/** Redirect to different location */

253

RawLocation |

254

/** Execute callback when navigation confirmed (beforeRouteEnter only) */

255

((vm: Vue) => any)

256

) => void;

257

```

258

259

**Usage Examples:**

260

261

```javascript

262

router.beforeEach((to, from, next) => {

263

// Continue navigation

264

next();

265

266

// Abort navigation

267

next(false);

268

269

// Redirect to different route

270

next('/login');

271

next({ name: 'login', query: { redirect: to.fullPath }});

272

273

// Multiple conditions

274

if (!isAuthenticated()) {

275

next('/login');

276

} else if (!hasPermission(to.meta.permission)) {

277

next('/unauthorized');

278

} else {

279

next();

280

}

281

});

282

283

// Callback usage in beforeRouteEnter

284

beforeRouteEnter(to, from, next) {

285

fetchUserData(to.params.id).then(userData => {

286

next(vm => {

287

vm.userData = userData;

288

});

289

});

290

}

291

```

292

293

### Error Handling in Guards

294

295

Handle errors and failed navigation attempts.

296

297

```javascript { .api }

298

/**

299

* Navigation error types

300

*/

301

enum NavigationFailureType {

302

aborted = 4,

303

cancelled = 8,

304

duplicated = 16,

305

redirected = 2

306

}

307

308

/**

309

* Check if error is a navigation failure

310

* @param error - Error to check

311

* @param type - Optional specific failure type to check for

312

* @returns True if error is navigation failure of specified type

313

*/

314

function isNavigationFailure(error: any, type?: NavigationFailureType): boolean;

315

```

316

317

**Usage Examples:**

318

319

```javascript

320

import { isNavigationFailure, NavigationFailureType } from 'vue-router';

321

322

// Handle navigation errors

323

router.push('/some-route').catch(error => {

324

if (isNavigationFailure(error, NavigationFailureType.aborted)) {

325

console.log('Navigation was aborted');

326

} else if (isNavigationFailure(error, NavigationFailureType.duplicated)) {

327

console.log('Navigation to same location');

328

} else {

329

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

330

}

331

});

332

333

// Global error handling

334

router.onError(error => {

335

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

336

// Handle errors globally

337

});

338

339

// Guard error handling

340

router.beforeEach(async (to, from, next) => {

341

try {

342

await validateRoute(to);

343

next();

344

} catch (error) {

345

console.error('Route validation failed:', error);

346

next('/error');

347

}

348

});

349

```

350

351

### Guard Execution Order

352

353

Understanding the complete navigation resolution flow.

354

355

```javascript { .api }

356

/**

357

* Complete navigation resolution flow:

358

* 1. Navigation triggered

359

* 2. Call beforeRouteLeave guards in deactivated components

360

* 3. Call global beforeEach guards

361

* 4. Call beforeRouteUpdate guards in reused components

362

* 5. Call beforeEnter in route configs

363

* 6. Resolve async route components

364

* 7. Call beforeRouteEnter in activated components

365

* 8. Call global beforeResolve guards

366

* 9. Navigation confirmed

367

* 10. Call global afterEach hooks

368

* 11. DOM updates triggered

369

* 12. Call callbacks passed to next in beforeRouteEnter guards

370

*/

371

```

372

373

**Usage Example:**

374

375

```javascript

376

// Complete guard setup demonstrating execution order

377

export default {

378

// Component guard (step 7)

379

beforeRouteEnter(to, from, next) {

380

console.log('7. beforeRouteEnter');

381

next();

382

},

383

384

// Component guard (step 4)

385

beforeRouteUpdate(to, from, next) {

386

console.log('4. beforeRouteUpdate');

387

next();

388

},

389

390

// Component guard (step 2)

391

beforeRouteLeave(to, from, next) {

392

console.log('2. beforeRouteLeave');

393

next();

394

}

395

};

396

397

// Route config guard (step 5)

398

const routes = [{

399

path: '/example',

400

component: ExampleComponent,

401

beforeEnter: (to, from, next) => {

402

console.log('5. beforeEnter');

403

next();

404

}

405

}];

406

407

// Global guards

408

router.beforeEach((to, from, next) => {

409

console.log('3. global beforeEach');

410

next();

411

});

412

413

router.beforeResolve((to, from, next) => {

414

console.log('8. global beforeResolve');

415

next();

416

});

417

418

router.afterEach((to, from) => {

419

console.log('10. global afterEach');

420

});

421

```

422

423

## Types

424

425

```javascript { .api }

426

interface NavigationFailure extends Error {

427

from: Route;

428

to: Route;

429

type: NavigationFailureType.aborted | NavigationFailureType.cancelled | NavigationFailureType.duplicated;

430

}

431

432

type ErrorHandler = (err: Error) => void;

433

```