Server Side Rendering (SSR)
Vuetify Nuxt Module supports SSR out of the box. It will automatically detect if you are using SSR and configure Vuetify accordingly.
The module includes support for the following HTTP Client hints, check SSR HTTP Client hints for more details:
WARNING
The HTTP Client hints headers listed above are still in draft, and only Chromium based browsers support them: Chrome, Edge, Chromium and Opera.
Vuetify SASS Variables
If you are customising Vuetify SASS Variables via configFile module option with SSR enabled, you have to disable features.inlineStyles
(experimental.inlineSSRStyles
for Nuxt version prior to 3.9.0
) in your Nuxt config file, otherwise you will get an error when building your application:
// Nuxt config file
export default defineNuxtConfig({
ssr: true,
modules: ['vuetify-nuxt-module'],
vuetify: {
moduleOptions: {
/* other module options */
styles: { configFile: '/settings.scss' }
},
vuetifyOptions: {
/* vuetify options */
}
},
/* For Nuxt 3.9.0+ */
features: {
inlineStyles: false
},
/* For Nuxt prior to 3.9.0
experimental: {
inlineSSRStyles: false
}
*/
})
Vuetify Themes
If you're using multiple Vuetify Themes with SSR enabled, Vuetify useTheme will not work since there is no way to know which theme to use in the server (the server will use the default theme).
This module provides support to restore the theme using prefers-color-scheme
, check Sec-CH-Prefers-Color-Scheme for more details.
Alternatively, you will need to add some logic in the client to restore the theme after hydration.
For example, if you want to use dark
and light
Vuetify Themes restoring the initial value using prefers-color-scheme
and localStorage
, you can use useDark and useToogle composables from VueUse in the following way:
// composables/useCustomTheme.ts
export function useCustomTheme() {
const { $vuetify } = useNuxtApp()
const isDark = useDark({
valueDark: 'dark',
valueLight: 'light',
initialValue: 'light',
onChanged: (dark: boolean) => {
$vuetify.theme.global.name.value = dark ? 'dark' : 'light'
},
})
const toggle = useToggle(isDark)
return { isDark, toggle }
}
then, in your App.vue
or layout templates, you can use previous composable to restore the theme:
<script setup>
import { useCustomTheme } from '~/composables/useCustomTheme'
const { isDark } = useCustomTheme()
</script>
<template>
<VApp :theme="isDark ? 'dark' : 'light'">
<!-- your content here -->
</VApp>
</template>
Vuetify Display
If you're using Vuetify useDisplay composable with SSR enabled, there is only one way for the server to get the client's width and height (still in draft): use the Sec-CH-Viewport-Width and Sec-CH-Viewport-Height headers respectively, will not work for the initial request.
Check SSR HTTP Client hints for more details.
SSR HTTP Client hints
You can enable SSR HTTP Client hints using the ssrClientHints
module option:
viewportSize
: enableSec-CH-Viewport-Width
andSec-CH-Viewport-Height
headers (defaults tofalse
)?prefersColorScheme
: enableSec-CH-Prefers-Color-Scheme
header (defaults tofalse
)? Check Sec-CH-Prefers-Color-Scheme for more detailsprefersReducedMotion
:Sec-CH-Prefers-Reduced-Motion
header (defaults tofalse
)?
If you enable prefersReducedMotion
option, you should handle it with a Nuxt plugin registering the vuetify:ssr-client-hints
hook. Your Nuxt plugin hook will be only called on the server with the Vuetify options and the ssrClientHints
as parameter. Before calling your vuetify:ssr-client-hints
hook, this module will configure vuetifyOptions.ssr
and the global Vuetify theme
properly when ssrClientHints.viewportSize
and ssrClientHints.prefersColorScheme
are enabled.
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('vuetify:ssr-client-hints', ({ vuetifyOptions, ssrClientHints, ssrClientHintsConfiguration }) => {
// your logic here
})
})
where:
vuetifyOptions
is the configuration for the Vuetify instance (if you need to update some option)ssrClientHints
are the client hints extracted from the request headers (the full definition can be found in the types.ts in the#app
module augmentation)ssrClientHintsConfiguration
is the client hints configuration (the full definition can be found in thevirtual:vuetify-ssr-client-hints-configuration
declaration in the configuration.ts module)
This module will expose the $ssrClientHints
property in the Nuxt App instance (useNuxtApp().$ssrClientHints
) for the headers received from the client (all the properties that are not enabled in the module option will be undefined
), check the module augmentation for #app
in the types.ts module for the full definition.
Reload on First Request
Browsers that support any of the HTTP Client hints will send them only after the first request. This module provides support to reload the page when the browser hits the server for the first time.
To enable this feature, you must configure ssrClientHints.reloadOnFirstRequest
to true
in the module options.
Sec-CH-Prefers-Color-Scheme
This module provides support to access to the prefers-color-scheme
user's preference in the server side, it will not work on first request.
To enable this feature, you must configure ssrClientHints.prefersColorScheme
to true
in the module options. To access the value in the server, you can use the vuetify:ssr-client-hints
hook in your custom Nuxt plugin or using the $ssrClientHints
property in the Nuxt App instance (useNuxtApp().$ssrClientHints
).
WARNING
Since the headers sent by the user agent may not be accurate, from time to time your application will get some hydration mismatch warnings in the console.
If you resize the window while your application is loading then you may get a mismatch hydration warning in the console.
Multiple Themes
This module also provides support for multiple themes via custom HTTP cookie.
To enable this feature, add the following module options:
ssrClientHints.prefersColorScheme
totrue
ssrClientHints.prefersColorSchemeOptions
: can be an empty object
where ssrClientHints.prefersColorSchemeOptions
is an object with the following properties:
baseUrl
: the cookie path (defaults to/
)cookieName
: the cookie name to store the theme name (defaults tocolor-scheme
)darkThemeName
: the theme name to be used when the user's preference isdark
(defaults todark
)lightThemeName
: the theme name to be used when the user's preference islight
(defaults tolight
)useBrowserThemeOnly
: this flag can be used when your application provides a custom dark and light themes, but will not provide a theme selector, i.e., the theme selector will be the one provided by the browser (defaults tofalse
)
You also need to configure the default Vuetify theme in the vuetifyOptions
module option, should be darkThemeName
or lightThemeName
, otherwise you will get an error.
darkThemeName
and lightThemeName
will be used by the module for the initial theme configuration, when the user changes the application theme (via useNuxtApp().$vuetify.theme.global.name
), the module will update the cookie with the selected theme.
The module will add the cookie with the following properties:
Path
tonuxt.options.app.baseURL
(defaults to/
)Expires
to 365 days (will be updated on every page refresh)SameSite
toLax