y-l-g · GitHub

Hi,

The issue is that Inertia handles its own head management, so it doesn't pick up the tags generated by Nuxt UI's internal unhead instance during the SSR pass.

The fix is to create a dedicated unhead instance, let Nuxt UI populate it during the setup, and then asynchronously push its rendered tags into Inertia's head array just before the response is sent. This ensures Nuxt UI's styles are present in the initial HTML.

Here's my createServer in resources/js/ssr.ts:

createServer(
  (page) => {
    const head = createHead();
    return createInertiaApp({
      page,
      render: renderToString,
      resolve: (name) =>
        resolvePageComponent(
          `./pages/${name}.vue`,
          import.meta.glob<DefineComponent>("./pages/**/*.vue")
        ),
      setup: ({ App, props, plugin }) =>
        createSSRApp({ render: () => h(App, props) })
          .use(plugin)
          .use(head)
          .use(ui),
    }).then(async (app) => {
      const payload = await renderSSRHead(head);
      app.head.push(payload.headTags);
      return app;
    });
  },
  { cluster: true }
);

To prevent the theme from flashing on hydration, i use a small script in app.blade.php:

<script>
    try {
        const theme = localStorage.getItem('vueuse-color-scheme');
        if (theme === 'dark' || (theme === null && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
            document.documentElement.classList.add('dark');
        } else {
            document.documentElement.classList.remove('dark');
        }
    } catch (e) { /* ignore */ }
</script>

On a related note, I saw the Laravel starter kit still uses Ziggy, while the official Laravel kits have moved on to Wayfinder(https://github.com/laravel/vue-starter-kit/pull/178). I'd be happy to open a separate PR to update it and include these SSR fixes. I've already implemented this in my own starter kit if you want to take a look: https://github.com/y-l-g/saasterkit. By the way https://saasterkit.com is server rendered.

Let me know if this approach works for you.

Read the original on github.com ↗