Environment: client.

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

The onRenderClient() and onRenderHtml() hooks are essentially the glue code between Vike and the UI framework (React/Vue/Solid/...).

If you use a UI framework Vike extension vike-react/vike-vue/vike-solid, then you don't need to (and shouldn't) 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.
  • 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