<ClientOnly> vs .client.vue

Yo Kapa Difference between naming a component something.client.vue and wrapping it into <ClientOnly> in the parent
2 Replies
kapa.ai
kapa.ai2w ago
Hi @Omnislash. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Hey! Here’s the difference between using the .client.vue suffix and wrapping a component in <ClientOnly> in Nuxt: .client.vue Suffix - If you name a component with the .client.vue suffix (e.g., Comments.client.vue), Nuxt will only render this component on the client side. It will not be rendered or included in the server-side output at all. - This is automatic if you use Nuxt’s auto-imports or #components imports. If you import the component explicitly by its path, it won’t be treated as client-only. - The component is mounted only on the client, and if you need to access its DOM in onMounted(), you should await nextTick() to ensure it’s available. - This approach is best for components that should never be rendered on the server, such as those relying on browser-only APIs or third-party libraries that don’t support SSR. Example:
<!-- components/Comments.client.vue -->
<template>
<div>Client-only comments</div>
</template>
<!-- components/Comments.client.vue -->
<template>
<div>Client-only comments</div>
</template>
<!-- pages/example.vue -->
<template>
<Comments />
</template>
<!-- pages/example.vue -->
<template>
<Comments />
</template>
Client Components --- <ClientOnly> Component - <ClientOnly> is a built-in Nuxt component that renders its slot content only on the client side. Anything inside <ClientOnly> will not be rendered on the server. - You can use it to wrap any component or markup that should only appear on the client, even if the component itself isn’t named with .client.vue. - It’s useful for third-party components or dynamic content that can’t be server-rendered. - You can provide a fallback (placeholder) to show while the client-only content is loading. Example:
<template>
<ClientOnly fallbackTag="span">
<Comments />
<template #fallback>
<p>Loading comments...</p>
</template>
</ClientOnly>
</template>
<template>
<ClientOnly fallbackTag="span">
<Comments />
<template #fallback>
<p>Loading comments...</p>
</template>
</ClientOnly>
</template>
<ClientOnly> API --- Key Differences - Scope: .client.vue affects the component itself globally; <ClientOnly> is used at the usage site and can wrap any content. - Auto-import: .client.vue only works with Nuxt’s auto-imports; <ClientOnly> works with any component. - Fallback: <ClientOnly> allows you to specify a fallback for SSR, while .client.vue components simply don’t render on the server. In summary:
Use .client.vue for components that should always be client-only, everywhere they’re used. Use <ClientOnly> when you want to conditionally render something on the client, or when you can’t (or don’t want to) rename the component file. Let me know if you want a code example for a specific use case! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@305772639438503936> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?