⚠️ The
vite-plugin-ssr project has been renamed
Vike.
- If you are already using vite-plugin-ssr then migrate to Vike.
- For new projects, don't use vite-plugin-ssr but use Vike instead.
pageContext
The pageContext object holds information about the current page.
Once the page is rendered we recommend treating pageContext as immutable, see Lifecycle.
Built-in
Built-in properties:
-
pageContext.Page: the export { Page } or export default of the page's .page.js file.
-
pageContext.routeParams: the route parameters. (E.g. pageContext.routeParams.movieId for a page with a Route String /movie/@movieId.)
-
pageContext.urlOriginal: the current URL.
On the server-side, pageContext.urlOriginal is the value you passed at the server middleware:
// Server middleware
app.get('*', async (req, res, next) => {
const pageContextInit = {}
// `pageContext.urlOriginal` is defined here
pageContextInit.urlOriginal = req.url
const result = await renderPage(pageContextInit)
/* ... */
})
On the client-side, when using Server Routing, the pageContext.urlOriginal value is undefined (unless you use passToClient).
On the client-side, when using Client Routing, the value of pageContext.urlOriginal is the browser's current URL (window.location.href).
-
pageContext.urlPathname: alias of pageContext.urlParsed.pathname.
-
pageContext.urlParsed: URL information:
{
origin: null | string
pathname: string
pathnameOriginal: string
search: Record<string, string> // (AKA query parameters)
searchAll: Record<string, string[]>
searchOriginal: null | string
hash: string
hashOriginal: null | string
}
For example:
// https://example.com/some-base-url/hello/s%C3%A9bastien?fruit=%C3%A2pple&fruit=orânge#%C3%A2ge
{
origin: 'https://example.com',
pathname: '/hello/sébastien', // Without Base URL
pathnameOriginal: '/some-base-url/hello/s%C3%A9bastien',
search: { fruit: 'orânge' }, // (AKA query params)
searchAll: { fruit: ['âpple', 'orânge'] },
searchOriginal: '?fruit=%C3%A2pple&fruit=orânge',
hash: 'âge',
hashOriginal: '#%C3%A2ge'
}
-
pageContext.exports: See Guides > Custom Exports/Hooks.
-
pageContext.exportsAll: Same as pageContext.exports but cumulative.
-
pageContext.isHydration: Whether the current page is already rendered to HTML. When using Client Routing, the value is usually true for the first page the user navigates to, and false for any subsequent navigation. (When using Server Routing, the value is always 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.js.
-
pageContext.isClientSideNavigation: Whether the page was navigated by the 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.)
-
pageContext.abortReason: Set by throw render() and used by the error page.
-
pageContext.abortStatusCode: Set by throw render() and used by the error page.
Custom
You can define custom pageContext properties.
- Using the
onBeforeRender() hook:
export async function onBeforeRender() {
return {
pageContext: {
// ***************************************
// **** Custom pageContext properties ****
// ***************************************
// Common use case: make fetched data available over pageContext
someData: { product: { id: 123, name: 'MacBook' } }
// Or any other custom property you want
someCustomProp: 'some-value'
}
}
}
A common use case for onBeforeRender() is to fetch data: Guides > Data Fetching.
- At your vite-pugin-ssr server middleware:
app.get('*', async (req, res, next) => {
const pageContextInit = {
urlOriginal: req.url,
// ***************************************
// **** Custom pageContext properties ****
// ***************************************
// Common use case: make information about logged-in user available over pageContext
user: req.user,
// Common use case: make the cookies available over pageContext.headers.cookies
headers: req.headers,
// Or any other custom property you want
someCustomProp: 'some-value',
}
const pageContext = await renderPage(pageContextInit)
/* ... */
})
A common use case is to integrate authentication tools: Guides > Authentication.
- Using the
render() hook:
export function render() {
return {
documentHtml: escapeInject`<html><!--...--></html>`,
pageContext: {
// ***************************************
// **** Custom pageContext properties ****
// ***************************************
// Common use case: make the state management's initial store state available
initialStoreState: pageRendered.store.state,
// Or any other custom property you want
someCustomProp: 'some-value'
}
}
}
A common use case is to integrate state management tools: Integration > Data Store.
Anywhere
Any component
The pageContext object can be accessed from within any UI component, see Guides > Access pageContext anywhere.
Client-side
While some pageContext values are also available on the client-side, most values are only available in Node.js and you have to use passToClient to make them available in the browser.
When using Server Routing, the following are also available in the browser by default:
pageContext.Page
pageContext.exports
When using Client Routing, the following are also available in the browser by default:
pageContext.Page
pageContext.exports
pageContext.isHydration
pageContext.isBackwardNavigation
pageContext.routeParams
pageContext.urlOriginal
pageContext.urlPathname
pageContext.urlParsed
TypeScript
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 'vite-plugin-ssr/types'
To extend and/or refine the PageContext type, use the global interface Vike.PageContext:
Vike is the upcoming new name of vite-plugin-ssr, see #736.
declare global {
namespace Vike {
interface PageContext {
// Define type of pageContext.user
user?: {
name: string
id: string
isAdmin: boolean
}
// Define type of pageContext.pageProps
pageProps?: PageProps
// Refine type of pageContext.Page (it's `unknown` by default)
Page: (pageProps) => JSX.Element
}
}
}
type PageProps = {
movies: {
title: string
releaseDate: Date
}[]
}
// Tell TypeScript this file isn't an ambient module
export {}
If you use Server Routing:
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 'vite-plugin-ssr/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.
Vite-plugin-ssr 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.