Next font sever/client mismatch in app dir

Hi trying to include a style tag which sets css vars based on next font but get the following error
Text content did not match. Server: ":root {
--font-p: '__Montserrat_656221', '__Montserrat_Fallback_656221';
}" Client: ":root {
--font-p: '__Montserrat_656221', '__Montserrat_Fallback_656221';
}"
at style
at body
at html
at RedirectErrorBoundary
...
at Router (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/app-router.js:90:11)
at ErrorBoundaryHandler (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/error-boundary.js:62:9)
at ErrorBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/error-boundary.js:87:11)
at AppRouter (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/app-router.js:372:13)
at ServerRoot (webpack-internal:///(app-client)/./node_modules/next/dist/client/app-index.js:154:11)
at RSCComponent
at Root (webpack-internal:///(app-client)/./node_modules/next/dist/client/app-index.js:171:11)
Text content did not match. Server: ":root {
--font-p: '__Montserrat_656221', '__Montserrat_Fallback_656221';
}" Client: ":root {
--font-p: '__Montserrat_656221', '__Montserrat_Fallback_656221';
}"
at style
at body
at html
at RedirectErrorBoundary
...
at Router (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/app-router.js:90:11)
at ErrorBoundaryHandler (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/error-boundary.js:62:9)
at ErrorBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/error-boundary.js:87:11)
at AppRouter (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/app-router.js:372:13)
at ServerRoot (webpack-internal:///(app-client)/./node_modules/next/dist/client/app-index.js:154:11)
at RSCComponent
at Root (webpack-internal:///(app-client)/./node_modules/next/dist/client/app-index.js:171:11)
seems likes next font is adding ' on the server, tried logging it but didn't appear in logs ty for any help here is the layout.tsx (root layout)
import { Montserrat } from 'next/font/google'

const font_p = Montserrat({
subsets: ['latin'],
variable: '--font-p',
})

const var_styles = `:root {
--font-p: ${font_p.style.fontFamily};
}`

export default async function RootLayout({ children }: {children: React.ReactNode,}) {

return <html lang="en">

<body className={`${font_p.variable}`}>

<style>{var_styles}</style>

{children}
</body>

</html>
}
import { Montserrat } from 'next/font/google'

const font_p = Montserrat({
subsets: ['latin'],
variable: '--font-p',
})

const var_styles = `:root {
--font-p: ${font_p.style.fontFamily};
}`

export default async function RootLayout({ children }: {children: React.ReactNode,}) {

return <html lang="en">

<body className={`${font_p.variable}`}>

<style>{var_styles}</style>

{children}
</body>

</html>
}
Solution:
It looks like it’s encoding the '. What happens if you dangerously set html for var styles
Jump to solution
6 Replies
Solution
sathuros
sathuros14mo ago
It looks like it’s encoding the '. What happens if you dangerously set html for var styles
sathuros
sathuros14mo ago
That said, I don’t think you need to use the style tag. It should be applying it automatically
ja_iy
ja_iy14mo ago
ty the encoding was the issue : D I'm using tailwind & my tailwind config references the css var, so when the app loads it briefly flashes the font as the var is undefined, so have to set it in the html wrote this to fix the error
const filter_chars = (str:string) => str.replace(/['|,]/g, "");

export function RootCssVars({vars}:{vars:[name:string, value:string][]}) {

const var_style = vars
.map(([name, value]) => `--${name}: ${filter_chars(value)};`)
.join('\n')

return <style>{`
:root {
${var_style}
}
`}</style>
}
const filter_chars = (str:string) => str.replace(/['|,]/g, "");

export function RootCssVars({vars}:{vars:[name:string, value:string][]}) {

const var_style = vars
.map(([name, value]) => `--${name}: ${filter_chars(value)};`)
.join('\n')

return <style>{`
:root {
${var_style}
}
`}</style>
}
thanks again OwO
ja_iy
ja_iy14mo ago
never mind <body className={${font_p.variable}}> is performing the same functionality I'm implementing by setting the css var it seems, but the flashing of the font still remains T~T
sathuros
sathuros14mo ago
Optimizing: Fonts
Optimize your application's web fonts with the built-in next/font loaders.
ja_iy
ja_iy14mo ago
ty that's how I have it setup except for the className on the body, after switching it to the html the brief flash was even shorter : D was also reading this https://www.lydiahallie.io/blog/optimizing-webfonts-in-nextjs-13 and it seems that a brief flash is inevitable as long as the page loads before the font does, which is probably the case if I'm building and running locally, & reloading the page without the cache
Optimizing Web Fonts in Next.js 13
Learn more about optimizing web fonts and the @next/font module in Next.js 13.