Certainly! Here’s a solution for your Inertia SSR – error when using a component like WhenVisible that utilizes IntersectionObserver in a Node (SSR) environment.
Problem Explanation
The error is:
ReferenceError: IntersectionObserver is not defined
This is because IntersectionObserver is a browser-only API and does not exist in the Node.js environment where SSR rendering occurs. When such code runs during SSR, it fails.
Solution
You need to ensure that the IntersectionObserver-related code is only run on the client/browser and not during SSR.
Here’s how you can approach this:
1. Use Client-Only Components
If you’re using Vue 3, Inertia doesn’t yet provide a built-in <client-only> component, but you can use the one from Vue:
<template>
<client-only>
<WhenVisible>
<!-- ... -->
</WhenVisible>
</client-only>
</template>
Or, if you're not using <client-only>, conditionally render the component only on the client:
<template>
<div>
<WhenVisible v-if="isClient">
<!-- ... -->
</WhenVisible>
</div>
</template>
<script>
export default {
data() {
return {
isClient: false,
}
},
mounted() {
this.isClient = true
}
}
</script>
2. Guard IntersectionObserver Usage
If you have control over the WhenVisible component (or a similar one), you can add a guard around the usage of IntersectionObserver:
if (typeof window !== 'undefined' && 'IntersectionObserver' in window) {
// Safe to use IntersectionObserver
}
3. SSR No-Op Fallback
If you want to avoid SSR errors but still want the component to render (but do nothing during SSR):
let observer
if (typeof window !== 'undefined' && 'IntersectionObserver' in window) {
observer = new IntersectionObserver(...)
}
Or in Vue component:
mounted() {
if (typeof window !== 'undefined' && 'IntersectionObserver' in window) {
// Set up observer
}
}
Summary
- The error is because
IntersectionObserveris not available in SSR. - Render
WhenVisibleonly on client-side (not on server during SSR). - Use Vue's
<client-only>or conditional rendering with amounted()flag. - Or, guard the usage of
IntersectionObserverwith atypeof window !== 'undefined'check.
Example Fix
<template>
<div>
<WhenVisible v-if="isClient">
<!-- Your content here -->
</WhenVisible>
</div>
</template>
<script>
export default {
data() {
return {
isClient: false,
}
},
mounted() {
this.isClient = true
}
}
</script>
References:
Let me know if you need a more tailored solution for your codebase!