When using Nuxt UI with Nuxt.js framework, SSR server will fully work out of the box. However, when using it with pure Vue.js, you will need to pay attention to some details to make it function as expected.
Nuxt UI, by default, injects to the <head> of the document color variables that are used across all components. Since the document is not managed by the UI library in the Vue.js SSR, you will need to inject that manually.
You can do that by using @unhead in the following way:
import { createHead, renderSSRHead } from '@unhead/vue/server';
// Create the header with unhead
const head = createHead();
// Render SSR header and append it to the SSR application instance
const payload = await renderSSRHead(head);
app.head.push(payload.headTags);
Below is a full working example for Inertia.js SSR:
import { createInertiaApp } from '@inertiajs/vue3';
import createServer from '@inertiajs/vue3/server';
import ui from '@nuxt/ui/vue-plugin';
import { createHead, renderSSRHead } from '@unhead/vue/server';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { createSSRApp, DefineComponent, h } from 'vue';
import { renderToString } from 'vue/server-renderer';
import PersistentLayout from './layouts/PersistentLayout.vue';
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 },
);
The same goes to the color scheme detection. To avoid flashings in the SSR because of the selected color scheme difference, you will need to detect the user's color scheme before the application initialization.
Adding the script below to the <head> of your document will detect if the user is using dark theme, and therefore, render the SSR in the dark theme as well.
<script>
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');
}
</script>
Unfortunately displaying icons with the SSR server of the Vue.js version is currently not supported. The icons will only be displayed after the application is initialized at the user's end.