diff --git a/.changeset/violet-poets-wait.md b/.changeset/violet-poets-wait.md
new file mode 100644
index 0000000000..8d86936fec
--- /dev/null
+++ b/.changeset/violet-poets-wait.md
@@ -0,0 +1,5 @@
+---
+'@tanstack/router-core': patch
+---
+
+Fix context value from a parent route's `beforeLoad` not being propagated to a sub-route while the sub-route's loader is reloading in the background
diff --git a/packages/react-router/tests/routeContext.test.tsx b/packages/react-router/tests/routeContext.test.tsx
index d11f86420e..b92f0c374f 100644
--- a/packages/react-router/tests/routeContext.test.tsx
+++ b/packages/react-router/tests/routeContext.test.tsx
@@ -2796,6 +2796,68 @@ describe('useRouteContext in the component', () => {
expect(content).toBeInTheDocument()
})
+ test('context value from beforeLoad is propagated to a sub-route while its loader reloads in the background', async () => {
+ let sawUndefinedContext = false
+
+ const rootRoute = createRootRoute({
+ component: () => ,
+ })
+ const homeRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/',
+ component: () =>
Home page
,
+ })
+ const contextPropagationRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/context-propagation',
+ beforeLoad: () => ({ number: 42 }),
+ component: () => ,
+ })
+ const contextPropagationIndexRoute = createRoute({
+ getParentRoute: () => contextPropagationRoute,
+ path: '/',
+ staleTime: 0,
+ loader: async () => {
+ await sleep(WAIT_TIME)
+ },
+ component: () => {
+ const { number } = contextPropagationIndexRoute.useRouteContext()
+ sawUndefinedContext ||= number === undefined
+
+ return (
+
+ number = {String(number)}, saw undefined ={' '}
+ {String(sawUndefinedContext)}
+
+ )
+ },
+ })
+
+ const routeTree = rootRoute.addChildren([
+ homeRoute,
+ contextPropagationRoute.addChildren([contextPropagationIndexRoute]),
+ ])
+ const router = createRouter({ routeTree, history })
+
+ render()
+
+ await act(() => router.navigate({ to: '/context-propagation' }))
+
+ expect(
+ await screen.findByText('number = 42, saw undefined = false'),
+ ).toBeInTheDocument()
+
+ await act(() => router.navigate({ to: '/' }))
+
+ expect(await screen.findByText('Home page')).toBeInTheDocument()
+
+ act(() => router.history.back())
+
+ expect(
+ await screen.findByText('number = 42, saw undefined = false'),
+ ).toBeInTheDocument()
+ })
+
// Check if context that is updated at the root, is the same in the root route
test('modified route context, present in the root route', async () => {
const rootRoute = createRootRoute({
diff --git a/packages/router-core/src/load-matches.ts b/packages/router-core/src/load-matches.ts
index f901a0c97d..20d31afd1d 100644
--- a/packages/router-core/src/load-matches.ts
+++ b/packages/router-core/src/load-matches.ts
@@ -832,6 +832,7 @@ const loadRouteMatch = async (
shouldReloadInBackground
) {
loaderIsRunningAsync = true
+ syncMatchContext(inner, matchId, index)
;(async () => {
try {
await runLoader(inner, matchPromises, matchId, index, route)