@@ -4869,9 +4869,7 @@ function getMatchesToLoad(
48694869 let actionStatus = pendingActionResult
48704870 ? pendingActionResult [ 1 ] . statusCode
48714871 : undefined ;
4872- let shouldSkipRevalidation =
4873- ( actionStatus && actionStatus >= 400 ) ||
4874- callSiteDefaultShouldRevalidate === false ;
4872+ let shouldSkipRevalidation = actionStatus && actionStatus >= 400 ;
48754873
48764874 let baseShouldRevalidateArgs = {
48774875 currentUrl,
@@ -4929,15 +4927,28 @@ function getMatchesToLoad(
49294927 // provides it's own implementation, then we give them full control but
49304928 // provide this value so they can leverage it if needed after they check
49314929 // their own specific use cases
4932- let defaultShouldRevalidate = shouldSkipRevalidation
4933- ? false
4934- : // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate
4935- isRevalidationRequired ||
4936- currentUrl . pathname + currentUrl . search ===
4937- nextUrl . pathname + nextUrl . search ||
4938- // Search params affect all loaders
4939- currentUrl . search !== nextUrl . search ||
4940- isNewRouteInstance ( state . matches [ index ] , match ) ;
4930+ let defaultShouldRevalidate = false ;
4931+ if ( callSiteDefaultShouldRevalidate != null ) {
4932+ // Use callsite value verbatim if provided
4933+ defaultShouldRevalidate = callSiteDefaultShouldRevalidate ;
4934+ } else if ( shouldSkipRevalidation ) {
4935+ // Skip due to 4xx/5xx action result
4936+ defaultShouldRevalidate = false ;
4937+ } else if ( isRevalidationRequired ) {
4938+ // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate
4939+ defaultShouldRevalidate = true ;
4940+ } else if (
4941+ currentUrl . pathname + currentUrl . search ===
4942+ nextUrl . pathname + nextUrl . search
4943+ ) {
4944+ // Same URL - mimic a hard reload
4945+ defaultShouldRevalidate = true ;
4946+ } else if ( currentUrl . search !== nextUrl . search ) {
4947+ // Search params affect all loaders
4948+ defaultShouldRevalidate = true ;
4949+ } else if ( isNewRouteInstance ( state . matches [ index ] , match ) ) {
4950+ defaultShouldRevalidate = true ;
4951+ }
49414952 let shouldRevalidateArgs = {
49424953 ...baseShouldRevalidateArgs ,
49434954 defaultShouldRevalidate,
@@ -4953,6 +4964,7 @@ function getMatchesToLoad(
49534964 scopedContext ,
49544965 shouldLoad ,
49554966 shouldRevalidateArgs ,
4967+ callSiteDefaultShouldRevalidate ,
49564968 ) ;
49574969 } ) ;
49584970
@@ -5848,6 +5860,7 @@ function getDataStrategyMatch(
58485860 scopedContext : unknown ,
58495861 shouldLoad : boolean ,
58505862 unstable_shouldRevalidateArgs : DataStrategyMatch [ "unstable_shouldRevalidateArgs" ] = null ,
5863+ callSiteDefaultShouldRevalidate ?: boolean ,
58515864) : DataStrategyMatch {
58525865 // The hope here is to avoid a breaking change to the resolve behavior.
58535866 // Opt-ing into the `unstable_shouldCallHandler` API changes some nuanced behavior
@@ -5873,6 +5886,13 @@ function getDataStrategyMatch(
58735886 return shouldLoad ;
58745887 }
58755888
5889+ if ( typeof callSiteDefaultShouldRevalidate === "boolean" ) {
5890+ return shouldRevalidateLoader ( match , {
5891+ ...unstable_shouldRevalidateArgs ,
5892+ defaultShouldRevalidate : callSiteDefaultShouldRevalidate ,
5893+ } ) ;
5894+ }
5895+
58765896 if ( typeof defaultShouldRevalidate === "boolean" ) {
58775897 return shouldRevalidateLoader ( match , {
58785898 ...unstable_shouldRevalidateArgs ,
0 commit comments