Edit

+guard() hook

Environment: server (configurable)
Local
Non-cumulative
Provided by: vike

The guard() hook enables you to protect pages from unauthorized access.

// /pages/admin/+guard.js
 
export { guard }
 
import { render } from 'vike/abort'
 
// This guard() hook protects all pages /pages/admin/**/+Page.js
 
async function guard(pageContext) {
  if (!pageContext.user.isAdmin) {
    throw render(401, "You aren't allowed to access this page.")
  }
}
// /pages/admin/+guard.ts
 
export { guard }
 
import type { PageContextServer } from 'vike/types'
import { render } from 'vike/abort'
 
// This guard() hook protects all pages /pages/admin/**/+Page.ts
 
async function guard(pageContext: PageContextServer) {
  if (!pageContext.user.isAdmin) {
    throw render(401, "You aren't allowed to access this page.")
  }
}

Note that:

Execution order

By default, the guard() hook is the first hook called after the routing is evaluated. Most notably, it's always called before the data() hook. See API > Hooks > Lifecycle.

This guarantees that throw render() / throw redirect() is called before fetching data. (Unauthorized data fetching can be problematic.)

If you want to guard your pages after or during fetching data, then use throw render() / throw redirect() inside your data() hook instead (or any another Vike hook).

For being able to use throw render() / throw redirect() inside UI components, see #1707: Use throw render() / throw redirect() inside React/Vue/Solid components.

For more control on where and when your guarding logic is executed, consider using throw render() / throw redirect() inside another hook than guard().

Environment

The guard() hook is called in the same environment as data(). In other words, it's always called on the server-side unless you configure data() to run on the client-side.

If the page doesn't have a data() hook, then guard() executes in the environment where routing happens. See API > Hooks > Lifecycle.

By default, the guard() hook (and the entire +guard.js file) is always loaded in both the client and server — even if it executes only on the client- or server-side.

+guard.server.js

If you define +guard.server.js then it's executed and loaded only on the server.

See: Guides > .server.js / .client.js / .shared.js

+guard.client.js

If you define +guard.client.js then it's executed and loaded only on the client.

See: Guides > .server.js / .client.js / .shared.js

Usually, the motivation for defining +guard.client.js is to implement authorization for an SSG app that doesn't have any server. But keep in mind that +guard.client.js cannot prevent a page from being pre-rendered to HTML — pre-rendering happens at build-time while authorization is done at request-time.

Upon the first page the user visits, +guard.client.js is called before rendering/hydrating. If that's an issue, consider:

Aborting hydration works with React but not with Vue.

See also