Initial Commit
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
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 = `<script>window.__SUAVEPLAN_E2E_INITIAL_LOCALE__=${JSON.stringify(resolvedLocale)};window.__SUAVEPLAN_E2E_SSR__=true;</script>`;
|
||||
const finalHtml = transformed
|
||||
.replace(`<div id="root"></div>`, `<div id="root">${html}</div>${bootstrap}`)
|
||||
.replace(`<html lang="en-GB" dir="ltr">`, `<html lang="${resolvedLocale}" dir="${resolvedLocale.startsWith("ar") ? "rtl" : "ltr"}">`);
|
||||
res.statusCode = 200;
|
||||
res.setHeader("Content-Type", "text/html");
|
||||
res.end(finalHtml);
|
||||
} catch (error) {
|
||||
next(error as Error);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user