Skip to content

Commit 909b7f7

Browse files
rphlmrAlemTuzlak
andauthored
React Router Hono Server v2 (#11)
# Description Fixes #9 This is the migration path for the incoming new version 2.0.0 ## Type of change Please mark relevant options with an `x` in the brackets. - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [x] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update - [ ] Algorithm update - updates algorithm documentation/questions/answers etc. - [x] Other (please describe): Upgrade and migrate # How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration - [ ] Integration tests - [ ] Unit tests - [x] Manual tests - [ ] No tests required # Reviewer checklist Mark everything that needs to be checked before merging the PR. - [x] Check if the UI is working as expected and is satisfactory - [ ] Check if the code is well documented - [x] Check if the behavior is what is expected - [ ] Check if the code is well tested - [ ] Check if the code is readable and well formatted - [ ] Additional checks (document below if any) # Screenshots (if appropriate): # Questions (if appropriate): --------- Co-authored-by: Alem Tuzlak <t.zlak@hotmail.com>
1 parent 082359e commit 909b7f7

File tree

9 files changed

+333
-833
lines changed

9 files changed

+333
-833
lines changed

.npmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ side-effects-cache=false
33
save-exact=true
44
audit=false
55
fund=false
6-
progress=false
6+
progress=false

app/entry.server.tsx

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
import { PassThrough } from "node:stream"
22
import { createReadableStreamFromReadable } from "@react-router/node"
3-
import type { Context } from "hono"
43
import { createInstance } from "i18next"
54
import { isbot } from "isbot"
65
import { renderToPipeableStream } from "react-dom/server"
76
import { I18nextProvider, initReactI18next } from "react-i18next"
87
import { type AppLoadContext, type EntryContext, ServerRouter } from "react-router"
9-
import { createHonoServer } from "react-router-hono-server/node"
10-
import { i18next } from "remix-hono/i18next"
11-
import { getClientEnv, initEnv } from "./env.server"
128
import i18n from "./localization/i18n" // your i18n configuration file
139
import i18nextOpts from "./localization/i18n.server"
1410
import { resources } from "./localization/resource"
11+
1512
const ABORT_DELAY = 5000
1613

1714
export default async function handleRequest(
@@ -73,41 +70,3 @@ export default async function handleRequest(
7370
setTimeout(abort, ABORT_DELAY)
7471
})
7572
}
76-
77-
// Code below used to initialize our own Hono server!
78-
// Setup the .env vars
79-
const env = initEnv()
80-
81-
const getLoadContext = async (c: Context) => {
82-
// get the locale from the context
83-
const locale = i18next.getLocale(c)
84-
// get t function for the default namespace
85-
const t = await i18next.getFixedT(c)
86-
87-
const clientEnv = getClientEnv()
88-
return {
89-
lang: locale,
90-
t,
91-
env,
92-
clientEnv,
93-
// We do not add this to AppLoadContext type because it's not needed in the loaders, but it's used above to handle requests
94-
body: c.body,
95-
}
96-
}
97-
98-
interface LoadContext extends Awaited<ReturnType<typeof getLoadContext>> {}
99-
100-
/**
101-
* Declare our loaders and actions context type
102-
*/
103-
declare module "react-router" {
104-
interface AppLoadContext extends Omit<LoadContext, "body"> {}
105-
}
106-
107-
export const server = await createHonoServer({
108-
configure(server) {
109-
server.use("*", i18next(i18nextOpts))
110-
},
111-
defaultLogger: false,
112-
getLoadContext,
113-
})

app/routes/resource.locales.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { cacheHeader } from "pretty-cache-header"
2-
import { data } from "react-router"
32
import { z } from "zod"
43
import { resources } from "~/localization/resource"
54
import type { Route } from "./+types/resource.locales"
@@ -37,5 +36,5 @@ export async function loader({ request, context }: Route.LoaderArgs) {
3736
)
3837
}
3938

40-
return data(namespaces[ns], { headers })
39+
return Response.json(namespaces[ns], { headers })
4140
}

app/server/context.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import type { Context } from "hono"
2+
import { i18next } from "remix-hono/i18next"
3+
import { getClientEnv, initEnv } from "~/env.server"
4+
5+
// Setup the .env vars
6+
const env = initEnv()
7+
8+
export const getLoadContext = async (c: Context) => {
9+
// get the locale from the context
10+
const locale = i18next.getLocale(c)
11+
// get t function for the default namespace
12+
const t = await i18next.getFixedT(c)
13+
14+
const clientEnv = getClientEnv()
15+
return {
16+
lang: locale,
17+
t,
18+
env,
19+
clientEnv,
20+
// We do not add this to AppLoadContext type because it's not needed in the loaders, but it's used above to handle requests
21+
body: c.body,
22+
}
23+
}
24+
25+
interface LoadContext extends Awaited<ReturnType<typeof getLoadContext>> {}
26+
27+
/**
28+
* Declare our loaders and actions context type
29+
*/
30+
declare module "react-router" {
31+
interface AppLoadContext extends Omit<LoadContext, "body"> {}
32+
}

app/server/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { createHonoServer } from "react-router-hono-server/node"
2+
import { i18next } from "remix-hono/i18next"
3+
import i18nextOpts from "../localization/i18n.server"
4+
import { getLoadContext } from "./context"
5+
6+
export default await createHonoServer({
7+
configure(server) {
8+
server.use("*", i18next(i18nextOpts))
9+
},
10+
defaultLogger: false,
11+
getLoadContext,
12+
})

knip.json

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
{
22
"$schema": "https://unpkg.com/knip@5/schema.json",
3-
"entry": ["scripts/*.{ts,js}", "app/routes.ts","vite.config.ts"],
3+
"entry": [
4+
"scripts/*.{ts,js}",
5+
"app/routes.ts",
6+
"vite.config.ts",
7+
"app/server/*.ts"
8+
],
49
"remix": true,
5-
"project": ["**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}", "vite.config.ts"],
6-
"ignore": ["app/library/icon/icons/types.ts"]
7-
}
10+
"lefthook": true,
11+
"project": [
12+
"**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}",
13+
"vite.config.ts"
14+
],
15+
"ignore": [
16+
"app/library/icon/icons/types.ts"
17+
]
18+
}

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"clean": "git clean -fdX --exclude=\"!.env\"",
1212
"script": "tsx scripts/setup.ts",
1313
"cleanup": "pnpm run script scripts/cleanup.ts",
14-
"build": "NODE_ENV=production react-router build",
14+
"build": "react-router build",
1515
"dev": "react-router dev",
1616
"start": "NODE_ENV=production node ./build/server/index.js",
1717
"test": "vitest run",
@@ -30,7 +30,7 @@
3030
"@forge42/seo-tools": "1.3.0",
3131
"@react-router/node": "7.0.1",
3232
"clsx": "2.1.1",
33-
"hono": "4.6.11",
33+
"hono": "4.6.12",
3434
"i18next": "23.15.2",
3535
"i18next-browser-languagedetector": "8.0.0",
3636
"i18next-fetch-backend": "6.0.0",
@@ -40,7 +40,7 @@
4040
"react-dom": "18.3.1",
4141
"react-i18next": "15.1.1",
4242
"react-router": "7.0.1",
43-
"react-router-hono-server": "https://pkg.pr.new/rphlmr/react-router-hono-server@18.tgz",
43+
"react-router-hono-server": "2.0.0",
4444
"remix-hono": "0.0.16",
4545
"remix-i18next": "7.0.0",
4646
"tailwind-merge": "2.5.4",

0 commit comments

Comments
 (0)