feat: implement middleware and context provider for Express integration

This commit is contained in:
Chris Parsons 2025-10-11 20:56:00 -07:00
parent 8425ad3b42
commit 226cdd0ea7
5 changed files with 16 additions and 12 deletions

3
app/contexts/express.ts Normal file
View file

@ -0,0 +1,3 @@
import { createContext } from "react-router";
export const expressValueContext = createContext<string>();

View file

@ -9,11 +9,13 @@ import {
import type { Route } from "./+types/root"; import type { Route } from "./+types/root";
import "./app.css"; import "./app.css";
import { rootAuthLoader } from "@clerk/react-router/server"; import { clerkMiddleware, rootAuthLoader } from "@clerk/react-router/server";
import { Navbar } from "~/components/navbar"; import { Navbar } from "~/components/navbar";
import { ClerkProvider } from "@clerk/react-router"; import { ClerkProvider } from "@clerk/react-router";
import { Toaster } from "~/components/ui/sonner"; import { Toaster } from "~/components/ui/sonner";
export const middleware: Route.MiddlewareFunction[] = [clerkMiddleware()];
export async function loader(args: Route.LoaderArgs) { export async function loader(args: Route.LoaderArgs) {
return rootAuthLoader(args); return rootAuthLoader(args);
} }

View file

@ -4,6 +4,7 @@ import { toast } from "sonner";
import type { Route } from "./+types/home"; import type { Route } from "./+types/home";
import { Welcome } from "../welcome/welcome"; import { Welcome } from "../welcome/welcome";
import { expressValueContext } from "~/contexts/express";
export function meta() { export function meta() {
return [ return [
@ -17,7 +18,7 @@ export function meta() {
export async function loader({ context }: Route.LoaderArgs) { export async function loader({ context }: Route.LoaderArgs) {
return { return {
message: context.VALUE_FROM_EXPRESS, message: context.get(expressValueContext) || "No message from Express",
}; };
} }

View file

@ -4,4 +4,7 @@ export default {
// Config options... // Config options...
// Server-side render by default, to enable SPA mode set this to `false` // Server-side render by default, to enable SPA mode set this to `false`
ssr: true, ssr: true,
future: {
v8_middleware: true,
},
} satisfies Config; } satisfies Config;

View file

@ -2,16 +2,11 @@ import { createRequestHandler } from "@react-router/express";
import { drizzle } from "drizzle-orm/postgres-js"; import { drizzle } from "drizzle-orm/postgres-js";
import express from "express"; import express from "express";
import postgres from "postgres"; import postgres from "postgres";
import "react-router"; import { RouterContextProvider } from "react-router";
import { DatabaseContext } from "~/database/context"; import { DatabaseContext } from "~/database/context";
import * as schema from "~/database/schema"; import * as schema from "~/database/schema";
import { expressValueContext } from "~/contexts/express";
declare module "react-router" {
interface AppLoadContext {
VALUE_FROM_EXPRESS: string;
}
}
export const app = express(); export const app = express();
@ -25,9 +20,9 @@ app.use(
createRequestHandler({ createRequestHandler({
build: () => import("virtual:react-router/server-build"), build: () => import("virtual:react-router/server-build"),
getLoadContext() { getLoadContext() {
return { const context = new RouterContextProvider();
VALUE_FROM_EXPRESS: "Hello from Express", context.set(expressValueContext, "Hello from Express");
}; return context;
}, },
}), }),
); );