@@ -10,7 +10,7 @@ import {Injector} from '../di/injector';
1010import { EnvironmentInjector } from '../di/r3_injector' ;
1111import { validateMatchingNode } from '../hydration/error_handling' ;
1212import { CONTAINERS } from '../hydration/interfaces' ;
13- import { isInSkipHydrationBlock } from '../hydration/skip_hydration' ;
13+ import { hasInSkipHydrationBlockFlag , isInSkipHydrationBlock } from '../hydration/skip_hydration' ;
1414import { getSegmentHead , isDisconnectedNode , markRNodeAsClaimedByHydration } from '../hydration/utils' ;
1515import { findMatchingDehydratedView , locateDehydratedViewsInContainer } from '../hydration/views' ;
1616import { isType , Type } from '../interface/type' ;
@@ -311,7 +311,11 @@ const R3ViewContainerRef = class ViewContainerRef extends VE_ViewContainerRef {
311311
312312 const hydrationInfo = findMatchingDehydratedView ( this . _lContainer , templateRef . ssrId ) ;
313313 const viewRef = templateRef . createEmbeddedViewImpl ( context || < any > { } , injector , hydrationInfo ) ;
314- this . insertImpl ( viewRef , index , ! ! hydrationInfo ) ;
314+ // If there is a matching dehydrated view, but the host TNode is located in the skip
315+ // hydration block, this means that the content was detached (as a part of the skip
316+ // hydration logic) and it needs to be appended into the DOM.
317+ const skipDomInsertion = ! ! hydrationInfo && ! hasInSkipHydrationBlockFlag ( this . _hostTNode ) ;
318+ this . insertImpl ( viewRef , index , skipDomInsertion ) ;
315319 return viewRef ;
316320 }
317321
@@ -428,7 +432,11 @@ const R3ViewContainerRef = class ViewContainerRef extends VE_ViewContainerRef {
428432 const rNode = dehydratedView ?. firstChild ?? null ;
429433 const componentRef =
430434 componentFactory . create ( contextInjector , projectableNodes , rNode , environmentInjector ) ;
431- this . insertImpl ( componentRef . hostView , index , ! ! dehydratedView ) ;
435+ // If there is a matching dehydrated view, but the host TNode is located in the skip
436+ // hydration block, this means that the content was detached (as a part of the skip
437+ // hydration logic) and it needs to be appended into the DOM.
438+ const skipDomInsertion = ! ! dehydratedView && ! hasInSkipHydrationBlockFlag ( this . _hostTNode ) ;
439+ this . insertImpl ( componentRef . hostView , index , skipDomInsertion ) ;
432440 return componentRef ;
433441 }
434442
@@ -638,8 +646,13 @@ function locateOrCreateAnchorNode(
638646
639647 const hydrationInfo = hostLView [ HYDRATION ] ;
640648 const noOffsetIndex = hostTNode . index - HEADER_OFFSET ;
641- const isNodeCreationMode = ! hydrationInfo || isInSkipHydrationBlock ( hostTNode ) ||
642- isDisconnectedNode ( hydrationInfo , noOffsetIndex ) ;
649+
650+ // TODO(akushnir): this should really be a single condition, refactor the code
651+ // to use `hasInSkipHydrationBlockFlag` logic inside `isInSkipHydrationBlock`.
652+ const skipHydration = isInSkipHydrationBlock ( hostTNode ) || hasInSkipHydrationBlockFlag ( hostTNode ) ;
653+
654+ const isNodeCreationMode =
655+ ! hydrationInfo || skipHydration || isDisconnectedNode ( hydrationInfo , noOffsetIndex ) ;
643656
644657 // Regular creation mode.
645658 if ( isNodeCreationMode ) {
0 commit comments