Edit

<ClientOnly>

Environment: client, server
Provided by: vike-react/vike-vue/vike-solid

You need vike-react/vike-vue/vike-solid to be able to use <ClientOnly>. If you don't use vike-{react,vue,solid} then see Without vike-{react,vue,solid}.

Render components only on the client-side.

Features automatic code removal.

The children of <ClientOnly> are automatically removed and never loaded on the server.

import { SomeComponent } from './SomeComponent'
<ClientOnly fallback={<p>Loading...</p>}>
  <SomeComponent />
</ClientOnly>

This means <SomeComponent> can use browser-only APIs.

// SomeComponent.js
 
export { SomeComponent }
 
// ✅ Doesn't throw "window is not defined" error — it's loaded only on the client-side
console.log('Browser viewport width: ', window.innerWidth)
 
function SomeComponent() {
  // ...
}

<ClientOnly> supersedes clientOnly() — it has better performance with a simpler DX.

React

import { ClientOnly } from 'vike-react/ClientOnly'
 
function Page() {
  return (
    <ClientOnly fallback={<p>Loading...</p>}>
      <SomeComponent />
    </ClientOnly>
  )
}

Props:

  • children: Content rendered only on the client-side after hydration.
  • fallback (optional): Content shown during SSR and before hydration completes.

Vue

<template>
  <ClientOnly>
    <SomeComponent />
    <template #fallback>
      <p>Loading...</p>
    </template>
  </ClientOnly>
</template>
 
<script setup>
import { ClientOnly } from 'vike-vue/ClientOnly'
</script>
<template>
  <ClientOnly>
    <SomeComponent />
    <template #fallback>
      <p>Loading...</p>
    </template>
  </ClientOnly>
</template>
 
<script setup lang="ts">
import { ClientOnly } from 'vike-vue/ClientOnly'
</script>

Props:

  • default slot: Content rendered only on the client-side after hydration.
  • fallback slot (optional): Content shown during SSR and before hydration completes.

Solid

import { ClientOnly } from 'vike-solid/ClientOnly'
 
function Page() {
  return (
    <ClientOnly fallback={<p>Loading...</p>}>
      <SomeComponent />
    </ClientOnly>
  )
}

Props:

  • children: Content rendered only on the client-side after hydration.
  • fallback (optional): Content shown during SSR and before hydration completes.

Without vike-{react,vue,solid}

If you don't use a UI framework Vike extension vike-react/vike-vue/vike-solid, you can implement <ClientOnly> yourself.

See the source code:

See also