Skip to content

Commit 0066487

Browse files
authored
Upgrade React Router to v8 (#153)
* Upgrade React Router to v8 Bumps react-router, @react-router/dev, @react-router/node, and @react-router/serve to 8.2.0, and remix-i18next to 8.0.0 (required, since it only supports React Router v8 starting at its own v8). - Migrate i18next.server.ts to remix-i18next's v8 middleware API (createI18nextMiddleware), replacing the removed RemixI18Next class and its /server, /client, /react subpath exports. - Register the i18next middleware in root.tsx so getLocale/getInstance work from route context; replace useChangeLanguage with a useTranslation + useEffect sync. - Fix explicit ns handling in the client and server i18next config: defaultNS and ns are independent i18next options, so dropping the namespace helpers without setting ns explicitly would have made the app preload the wrong ("translation") namespace instead of "common". - Rename unstable_pattern/unstable_url to pattern/url across loader and action test helpers (now stable, unprefixed fields in v8). - Update meta() functions in cmsui, contents, and publicui routes to read match.loaderData instead of the removed match.data. - Remove the now-default v8_middleware future flag. - Bump apps/aurora engines to Node >=22.22.0. * Fix incidental prettier version bump in lockfile Running pnpm install for the React Router upgrade had re-resolved prettier's unpinned devDependency range (packages/tooling: ^3.5.2) from 3.6.2 to 3.9.5, an unrelated side effect that would have caused prettier to reformat unrelated files across the repo. Restored the 3.6.2 resolution (matching main) without adding an override, so this PR stays scoped to the React Router upgrade. * Revert prettier pin; @react-router/dev v8 requires prettier ^3.8.3 The previous commit treated the prettier 3.6.2 -> 3.9.5 resolution bump as an unrelated side effect and pinned it back down. That was wrong: @react-router/dev@8.2.0 has a hard dependency on `prettier: ^3.8.3`, which packages/tooling's existing ^3.5.2 range (previously satisfied by 3.6.2) can no longer share a single resolved version with. pnpm's natural resolution of 3.9.5 (satisfying both ranges) is correct and necessary for this upgrade, not incidental drift to suppress. * Bump prettier to latest, deal with format changes... * Changelog
1 parent 3b21d34 commit 0066487

73 files changed

Lines changed: 1182 additions & 903 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/aurora/app/config/server/content-migrations.server.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ const createSomersaultValue = (content: Content): SomersaultValue => {
1616

1717
return orderedBlockIds.flatMap((blockId) => {
1818
const block = content.blocks?.[blockId] as
19-
| Record<string, unknown>
20-
| undefined;
19+
Record<string, unknown> | undefined;
2120
if (!block) return [];
2221

2322
return somersaultBlockMigrations.flatMap(

apps/aurora/app/config/server/migrations.server.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ const isRegisteredNativeBlock = (block: Record<string, unknown>) => {
2222
if (typeof blockType !== 'string') return false;
2323

2424
const blocksConfig = config.blocks?.blocksConfig as
25-
| Record<string, unknown>
26-
| undefined;
25+
Record<string, unknown> | undefined;
2726

2827
return Boolean(blocksConfig?.[blockType]);
2928
};
@@ -38,8 +37,7 @@ const getMigratedPloneBlockWidth = (block: Record<string, unknown>) => {
3837
}
3938

4039
const blocksConfig = config.blocks?.blocksConfig as
41-
| Record<string, BlockConfigBase>
42-
| undefined;
40+
Record<string, BlockConfigBase> | undefined;
4341
const blockConfig = blocksConfig?.[blockType];
4442
const styleFields = getStyleFieldsFromBlockSchema(
4543
blockConfig,

apps/aurora/app/entry.client.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import i18next from 'i18next';
66
import { I18nextProvider, initReactI18next } from 'react-i18next';
77
import LanguageDetector from 'i18next-browser-languagedetector';
88
import Backend from 'i18next-http-backend';
9-
import { getInitialNamespaces } from 'remix-i18next/client';
109
import install from './config';
1110

1211
install();
@@ -18,8 +17,7 @@ async function hydrate() {
1817
.use(Backend) // Setup your backend
1918
.init({
2019
...i18n, // spread the configuration
21-
// This function detects the namespaces your routes rendered while SSR use
22-
ns: getInitialNamespaces(),
20+
ns: i18n.defaultNS,
2321
backend: { loadPath: '/locales/{{lng}}/{{ns}}.json' },
2422
detection: {
2523
// Here only enable htmlTag detection, we'll detect the language only

apps/aurora/app/entry.server.tsx

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,8 @@ import { ServerRouter } from 'react-router';
1010
import { isbot } from 'isbot';
1111
import type { RenderToPipeableStreamOptions } from 'react-dom/server';
1212
import { renderToPipeableStream } from 'react-dom/server';
13-
import { createInstance } from 'i18next';
14-
import i18next from './i18next.server';
15-
import { I18nextProvider, initReactI18next } from 'react-i18next';
16-
import Backend from 'i18next-fs-backend/cjs';
17-
import i18n from './i18n'; // your i18n configuration file
18-
import { resolve } from 'node:path';
13+
import { getInstance } from './i18next.server';
14+
import { I18nextProvider } from 'react-i18next';
1915

2016
export const streamTimeout = 5_000;
2117

@@ -36,19 +32,7 @@ export default async function handleRequest(
3632
? 'onAllReady'
3733
: 'onShellReady';
3834

39-
const instance = createInstance();
40-
const lng = await i18next.getLocale(request);
41-
const ns = i18next.getRouteNamespaces(routerContext);
42-
43-
await instance
44-
.use(initReactI18next) // Tell our instance to use react-i18next
45-
.use(Backend) // Setup our backend
46-
.init({
47-
...i18n, // spread the configuration
48-
lng, // The locale we detected above
49-
ns, // The namespaces the routes about to render wants to use
50-
backend: { loadPath: resolve('./public/locales/{{lng}}/{{ns}}.json') },
51-
});
35+
const instance = getInstance(loadContext);
5236

5337
return new Promise((resolve, reject) => {
5438
let shellRendered = false;

apps/aurora/app/i18next.server.ts

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
import Backend from 'i18next-fs-backend/cjs';
22
import { resolve } from 'node:path';
3-
import { RemixI18Next } from 'remix-i18next/server';
3+
import { initReactI18next } from 'react-i18next';
4+
import { createI18nextMiddleware } from 'remix-i18next';
45
import i18n from './i18n'; // your i18n configuration file
56

6-
const i18next = new RemixI18Next({
7-
detection: {
8-
supportedLanguages: i18n.supportedLngs,
9-
fallbackLanguage: i18n.fallbackLng as string,
10-
},
11-
// This is the configuration for i18next used
12-
// when translating messages server-side only
13-
i18next: {
14-
...i18n,
15-
fallbackLng: i18n.fallbackLng as string,
16-
backend: {
17-
loadPath: resolve('../locales/{{lng}}/{{ns}}.json'),
7+
export const [i18nextMiddleware, getLocale, getInstance] =
8+
createI18nextMiddleware({
9+
detection: {
10+
supportedLanguages: i18n.supportedLngs,
11+
fallbackLanguage: i18n.fallbackLng as string,
1812
},
19-
},
20-
// The i18next plugins you want RemixI18next to use for `i18n.getFixedT` inside loaders and actions.
21-
// E.g. The Backend plugin for loading translations from the file system
22-
// Tip: You could pass `resources` to the `i18next` configuration and avoid a backend here
23-
plugins: [Backend],
24-
});
25-
26-
export default i18next;
13+
// This is the configuration for i18next used
14+
// when translating messages server-side only
15+
i18next: {
16+
...i18n,
17+
fallbackLng: i18n.fallbackLng as string,
18+
ns: i18n.defaultNS,
19+
backend: {
20+
loadPath: resolve('../locales/{{lng}}/{{ns}}.json'),
21+
},
22+
},
23+
// The i18next plugins the middleware's instance uses.
24+
// Tip: You could pass `resources` to the `i18next` configuration and avoid a backend here
25+
plugins: [Backend, initReactI18next],
26+
});

0 commit comments

Comments
 (0)