import react from "@vitejs/plugin-react"; import { defineConfig } from "vite"; export default defineConfig({ root: __dirname, server: { port: 5273, strictPort: true, host: "127.0.0.1", }, plugins: [react(), ssrMiddlewarePlugin()], optimizeDeps: { // Force pre-bundle of the workspace package so Vite resolves the // exports map correctly the first hit. include: ["@suaveplan/react-i18n", "@suaveplan/i18n"], }, }); /** * Adds a `/ssr/:locale` endpoint that renders the React tree on the * server, inlines the markup into the HTML template, and adds a tiny * bootstrap script that flips `entry-client.tsx` into hydration mode. * * This is the SSR scenario surface exercised by the Playwright spec — * the regular `/` route serves the standard CSR build. */ function ssrMiddlewarePlugin(): import("vite").Plugin { return { name: "react-i18n-e2e-ssr", configureServer(server) { server.middlewares.use(async (req, res, next) => { if (req.url === undefined || !req.url.startsWith("/ssr/")) { next(); return; } try { const localeFromUrl = req.url.replace(/^\/ssr\//, "").split("?")[0] ?? ""; const locale = decodeURIComponent(localeFromUrl); const templatePath = `${__dirname}/index.html`; const fs = await import("node:fs/promises"); const rawTemplate = await fs.readFile(templatePath, "utf8"); const transformed = await server.transformIndexHtml(req.url, rawTemplate); const mod = await server.ssrLoadModule("/src/entry-server.tsx"); const renderFn = (mod as { render: (l: string) => { html: string; locale: string } }).render; const { html, locale: resolvedLocale } = renderFn(locale); const bootstrap = ``; const finalHtml = transformed .replace(`
`, `
${html}
${bootstrap}`) .replace(``, ``); res.statusCode = 200; res.setHeader("Content-Type", "text/html"); res.end(finalHtml); } catch (error) { next(error as Error); } }); }, }; }