pageContext.isHydration: Whether the page is rendered to HTML. When using Client Routing, the value is true for the first page the user navigates to, and false for any subsequent navigation. (When using Server Routing, the value is always true.) (If the page doesn't throw an error then it's equivalent to !pageContext.isClientSideNavigation, otherwise the error page is rendered and thus pageContext.isHydration is false whereas !pageContext.isClientSideNavigation is true.)
pageContext.isBackwardNavigation: Whether the user is navigating back in history. The value is true when the user clicks on his browser's backward navigation button, or when invoking history.back(). The isBackwardNavigation property only works with Client Routing. (The value is always null when using Server Routing.)
pageContext.is404: If an error occurs, whether the error is a 404 Page Not Found or a 500 Internal Error, see API > Error page.
pageContext.isClientSideNavigation: Whether the page was navigated by the client-side router. In other words, when using Client Routing, the value is false for the first page the user visits, and true for any subsequent navigation. (When using Server Routing, the value is always false.)
app.get('*', async (req) => { const pageContextInit = { urlOriginal: req.url, headersOriginal: req.headers, // *************************************** // **** Custom pageContext properties **** // *************************************** // Common use case: make information about logged-in user available at pageContext.user user: req.user, // Or any other value: // pageContext.anyCustomProp anyCustomProp: 'some-value' } const pageContext = await renderPage(pageContextInit) // ...})
Using the upcoming hook onBoot() (#962). It isn't implement yet, add a comment to the GitHub issue if you need it. (We expect onBoot() to be particularly useful for pre-rendered apps.)
export async function onBeforeRender() { return { pageContext: { // *************************************** // **** Custom pageContext properties **** // *************************************** // Common use case: make the state management's initial state available. // pageContext.initialStoreState – initial store state initialStoreState: pageRendered.store.state, // pageContext.anyCustomProp anyCustomProp: 'some-value' } }}
Setting pageContext.initialStoreState is a common use case for integrating state management tools, see Integration > Stores.
import type { // For code loaded in client and server PageContext, // For code loaded in client only PageContextClient, // For code loaded in server only PageContextServer} from 'vike/types'
To extend and/or refine Vike's types PageContext/PageContextServer/PageContextClient, use the global interface Vike.PageContext:
declare global { namespace Vike { interface PageContext { // Type of pageContext.user user?: { name: string id: string isAdmin: boolean } // Refine type of pageContext.Page (it's `unknown` by default) Page: () => JSX.Element } }}// If you define Vike.PageContext in a .d.ts file then// make sure there is at least one export/import statment.// Tell TypeScript this file isn't an ambient module:export {}
import type { // For code loaded in client and server PageContextWithServerRouting as PageContext, // For code loaded in client only PageContextClientWithServerRouting as PageContextClient, // For code loaded in server only PageContextServer} from 'vike/types'
Lifecycle
The main purpose of pageContext is to hold the information that is needed for rendering the page.
On the server-side, upon a new incoming HTTP request, a new pageContext object is created and used for rendering the HTML that is included in the HTTP response. The pageContext object is discarded after the HTML response is sent.
On the client-side, upon client-side page navigation, the pageContext object of the previous page is discarded and a new pageContext object is created.
At build-time, upon pre-rendering, a pageContext object is created for each URL and saved at dist/client/${url}/index.pageContext.json.
Vike adds information to pageContext only while rendering the page, and we recommend to treat pageContext as immutable after the rendering of the page has finished. Consequently:
We recommend against using pageContext to store UI state. (Use a proper state management tool instead.)
If you use pre-rendering, then the pageContext object of each URL is set in stone already at build-time.