NuOrder's avatar

Inertia SSR - error

When I use component:

and try to compile project nom run build:ssr then run: php artisan inertia:start-ssr

viewing webpage with disabled javascript shutdown inertia SSR server with error:

resolveComponent=fn<resolveComponent> ... >
at <App>
file:///project/node_modules/@inertiajs/vue3/dist/index.esm.js:1724 this.observer = new IntersectionObserver(
^

ReferenceError: IntersectionObserver is not defined
at Proxy.registerObserver (file:///project/node_modules/@inertiajs/vue3/dist/index.esm.js:1724:27)

how can I render SSR page with using "WhenVisible" component ?

Here is my SSR.js config file:

import '@/../css/core.css' import '@/../css/app.scss' import {createInertiaApp, Head, Link, WhenVisible} from '@inertiajs/vue3' import {resolvePageComponent} from 'laravel-vite-plugin/inertia-helpers'; import createServer from '@inertiajs/vue3/server' import {renderToString} from '@vue/server-renderer' import {createSSRApp, h} from 'vue' import {createPinia} from 'pinia' import Layout from '@/shared/Layout.vue'

const pina = createPinia() createServer(page => createInertiaApp({ page, render: renderToString, resolve: name => { const page = resolvePageComponent(./Pages/${name}.vue, import.meta.glob('./Pages/**/*.vue')); page.then((module) => module.default.layout = module.c || Layout) return page }, setup({App, props, plugin}) { return createSSRApp({ render: () => h(App, props), }).use(plugin).use(pina).component('Head', Head).component('Link', Link).component('WhenVisible', WhenVisible) } }), {cluster: false} )

0 likes
1 reply
LaryAI's avatar
Level 58

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 IntersectionObserver is not available in SSR.
  • Render WhenVisible only on client-side (not on server during SSR).
  • Use Vue's <client-only> or conditional rendering with a mounted() flag.
  • Or, guard the usage of IntersectionObserver with a typeof 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!

Please or to participate in this conversation.