-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
Closed as not planned
Closed as not planned
Copy link
Labels
Description
Describe what's incorrect/missing in the documentation
Hey folks, I'm trying out the new middleware API, followed these docs for v7.3.0 and got an error when I tried check if a context value exists:
import {
type unstable_MiddlewareFunction,
unstable_createContext,
} from "react-router"
import { appContext } from "~/app-context"
import { createAuthServer } from "./auth-server"
type AuthServer = ReturnType<typeof createAuthServer>
export const authServerContext = unstable_createContext<AuthServer>()
export const authMiddleware: unstable_MiddlewareFunction = async (
{ request, context },
next,
) => {
let authServer = context.get(authServerContext) // <-- error here
if (!authServer) {
let app = context.get(appContext)
authServer = createAuthServer(app)
context.set(authServerContext, authServer)
}
// ...
}Error: No value found for context
at unstable_RouterContextProvider.get (/home/vlady/code/gyarns/node_modules/.vite/deps_ssr/chunk-QZO7VHZY.js:1384:11)
at authMiddleware (/home/vlady/code/gyarns/app/routes/auth/auth-middleware.ts:19:28)
at callRouteMiddleware (/home/vlady/code/gyarns/node_modules/.vite/deps_ssr/chunk-QZO7VHZY.js:4660:24)
at runMiddlewarePipeline (/home/vlady/code/gyarns/node_modules/.vite/deps_ssr/chunk-QZO7VHZY.js:4600:24)
at Object.query (/home/vlady/code/gyarns/node_modules/.vite/deps_ssr/chunk-QZO7VHZY.js:3696:30)
at handleDocumentRequest (/home/vlady/code/gyarns/node_modules/.vite/deps_ssr/chunk-QZO7VHZY.js:10745:40)
at requestHandler (/home/vlady/code/gyarns/node_modules/.vite/deps_ssr/chunk-QZO7VHZY.js:10671:24)
Why is context.get erroring here? Are we expected to initialize all contexts that can ever be used before context.get calls?
My idea was to do a "self-initialization" pattern, where the middleware creates its own dependencies if needed. I am creating an initial context like this, but I was hoping that I don't have to add stuff to that any time I create a new context type.
// app/worker.ts
import { createRequestHandler } from "react-router"
import { createAppContext } from "./app-context"
const handler = createRequestHandler(
// @ts-expect-error - virtual module provided by React Router at build time
() => import("virtual:react-router/server-build"),
import.meta.env.MODE,
)
export default {
async fetch(request, env, ctx) {
try {
const appContext = await createAppContext(request, env, ctx)
// @ts-expect-error unstable types,
// import {AppContext} from './app-context' instead of AppLoadContext
return handler(request, appContext)
} catch (error) {
console.error(error)
return new Response("An unexpected error occurred", { status: 500 })
}
},
} satisfies ExportedHandler<Env>// app-context.ts
import { unstable_createContext } from "react-router"
import { type DatabaseClient, createDbClient } from "./db/db-client.server"
import { currencyCookie } from "./internationalization/cookies"
import type { Currency } from "./internationalization/currency-context"
import { i18next } from "./internationalization/i18n.server"
import { type ServerConfig, getServerConfig } from "./lib/config.server"
export type AppContext = {
env: Env
executionContext: ExecutionContext
db: DatabaseClient
config: ServerConfig
language: string
currency: Currency
}
/**
* Contains data and bindings needed by most requests.
*/
export const appContext = unstable_createContext<AppContext>()
// https://github.com/remix-run/react-router/issues/13181
// https://github.com/alexanderson1993/cloudflare-middleware/pull/1/files
export async function createAppContext(
request: Request,
env: Env,
executionContext: ExecutionContext,
) {
let map = new Map()
let db = createDbClient(env.DB)
let config = getServerConfig(env, request)
let language = await i18next.getLocale(request)
let cookie = request.headers.get("Cookie")
let currency = (await currencyCookie.parse(cookie)) ?? "EUR"
let contextValue: AppContext = {
env,
executionContext,
db,
config,
language,
currency,
}
map.set(appContext, contextValue)
return map
}