+guard()
hook
The guard()
hook enables you to protect pages from unauthorized access.
// /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:
- It can be asynchronous. (Unlike Route Functions which are always synchronous.)
- A single
guard()
hook can apply to one or multiple pages. - It's always used together with
throw render()
orthrow redirect()
. (Theguard()
hook doesn't accept any return value.)
Execution order
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.
Whenever possible, we recommend using
throw render()
/throw redirect()
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: Usethrow render()
/throw redirect()
inside React/Vue/Solid components.
Environment
Default
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 only executes on the server-side.
+guard.server.js
If you define +guard.server.js
then guard()
is always executed and only loaded on the server.
See also: see Guides >
.server.js
/.client.js
/.shared.js
Use other hooks
For more control on where and when your guarding logic is executed, consider using throw render()
/ throw redirect()
inside another hook than guard()
.