Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pre-rendered SPA route not re-loaded #13142

Open
namoscato opened this issue Mar 1, 2025 · 10 comments
Open

Pre-rendered SPA route not re-loaded #13142

namoscato opened this issue Mar 1, 2025 · 10 comments
Assignees
Labels

Comments

@namoscato
Copy link
Contributor

I'm using React Router as a...

framework

Reproduction

  1. Open StackBiltz project
  2. Click "Page 1" link
  3. Refresh page
  4. Click "Next"
  5. See that page navigates to /2, but component does not re-load

System Info

System:
  OS: Linux 5.0 undefined
  CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
  Memory: 0 Bytes / 0 Bytes
  Shell: 1.0 - /bin/jsh
Binaries:
  Node: 18.20.3 - /usr/local/bin/node
  Yarn: 1.22.19 - /usr/local/bin/yarn
  npm: 10.2.3 - /usr/local/bin/npm
  pnpm: 8.15.6 - /usr/local/bin/pnpm
npmPackages:
  @react-router/dev: * => 7.2.0 
  @react-router/node: * => 7.2.0 
  @react-router/serve: * => 7.2.0 
  react-router: * => 7.2.0 
  vite: ^6.0.11 => 6.2.0

Used Package Manager

npm

Expected Behavior

SPA transitions between the same pre-rendered route with updated params should re-invoke the route's loader and re-render the route component with the new loader result.

Actual Behavior

While the URL updates as expected, the pre-rendered route is re-rendered with the first page's loader data.

This seems to be scoped to pre-rendered routes in SPA mode (ssr: false) with a loader function, and it seemed to regress around v7.2.0.

@namoscato namoscato added the bug label Mar 1, 2025
@Akash187
Copy link

Akash187 commented Mar 2, 2025

Hey @namoscato, loader is only available during build time to pre-render when ssr:false.
I tested your code when I switched loader to clientLoader code is working fine.

@namoscato
Copy link
Contributor Author

loader is only available during build time to pre-render when ssr:false.

@Akash187, I'm not sure that is true given SPA transitions from pre-rendered route A → pre-rendered route B work as expected.

I tested your code when I switched loader to clientLoader code is working fine.

Yeah, that's probably true, but I am trying to pre-render the route in question.

@Akash187
Copy link

Akash187 commented Mar 2, 2025

@namoscato it will work as you think once you build it. Try building it and test.
Right now it is a SPA app with no access to loader unless during build time.

@namoscato
Copy link
Contributor Author

So should the routes define both loader and clientLoader, each returning the same dataset? I'm trying to pre-render the route in question; therefore, I do not wish to remove loader.

@Akash187
Copy link

Akash187 commented Mar 2, 2025

This seems to be a bug. I tested your code along with mine and came to conclusion that when dynamic route changes like /1 to /2 it is not triggering navigation.

To test this update your App function on root.tsx and see the console logs.

export default function App() {
	const navigation = useNavigation()
	const isNavigating = Boolean(navigation.location)
	console.log('isNavigating', isNavigating)
	return <Outlet />
}

@Akash187
Copy link

Akash187 commented Mar 2, 2025

@namoscato Here is the solution, you are suppose to re-render the component using key prop.
For more detail you can check this discussion - remix-run/remix#4535

Below is the full App function code that fixes your issue.

export default function App() {
	const navigation = useNavigation()
	const isNavigating = Boolean(navigation.location)
	const { pathname } = useLocation()
	console.log('isNavigating', isNavigating, pathname)
	return (
		<Fragment key={pathname}>
			<Outlet />
		</Fragment>
	)
}

@namoscato
Copy link
Contributor Author

Thanks @Akash187, but that potential workaround does not fix the issue. Even if it did, it would be undesirable – ideally the route component would just re-render with updated loader data as opposed to re-mount.

@Akash187
Copy link

Akash187 commented Mar 2, 2025

Yeah, upon refresh I see that the workaround is not working.

@Akash187
Copy link

Akash187 commented Mar 3, 2025

Hey @brophdawg11 why route param change from /1 to /2 is not considered as navigation. isNavigating is false and no route data is fetch beside it being available during build. When we move from / to '/1' it is considered a navigation and vice-versa.

Here is the updated code example for your reference https://stackblitz.com/edit/github-xpx3kyws-86ph2cy5

Image

@brophdawg11
Copy link
Contributor

This looks like a bug around some of the new revalidation logic with ssr:false + prerender. I'll look into a fix, but you can work around it for now by telling the /page route to revalidate:

export function shouldRevalidate() {
  return true;
}

@brophdawg11 brophdawg11 self-assigned this Mar 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants