diff --git a/frontend/src/__pro_stub__/i18n/register.ts b/frontend/src/__pro_stub__/i18n/register.ts new file mode 100644 index 00000000..21806329 --- /dev/null +++ b/frontend/src/__pro_stub__/i18n/register.ts @@ -0,0 +1,5 @@ +/** + * OSS stub for the overlay's i18n registration (see entry-server.tsx). + * The real module adds the "pro" namespace; here there is nothing to add. + */ +export function registerProI18n(): void {} diff --git a/frontend/src/entry-server.tsx b/frontend/src/entry-server.tsx index 83fee247..e29b778d 100644 --- a/frontend/src/entry-server.tsx +++ b/frontend/src/entry-server.tsx @@ -8,7 +8,12 @@ import React from 'react'; import { renderToString } from 'react-dom/server'; -import { MemoryRouter } from 'react-router-dom'; +// Initialise i18next with the bundled English resources before any page +// renders: without this every t() call in the SSR output came back as its +// KEY ("landing.hero.titleLine1"), which is what the prerendered bodies +// shipped once they were actually injected. +import './i18n'; +import { MemoryRouter, Routes, Route } from 'react-router-dom'; import { SEO_ROUTES } from './seoRoutes'; // ── SEO page components ───────────────────────────────────────────────────── @@ -56,6 +61,14 @@ export async function loadRouteComponents(): Promise> { if (import.meta.env.VITE_PRO_BUILD) { const m = await import('@pro/pages/marketing'); routeComponents = { ...OSS_ROUTE_COMPONENTS, ...m.MARKETING_ROUTE_COMPONENTS }; + // The overlay's own namespace ("pro": landing sections, pricing...), + // else its t() calls render as keys too. + try { + const reg = await import('@pro/i18n/register'); + reg.registerProI18n?.(); + } catch (err) { + console.warn(' ⚠ pro i18n not registered for SSR:', (err as Error).message); + } } return routeComponents; } @@ -103,9 +116,13 @@ export function getPrerenderedExampleRoutes() { */ export function renderExample(exampleId: string): string { try { + // Mounted under its real route so useParams() sees exampleId; rendered + // bare it had no params and every example page SSR'd as "not found". return renderToString( - + + } /> + , ); } catch (err) {