// pages/+onCreatePageContext.server.ts// Environment: serverimport type { PageContextServer } from 'vike/types'// This hook is called upon new incoming HTTP requestsexport async function onCreatePageContext(pageContext: PageContextServer) { // vike-server exposes the request object at pageContext.runtime.req const { req } = pageContext.runtime // Authentication middlewares (e.g. Passport.js and Grant) usually set req.user // to expose information about the logged-in user. const { user } = req // Or, when using a third-party authentication provider (e.g. Auth0): const user = await someAuthApi.getUser(req.headers) // Select the properties you want to make available everywhere pageContext.user = { firstName: user.firstName, email: user.email }}declare global { namespace Vike { interface PageContext { user?: { firstName: string email: string } } }}
// pages/+config.tsimport type { Config } from 'vike/types'export default { // Make pageContext.user available on the client-side passToClient: [{ prop: 'user', // Send it only once: upon client-side navigation re-use the initial pageContext.user value once: true }]} satisfies Config
// pages/+onCreateGlobalContext.client.js// Environment: clientexport async function onCreateGlobalContext(globalContext) { // Fetch user information from your backend (or an authentication SaaS platform) const user = await fetchUseInfo() globalContext.user = user}
// /pages/admin/+guard.jsimport { render, redirect } from 'vike/abort'export const guard = (pageContext) => { const { user } = pageContext if (user === null) { // Render the login page while preserving the URL. (This is novel technique // which we explain down below.) throw render('/login') /* The more traditional way, redirect the user: throw redirect('/login') */ } if (user.role !== 'admin') { // Render the error page and show message to the user throw render(403, 'Only admins are allowed to access this page.') }}
Using render('/login') instead of redirect('/login') allows the URL to be preserved during the entire login flow:
Unauthenticated user goes to URL /admin and sees the login page. (URL is /admin.)
User fills the sign-in form and successfully logs in. (URL is still /admin.)
Reload the page, the user now sees the admin page. (URL is still /admin.)
You can also define a guard() hook that applies to multiple pages:
// /pages/+guard.js// This guard() hook applies to all pages: the file is located at /pages/+guard.js// and therefore applies to all /pages/**/+Page.jsimport { render } from 'vike/abort'export const guard = (pageContext) => { if (!pageContext.user) { throw render('/login') }}