Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

React Router with Hono in less than 10 seconds

License

NotificationsYou must be signed in to change notification settings

rphlmr/react-router-hono-server

Repository files navigation

Psst!

Important

This package is only compatible with React Router v7

You can still use the v1 with @remix-run.Previous docs

Migration guide from v1here

TLDR

This package contains a helper functioncreateHonoServer that enables you to create a Honoserver bound to your React Router v7 app.

Since the Hono server is built along with the rest of your app, you may import app modules as needed.

It also supports Vite HMR via thereact-router-hono-server/dev plugin (which is requiredfor this to function).

It presets a default Hono server config that you cancustomize

Important

Only works with React Router v7 inESM mode

Only works withVite

OnlyNode,Bun,Cloudflare Workers andAWS Lambda (experimental) are supported

Tip

👨‍🏫 There is some examples in theexamples folder. I hope they will help you.

You can useremix-hono to add cool middleware likesession

Installation

Install the following npm package.

Note

This is not a dev dependency, as it creates the Hono server used in production.

npm install react-router-hono-server hono @hono/node-server# For Bun you can install @hono/node-server as a dev dependencybun install -D @hono/node-server# For Cloudflare Workers, add the followingnpm install -D miniflare wrangler

Tip

If you usepnpm, and want to use some imports fromhono, you may need to installhono manually or create a.npmrc file in your project with the following content:

public-hoist-pattern[]=hono

Easy mode

In yourvite.config.ts, add thereactRouterHonoServer plugin.

import{reactRouter}from"@react-router/dev/vite";import{reactRouterHonoServer}from"react-router-hono-server/dev";// add thisimport{defineConfig}from"vite";importtsconfigPathsfrom"vite-tsconfig-paths";exportdefaultdefineConfig({plugins:[reactRouterHonoServer(),// add thisreactRouter(),tsconfigPaths()],});

That's all!

Wait, what?

For really simple apps, that's all you need to do. Behind the hood, it will create a virtual module with a default Hono server.When building for production, it will create the server file atbuild/server/index.js and import your React Router app fromvirtual:react-router/server-build module (replacing it with the real file located inbuild/server/assets/server-build-[hash].js).

Configuration

Ok, by default it works, but you may want to customize the server and use some middleware.

Important

Until you define your ownserverEntryPoint, the file name${appDirectory}/server.ts and the folder name${appDirectory}/server are reserved words.

reactRouterHonoServer plugin is looking for them to find your server file.

Add the Vite plugin

Note

It uses thereactRouter plugin to build your app and will automatically load its config.

Node

Tip

Check thisexample to see how to use it.

// vite.config.tsimport{reactRouter}from"@react-router/dev/vite";import{reactRouterHonoServer}from"react-router-hono-server/dev";// add thisimport{defineConfig}from"vite";importtsconfigPathsfrom"vite-tsconfig-paths";exportdefaultdefineConfig({plugins:[reactRouterHonoServer(),// add thisreactRouter(),tsconfigPaths()],});

Bun

Tip

Check thisexample to see how to use it.

Important

React 19 andbun --bun flag should work with the sameentry.server.tsx file as Node. CheckUsingbun --bun flag?Check thisexample to see how to use it.

// vite.config.tsimport{reactRouter}from"@react-router/dev/vite";import{reactRouterHonoServer}from"react-router-hono-server/dev";// add thisimport{defineConfig}from"vite";importtsconfigPathsfrom"vite-tsconfig-paths";exportdefaultdefineConfig({plugins:[reactRouterHonoServer({runtime:"bun"}),// add thisreactRouter(),tsconfigPaths()],});
Usingbun --bun flag?

Tip

Check thisexample to see how to use it.

If you are using thebun --bun flag, you need to have the sameentry.server.tsx file as Node.

When building for production, at least for React 19, it uses a specialreact-dom/server.bun import with only therenderToReadableStream function available.

