onRenderClient() hook

Environment: client.

The onRenderClient() hook defines how pages are hydrated and rendered on the client-side.

If you use a UI framework Vike extension (vike-react/vike-vue/vike-solid), then you don't need to define onRenderClient() as it's already defined by vike-react/vike-vue/vike-solid.

// +onRenderClient.js
// Environment: browser
 
import { renderToDom, hydrateDom } from 'some-ui-framework'
 
export { onRenderClient }
 
async function onRenderClient(pageContext) {
  const { Page } = pageContext
 
  // SPA:
  await renderToDom(Page)
 
  // SSR:
  await hydrateDom(Page)
}

Where:

  • pageContext.Page is the Page value of the page that is being rendered, see API > <Page>.
  • pageContext is a subset of the pageContext defined on the server-side.

You can use passToClient to determine what subset of pageContext is sent to the browser.

See Render Modes (SPA, SSR, SSG, HTML-only) and Client Routing for illustrations of conditional DOM hydration, for supporting both SPA and SSR.

SPA vs SSR

When implementing SSR, the client-side onRenderClient() hook works in tandem with the server-side onRenderHtml() hook: the server-side onRenderHtml() hook renders the page to HTML and the client-side onRenderClient() hook hydrates the HTML.

When implementing an SPA, then the client-side onRenderClient() hook is solely responsible for rendering the page. (There is still a server-side onRenderHtml() hook but it only renders the HTML shell; it doesn't render pageContext.Page to HTML.)

See Render Modes (SPA, SSR, SSG, HTML-only).

Multiple onRenderClient() hooks

If you create /pages/star-wars/+onRenderClient.js then you define how /pages/star-wars/+Page.js is rendered while overriding the global onRenderClient() hook.

By defining multiple onRenderClient() hooks, you can define different renderings for different pages. See Multiple renderer/.

TypeScript

// /**/+onRenderClient.ts (usually /renderer/+onRenderClient.ts)
// Environment: browser
 
export { onRenderClient }
 
import type { OnRenderClientAsync } from 'vike/types'
import { hydrateDom } from 'some-ui-framework'
 
const onRenderClient: OnRenderClientAsync = async (
  pageContext
): ReturnType<OnRenderClientAsync> => {
  // ...
}

See also