How can I extend the client-side context down the route tree?
Hi there!
Using
beforeLoad, we are able to extend the router context on the server-side for all child routes. This is really useful, but has the constraint of needing the context to be serialisable, meaning we can't take full advantage of the context manipulation by passing functions, etc.
An example use-case might be logging. The context is created when the router is initialised:
However, if I wanted to extend the logger for sub-routes and add additional attributes, I'm unable to do so in beforeLoad because the logger function isn't serialisable:
The recommended solution for this seems to be to turn off SSR, but that seems like a big price!
It would be great to have an alternative lifecycle function that allows client-side extension of the context. Effectively how beforeLoad behaves if SSR is disabled. It could run after (and receive the output of) beforeLoad.
I have no idea how realistic this is - the serialisation might be essential - my loose understanding is that there's a context created for each server-side request, then a context for the client side. I think it's challenging to comprehend for me because of the blurring of the two with isomorphic functions.8 Replies
harsh-harlequinOP•2w ago
I think my confusion is around how we can have an isomorphic initialisation of the router (and context), but it's not possible to the same for context extension/manipulation
afraid-scarlet•2w ago
we are working on that. there it will run before beforeLoad and beforeLoad will be merged with the result of it
harsh-harlequinOP•2w ago
That's great news - thanks @Manuel Schiller. Is there anywhere I can follow the progress of this? or is there a working term for this so I can search? 🙂
afraid-scarlet•2w ago
we have documented this internally, but not yet publicly
it's also not our top priority right now, i guess we will bring this after we reach stable 1.0 state for start
harsh-harlequinOP•2w ago
ah ok - fair enough. Thanks @Manuel Schiller. Given this will run before beforeLoad, I'm not sure it would help address the issue I'm having 😬 I'd like to be able to read from the
serverContext and use that to extend the context (eg. extend the logger with request header info, build an api client using auth credentials, etc). But I can't see a way of reading that value without adding a server fn. Ideally I'd probably want it to run after the loader!afraid-scarlet•2w ago
is that something that needs to run for specific subroutes?
also, serverContext is only available on the server
so this wouldn't help on the client really
harsh-harlequinOP•2w ago
@Manuel Schiller also, serverContext is only available on the server so this wouldn't help on the client reallyYeah I think I sort of forgot my actual use-case in going down the rabbit hole on this 😆 My exact use-case in this situation is that I pass a logger instance around a lot using context, and I want to be able to add an attribute to all server-side logs containing the
Referer header of the request. But obviously wouldn't do that on the client so the header won't be present. Ideally I would be able to:
1. Build serverContext inside the start request middleware, passing headers and cookies etc
2. Read from serverContext in beforeLoad and/or loader
3. Use a "context" lifecycle hook to receive the result of loader and manipulate the context for all sub-routes.
This is almost certainly just ignorance on my part when it comes to understanding how the router works! But I think the bit I'm struggling to understand is why it's accepted that we have a router context in the server-side and a separate router context in the client-side... and the two are kept totally separate, except for beforeLoad where it's serialised and they get merged. I think I'm after a function that helps me manipulate the context that can run on both the server and the client. If that makes sense?afraid-scarlet•5d ago
we have a router context in the server-side and a separate router context in the client-sidei am not sure i am following here. you can define your own context in the root route by using createRootWithContext, and you initialize that by passing in
context into createRouter
since the router is created on the server and the client, this context is the same (unless you implement env specific logic here)
you cannot use the result of loader to feed anything to child routes due to a fundamental design paradigm:
loaders run in parallel. so if you match multiple nested routes, only the beforeLoads run serially, which makes it possible to send context to subroutes.
if you can provide some (pseudo) code on how you envision to use this it would help me better understand what you are trying to do here