React Router Hono Server vite plugin will alias that toreact-dom/server.node

import{PassThrough}from"node:stream";importtype{AppLoadContext,EntryContext}from"react-router";import{createReadableStreamFromReadable}from"@react-router/node";import{ServerRouter}from"react-router";import{isbot}from"isbot";importtype{RenderToPipeableStreamOptions}from"react-dom/server";import{renderToPipeableStream}from"react-dom/server";exportconststreamTimeout=5_000;exportdefaultfunctionhandleRequest(request:Request,responseStatusCode:number,responseHeaders:Headers,routerContext:EntryContext,loadContext:AppLoadContext,// If you have middleware enabled:// loadContext: unstable_RouterContextProvider){returnnewPromise((resolve,reject)=>{letshellRendered=false;letuserAgent=request.headers.get("user-agent");// Ensure requests from bots and SPA Mode renders wait for all content to load before responding// https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generationletreadyOption:keyofRenderToPipeableStreamOptions=(userAgent&&isbot(userAgent))||routerContext.isSpaMode        ?"onAllReady"        :"onShellReady";const{ pipe, abort}=renderToPipeableStream(<ServerRoutercontext={routerContext}url={request.url}/>,{[readyOption](){shellRendered=true;constbody=newPassThrough();conststream=createReadableStreamFromReadable(body);responseHeaders.set("Content-Type","text/html");resolve(newResponse(stream,{headers:responseHeaders,status:responseStatusCode,}),);pipe(body);},onShellError(error:unknown){reject(error);},onError(error: unknown){          responseStatusCode=500;// Log streaming rendering errors from inside the shell.  Don't log// errors encountered during initial shell rendering since they'll// reject and get logged in handleDocumentRequest.if(shellRendered){console.error(error);}},},);// Abort the rendering stream after the `streamTimeout` so it has time to// flush down the rejected boundariessetTimeout(abort,streamTimeout+1000);});}

Cloudflare Workers

Tip

Check thisexample to see how to use it.

Important

You need to add thecloudflareDevProxy plugin to use the Cloudflare Workers runtime on dev.

// vite.config.tsimport{reactRouter}from"@react-router/dev/vite";import{cloudflareDevProxy}from"@react-router/dev/vite/cloudflare";// add thisimport{reactRouterHonoServer}from"react-router-hono-server/dev";// add thisimport{defineConfig}from"vite";importtsconfigPathsfrom"vite-tsconfig-paths";exportdefaultdefineConfig({plugins:[cloudflareDevProxy(),reactRouterHonoServer({runtime:"cloudflare"}),// add thisreactRouter(),tsconfigPaths()],});
React 19

Important

Check thisexample to see how to use it.

Tip

You may need to add theforce_react_19 flag to thereactRouterHonoServer plugin config.

// vite.config.tsreactRouterHonoServer({runtime:"cloudflare",flag:{force_react_19:true}}),// add this

AWS Lambda

Tip

AWS shares the same runtime as Node.

// vite.config.tsimport{reactRouter}from"@react-router/dev/vite";import{reactRouterHonoServer}from"react-router-hono-server/dev";// add thisimport{defineConfig}from"vite";importtsconfigPathsfrom"vite-tsconfig-paths";exportdefaultdefineConfig({plugins:[reactRouterHonoServer({runtime:"aws",dev:{export:"handler"}}),// add thisreactRouter(),tsconfigPaths()],});

Create the server

Tip

You can use the CLI to create the server file for you.

npx react-router-hono-server reveal file

In yourapp folder, create a file namedserver.ts and exportas default the server created bycreateHonoServer.

touch app/server.ts
// app/server.tsimport{createHonoServer}from"react-router-hono-server/node";exportdefaultcreateHonoServer({/* options */});

Alternative

You can define your server inapp/server/index.ts.

Tip

You can use the CLI to create the server file for you.

npx react-router-hono-server reveal folder

It is useful if you have many middleware and want to keep your server file clean.

// app/server/index.tsimport{createHonoServer}from"react-router-hono-server/node";exportdefaultcreateHonoServer({/* options */});

I don't like this default

No problem, you can define your files wherever you want.

Use theserverEntryPoint option of the Vite pluginreactRouterHonoServer to point to your server file.

Update your package.json scripts

Node

It is not an error, you can keep the React Router defaults forbuild anddev!

"scripts": {"build":"react-router build","dev":"react-router dev","start":"node ./build/server/index.js",  },

Bun

It is not an error, you can keep the React Router defaults forbuild!

"scripts": {"build":"react-router build","dev":"bunx --bun vite","start":"bun ./build/server/index.js",  },

Cloudflare

It is not an error, you can keep the React Router defaults forbuild anddev!

"scripts": {"build":"react-router build","dev":"react-router dev","start":"wrangler dev",  },

Wrangler

Add a file namedwrangler.toml at the root of your project (close topackage.json).

Adapt themain andassets fields based on your build output, if you changed them from the defaults.

workers_dev =truename ="my-worker"compatibility_date ="2024-11-18"main ="./build/server/index.js"assets = {directory ="./build/client/" }
Custom assets serving

You can set Cloudflareexperimental_serve_directly and delegate assets serving to Hono, like for Node and Bun.

Tip

Check thisexample to see how to use it.

[assets]directory ="./build/client/"binding ="ASSETS"experimental_serve_directly =false

AWS Lambda

It is not an error, you can keep the React Router defaults forbuild anddev!

"scripts": {"build":"react-router build","dev":"react-router dev","start":"I don't know how to start it in production mode 😅",  },

How it works

This helper works differently depending on the environment.

In development, it uses@hono/vite-dev-server and loads your server and React Router app withimport('virtual:react-router/server-build').It can be configured invite.config.ts.

Inproduction, it will create a standard node HTTP server listening atHOST:PORT.You can customize the production server port using theport option ofcreateHonoServer.

When building for production, the Hono server is compiled asbuild/server/index.js and imports your React Router app fromassets/server-build-[hash].js.

To run the server in production, usenode ./build/server/index.js.

That's all!

Options

reactRouterHonoServer (Vite Plugin)

typeRuntime="node"|"bun"|"cloudflare"|"aws";typeReactRouterHonoServerPluginOptions={/**   * The runtime to use for the server.   *   * Defaults to `node`.   */runtime?:Runtime;/**   * The path to the server file, relative to `vite.config.ts`.   *   * If it is a folder (`app/server`), it will look for an `index.ts` file.   *   * Defaults to `${appDirectory}/server[.ts | /index.ts]` if present.   *   * Fallback to a virtual module `virtual:react-router-hono-server/server`.   */serverEntryPoint?:string;/**   * The paths that are not served by the dev-server.   *   * Defaults include `appDirectory` content.   */dev?:{/**     * The paths that are not served by the dev-server.     *     * Defaults include `appDirectory` content.     */exclude?:(string|RegExp)[];/**     * The name of the export to use for the server.     *     * Defaults to `default`.     */export?:string;};};

createHonoServer

All adapters
exporttypeHonoServerOptions<EextendsEnv=BlankEnv>={/**   * The base Hono app to use   *   * It will be used to mount the React Router server on the `basename` path   * defined in the [React Router config](https://api.reactrouter.com/v7/types/_react_router_dev.config.Config.html)   *   * {@link Hono}   */app?:Hono<E>;/**   * Enable the default logger   *   * Defaults to `true`   */defaultLogger?:boolean;/**   * The port to start the server on   *   * Defaults to `process.env.PORT || 3000`   */port?:number;/**   * Customize the Hono server, for example, adding middleware   *   * It is applied after the default middleware and before the React Router middleware   */configure?:<EextendsEnv=BlankEnv>(server:Hono<E>)=>Promise<void>|void;/**   * Augment the React Router AppLoadContext   *   * Don't forget to declare the AppLoadContext in your app, next to where you create the Hono server   *   * ```ts   * declare module "react-router" {   *   interface AppLoadContext {   *     // Add your custom context here   *     whatever: string;   *   }   * }   * ```   *   * **To make the typing works correctly, in your `react-router.config.ts`, add future v8_middleware flag to true.**   *   * ```ts   * import { defineConfig } from "@react-router/dev";   *   * export default defineConfig({   *   future: {   *     v8_middleware: true,   *   },   *   // other config options...   * });   * ```   */getLoadContext?:(c:Context,options:{build:ServerBuild;mode:"development"|"production"|"test";})=>Promise<AppLoadContext>|AppLoadContext;/**   * Hook to add middleware that runs before any built-in middleware, including assets serving.   *   * You can use it to add protection middleware, for example.   */beforeAll?:(app:Hono<E>)=>Promise<void>|void;};

You can add additional Hono middleware with theconfigure function. If you do not provide a function, it will create a default Hono server.

If you want to set up the React RouterAppLoadContext, pass in a function togetLoadContext.

Modify theAppLoadContext interface used in your app.

Since the Hono server is compiled in the same bundle as the rest of your React Router app, you can import app modules just like you normally would.

Example
// app/server.tsimport{createHonoServer}from"react-router-hono-server/node";/** * Declare our loaders and actions context type */declare module"react-router"{interfaceAppLoadContext{/**     * The app version from the build assets     */readonlyappVersion:string;}}exportdefaultcreateHonoServer({getLoadContext(_,{ build, mode}){constisProductionMode=mode==="production";return{appVersion:isProductionMode ?build.assets.version :"dev",};},});
// app/routes/test.tsximporttype{Route}from"./+types/test";exportasyncfunctionloader({ context}:Route.LoaderArgs){// get the context provided from `getLoadContext`return{appVersion:context.appVersion}}

Tip

If you declare yourgetLoadContext function in a separate file, you can use the helpercreateGetLoadContext fromreact-router-hono-server/{adapter}

import{createGetLoadContext}from"react-router-hono-server/node";exportconstgetLoadContext=createGetLoadContext((c,{ mode, build})=>{constisProductionMode=mode==="production";return{appVersion:isProductionMode ?build.assets.version :"dev",};});
Node
exportinterfaceHonoServerOptions<EextendsEnv=BlankEnv>extendsHonoServerOptionsBase<E>{/**   * Listening listener (production mode only)   *   * It is called when the server is listening   *   * Defaults log the port   */listeningListener?:(info:AddressInfo)=>void;/**   * Customize the node server (ex: using http2)   *   * {@link https://hono.dev/docs/getting-started/nodejs#http2}   */customNodeServer?:CreateNodeServerOptions;/**   * Callback executed just after `serve` from `@hono/node-server`   *   * **Only applied to production mode**   *   * For example, you can use this to bind `@hono/node-ws`'s `injectWebSocket`   */onServe?:(server:ServerType)=>void;/**   * The Node.js Adapter rewrites the global Request/Response and uses a lightweight Request/Response to improve performance.   *   * If you want this behavior, set it to `true`   *   * 🚨 Setting this to `true` can break `request.clone()` if you later check `instanceof Request`.   *   * {@link https://github.com/honojs/node-server?tab=readme-ov-file#overrideglobalobjects}   *   *@default false   */overrideGlobalObjects?:boolean;/**   * Customize the hostname of the node server   */hostname?:string;/**   * Customize the serve static options   */serveStaticOptions?:{/**     * Customize the public assets (what's in your `public` directory) serve static options.     *     */publicAssets?:Omit<ServeStaticOptions<E>,"root">;/**     * Customize the client assets (what's in your `build/client/assets` directory - React Router) serve static options.     *     */clientAssets?:Omit<ServeStaticOptions<E>,"root">;};}
Bun
exportinterfaceHonoServerOptions<EextendsEnv=BlankEnv>extendsHonoServerOptionsBase<E>{/**   * Customize the bun server   *   * {@link https://bun.sh/docs/api/http#start-a-server-bun-serve}   */customBunServer?:Serve.Options<unknown,string>;/**   * Customize the serve static options   */serveStaticOptions?:{/**     * Customize the public assets (what's in your `public` directory) serve static options.     *     */publicAssets?:Omit<ServeStaticOptions<E>,"root">;/**     * Customize the client assets (what's in your `build/client/assets` directory - React Router) serve static options.     *     */clientAssets?:Omit<ServeStaticOptions<E>,"root">;};}
Cloudflare Workers
exportinterfaceHonoServerOptions<EextendsEnv=BlankEnv>extendsOmit<HonoServerOptionsBase<E>,"port">{}
AWS Lambda
typeInvokeMode="default"|"stream";interfaceHonoAWSServerOptions<EextendsEnv=BlankEnv>extendsOmit<HonoServerOptionsBase<E>,"port">{/**   * The invoke mode to use   *   * Defaults to `default`   *   * {@link https://hono.dev/docs/getting-started/aws-lambda#lambda-response-streaming}   */invokeMode:InvokeMode;}

Middleware

🚨 Redirecting from a middleware

Important

TLDR: If you encounter aError: Unable to decode turbo-stream response after a redirect from your middleware, try to useredirect instead ofc.redirect.

redirect will usec.redirect for "normal" requests and a single-fetch-like response for React Router.data requests.

If the next handler is a Hono middleware (ex:#56), you can usec.redirect as usual.

Youhave to use theredirect helper to redirect from a middleware if the next handler that will receive this redirect is a React Router route.

It returns a single-fetch-like response.

If you usec.redirect, it will not work as expected and you will get aUnable to decode turbo-stream response error.

import{redirect}from"react-router-hono-server/http";

I'm sorry for this inconvenience, I hope it can be "fixed" in future React Router versions.

Middleware are functions that are called before React Router calls your loader/action.

Hono is the perfect tool for this, as it supports middleware out of the box.

See theHono docs for more information.

You can imagine many use cases for middleware, such as authentication, protecting routes, caching, logging, etc.

See howShelf.nu uses them!

Tip

This lib exports one middlewarecache (react-router-hono-server/middleware) that you can use to cache your responses.

beforeAll

You can use thebeforeAll option to add middleware that runs before any built-in middleware, including assets serving.

You can use it to add protection middleware, for example.

Tip

When you check the path to protect, don't forget to usec.req.path.includes("") to handle.data requests (loader)!

import{reactRouterRedirect}from"react-router-hono-server/http";import{createHonoServer}from"react-router-hono-server/node";exportdefaultcreateHonoServer({beforeAll(app){app.use(async(c,next)=>{if(c.req.path.includes("/protected")&&!c.req.header("Authorization")){returnreactRouterRedirect("/login");}returnnext();});},});

Using remix-hono middleware

It is easy to useremix-hono middleware with this package.

import{createCookieSessionStorage}from"react-router";import{createHonoServer}from"react-router-hono-server/node";import{session}from"remix-hono/session";exportdefaultcreateHonoServer({configure:(server)=>{server.use(session({autoCommit:true,createSessionStorage(){constsessionStorage=createCookieSessionStorage({cookie:{name:"session",httpOnly:true,path:"/",sameSite:"lax",secrets:[process.env.SESSION_SECRET],secure:process.env.NODE_ENV==="production",},});return{            ...sessionStorage,// If a user doesn't come back to the app within 30 days, their session will be deleted.asynccommitSession(session){returnsessionStorage.commitSession(session,{maxAge:60*60*24*30,// 30 days});},};},}));},});

Creating custom Hono Middleware

You can create middleware using thecreateMiddleware orcreateFactory functions fromhono/factory.

Then, use them with theconfigure function ofcreateHonoServer.

import{createMiddleware}from"hono/factory";import{createHonoServer}from"react-router-hono-server/node";exportdefaultcreateHonoServer({configure:(server)=>{server.use(createMiddleware(async(c,next)=>{console.log("middleware");returnnext();}));},});

Using React Router Middleware

You can use React Router middleware with this package.

Tip

Check thisexample to see how to use it.

Important

To make the typing works correctly, in yourreact-router.config.ts or where you want, add future v8_middleware flag type to true.

declare module"react-router"{interfaceFuture{v8_middleware:true;// 👈 Enable middleware types}}

If you already have a customgetLoadContext function, you now have to return an instance ofRouterContextProvider from it. Check thisexample for more information.

import{RouterContextProvider,createContext}from"react-router";import{createHonoServer}from"react-router-hono-server/node";console.log("loading server");typeGlobalAppContext={appVersion:string;};exportconstglobalAppContext=createContext<GlobalAppContext>();exportdefaultawaitcreateHonoServer({getLoadContext(_c,{ mode, build}){constisProductionMode=mode==="production";constcontext=newRouterContextProvider();context.set(globalAppContext,{appVersion:isProductionMode ?build.assets.version :"dev"});returncontext;},});

Then, you can use theuse function fromreact-router to access the context in your loaders and actions.

###UsingWebSockets####NodeThispackagehasabuilt-inhelpertouse`@hono/node-ws`>[!TIP]>Checkthis[example](./examples/node/websocket/)toseehowtouseit.```tsimport type { WSContext } from "hono/ws";import { createHonoServer } from "react-router-hono-server/node";// Store connected clientsconst clients = new Set<WSContext>();export default createHonoServer({  useWebSocket: true,  // 👆 Unlock this 👇 from @hono/node-ws  configure: (app, { upgradeWebSocket }) => {    app.get(      "/ws",      upgradeWebSocket((c) => ({        // https://hono.dev/helpers/websocket        onOpen(_, ws) {          console.log("New connection ⬆️");          clients.add(ws);        },        onMessage(event, ws) {          console.log("Context", c.req.header("Cookie"));          console.log("Event", event);          console.log(`Messagefromclient: ${event.data}`);          // Broadcast to all clients except sender          clients.forEach((client) => {            if (client.readyState === 1) {              client.send(`${event.data}`);}});},onClose(_,ws){console.log("Connection closed");clients.delete(ws);},})));},});

Bun

This package has a built-in helper to usehono/bun in prod and@hono/node-ws in dev

Tip

Check thisexample to see how to use it.

import{WSContext}from"hono/ws";import{createHonoServer}from"react-router-hono-server/bun";// Store connected clientsconstclients=newSet<WSContext>();exportdefaultcreateHonoServer({useWebSocket:true,// 👆 Unlock this 👇 from @hono/node-ws in dev, hono/bun in prodconfigure(app,{ upgradeWebSocket}){app.get("/ws",upgradeWebSocket((c)=>({// https://hono.dev/helpers/websocketonOpen(_,ws){console.log("New connection 🔥");clients.add(ws);},onMessage(event,ws){console.log("Context",c.req.header("Cookie"));console.log("Event",event);console.log(`Message from client:${event.data}`);// Broadcast to all clients except senderclients.forEach((client)=>{if(client.readyState===1){client.send(`${event.data}`);}});},onClose(_,ws){console.log("Connection closed");clients.delete(ws);},})));},});

Cloudflare Workers

Cloudflare requires a different approach to WebSockets, based on Durable Objects.

Tip

Check thisexample to see how to use it.

Important

For now, HMR is not supported in Cloudflare Workers. Will try to come back to it later.

Work in progress on Cloudflare team:https://github.com/flarelabs-net/vite-plugin-cloudflare

AWS

Not supported.

Basename and Hono sub apps

Note

By default, the React Router app is mounted at/ (defaultbasename value).

You may not need to use this option. It's for advanced use cases.

Tip

Check thisexample to see how to use it.

You can use thebasename option in your React Router config (react-router.config.ts) to mount your React Router app on a subpath.

It will automatically mount the app on the subpath.

// react-router.config.tsimporttype{Config}from"@react-router/dev/config";exportdefault{basename:"/app",// Now the React Router app will be mounted on /app}satisfiesConfig;

Then, you can use theapp option increateHonoServer to pass your "root" Hono app. This will be used to mount the React Router app on thebasename path.

import{Hono}from"hono";import{createHonoServer}from"react-router-hono-server/node";import{API_BASENAME,api}from"./api";import{getLoadContext}from"./context";// Create a root Hono appconstapp=newHono();// Mount the API app at /apiapp.route(API_BASENAME,api);exportdefaultcreateHonoServer({// Pass the root Hono app to the server.// It will be used to mount the React Router app on the `basename` defined in react-router.config.ts  app,  getLoadContext,});

Note

You now have two entry points!

  • /api - for your API
  • /app - for your React Router app

Pre-rendering

You should be able to use pre-rendering with this package.

Node and Bun

Tip

Check thisexample to see how to use it.

Important

You need to add theserverBuildFile option to yourreact-router.config.ts file.

The file path is fixed toassets/server-build.js.

Add the pre-render option to yourreact-router.config.ts

importtype{Config}from"@react-router/dev/config";exportdefault{prerender:["/"],}satisfiesConfig;

Cloudflare

Tip

Check thisexample to see how to use it.

Add the pre-render option to yourreact-router.config.ts

importtype{Config}from"@react-router/dev/config";exportdefault{prerender:["/"],}satisfiesConfig;

Migrate from v1

You should not expect any breaking changes.

Install the latest version

npm install react-router-hono-server@latest

Create the server file

Option 1 - You previously had all your server code inapp/entry.server.tsx

touch app/server.ts

or

npx react-router-hono-server reveal file

Option 2 - You previously had your server code in aserver folder

mkdir app/servertouch app/server/index.ts

or

npx react-router-hono-server reveal folder

Move your server code

Move your previous server code to the new file you created in the previous step.

Note

You can remove the import fromreact-router-hono-server/node in yourentry.server.tsx file and any other server code.

Many options are gone,serverBuildFileassetsDir andbuildDirectory.

We now use the Vite virtual importvirtual:react-router/server-build to load the server build and we read the Vite config thanks to thereactRouterHonoServer plugin.

Important

You now need to export the server created bycreateHonoServer asdefault.

import{createHonoServer}from"react-router-hono-server/node";exportdefaultcreateHonoServer({/* other options */});

Update yourvite.config.ts

Important

devServer is nowreactRouterHonoServer.

Many options are gone or have changed.

exportName (reactRouterHonoServer expects a default export from your server file),entry is nowserverEntryPoint.appDirectory is removed (read fromvite.config.ts), andexclude has been moved underdev.

You usedbuildEnd fromremix() plugin or a custombuildDirectory option

You may know that it has been moved toreact-router.config.ts (seehere for more information).

If you used this hook for Sentry, check thisexample to see how to migrate.

If you used a custombuildDirectory option, check thisexample to see how to migrate.

Update your package.json scripts

"scripts": {"build":"react-router build","dev":"react-router dev","start":"node ./build/server/index.js",  },

Special Thanks

Inspired byremix-express-vite-plugin from@kiliman

remix handler was forked fromremix-hono by@sergiodxa as it is a small and simple core dependency of this library.

I will still help maintain it.

Contributors ✨

This project follows theall-contributors specification. Contributions of any kind welcome!

About

React Router with Hono in less than 10 seconds

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Sponsor this project

 

Contributors13


[8]ページ先頭

©2009-2025 Movatter.jp