I'm new with Vite + SSR and I am using Vite SSR template with mantine UI and rtk and rrd with that I am getting this following errors and count found anyway around or solving this
I tried to look through the client side html and server side html but I'm helpless with the mantine Classes and how the server rendering it with the different markup as styles.
I would appreciate if anyone has gone through this and if they can guide me further what's the steps to correct this hydration error.
1) Expected server HTML to contain a matching <style> in <div>.
at style
at MantineClasses
2) react-dom.development.js:12507 Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
at throwOnHydrationMismatch
3) Warning: An error occurred during hydration. The server HTML was replaced with client content in <div>.
4) Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
5) Uncaught Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
This is my basic set-up files
entry-server.ts
import React from "react";
import ReactDOMServer from "react-dom/server";
import { StaticRouter } from "react-router-dom/server";
import App from "./App";
import { Provider } from "react-redux";
import store from "./redux/store";
interface IRenderProps {
path: string;
}
export const render = ({ path }: IRenderProps) => {
return ReactDOMServer.renderToString(
<Provider store={store}>
<StaticRouter location={path}>
<App />
</StaticRouter>
</Provider>
);
};
entry-client.ts
import "./index.css";
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
import { Provider } from "react-redux";
import store from "./redux/store";
ReactDOM.hydrateRoot(
document.getElementById("root") as HTMLElement,
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
);
server.js
import fs from 'node:fs/promises'
import express from 'express'
// Constants
const isProduction = process.env.NODE_ENV === 'production'
const port = process.env.PORT || 3000
const base = process.env.BASE || '/'
// Cached production assets
const templateHtml = isProduction
? await fs.readFile('./dist/client/index.html', 'utf-8')
: ''
const ssrManifest = isProduction
? await fs.readFile('./dist/client/ssr-manifest.json', 'utf-8')
: undefined
// Create http server
const app = express()
// Add Vite or respective production middlewares
let vite
if (!isProduction) {
const { createServer } = await import('vite')
vite = await createServer({
server: { middlewareMode: true },
appType: 'custom',
base
})
app.use(vite.middlewares)
} else {
const compression = (await import('compression')).default
const sirv = (await import('sirv')).default
app.use(compression())
app.use(base, sirv('./dist/client', { extensions: [] }))
}
// Serve HTML
app.use('*', async (req, res) => {
try {
const url = req.originalUrl.replace(base, '')
let template
let render
if (!isProduction) {
// Always read fresh template in development
template = await fs.readFile('./index.html', 'utf-8')
template = await vite.transformIndexHtml(url, template)
render = (await vite.ssrLoadModule('/src/entry-server.tsx')).render
} else {
template = templateHtml
render = (await import('./dist/server/entry-server.js')).render
}
const rendered = await render(url, ssrManifest)
const html = template
.replace(`<!--app-head-->`, rendered.head ?? '')
.replace(`<!--app-html-->`, rendered.html ?? '')
res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
} catch (e) {
vite?.ssrFixStacktrace(e)
console.log(e.stack)
res.status(500).end(e.stack)
}
})
// Start http server
app.listen(port, () => {
console.log(`Server started at http://localhost:${port}`)
})
App.ts
import { useState } from "react";
import { MantineProvider } from "@mantine/core";
import '@mantine/core/styles/global.css';
import '@mantine/core/styles.css';
import Routing from "./routes/Routing";
function App() {
return (
<MantineProvider>
<Routing />
</MantineProvider>
);
}
export default App;