@@ -245,10 +245,54 @@ export const LiveBlogEpic = ({
245245
246246 const [ pageUrl , setPageUrl ] = useState < string | undefined > ( ) ;
247247
248+ const [ epicPlaceholder , setEpicPlaceholder ] = useState < HTMLElement | null > (
249+ null ,
250+ ) ;
251+
248252 useEffect ( ( ) => {
249253 setPageUrl ( window . location . origin + window . location . pathname ) ;
250254 } , [ ] ) ;
251255
256+ useEffect ( ( ) => {
257+ /**
258+ * Here we decide where to insert the epic.
259+ *
260+ * If the url contains a permalink then we
261+ * want to insert it immediately after that block to prevent any CLS issues.
262+ *
263+ * Otherwise, we choose a random position near the top of the blog
264+ */
265+ const placeholder = document . createElement ( 'article' ) ;
266+ if ( window . location . href . includes ( '#block-' ) ) {
267+ // Because we're using a permalink there's a possibility the epic will render in
268+ // view. To prevent confusing layout shift we initially hide the message so that
269+ // we can reveal (animate in) it once it has been rendered
270+ placeholder . classList . add ( 'pending' ) ;
271+ const blockId = window . location . hash . slice ( 1 ) ;
272+ const blockLinkedTo = document . getElementById ( blockId ) ;
273+ if ( blockLinkedTo ) {
274+ insertAfter ( blockLinkedTo , placeholder ) ;
275+ }
276+ placeholder . classList . add ( 'reveal' ) ;
277+ placeholder . classList . remove ( 'pending' ) ;
278+ } else {
279+ // This is a simple page load so we simply insert the epic somewhere near the top
280+ // of the blog
281+ const randomPosition = Math . floor ( Math . random ( ) * 3 ) + 1 ; // 1, 2 or 3
282+ const aBlockNearTheTop =
283+ document . querySelectorAll < HTMLElement > ( 'article.block' ) [
284+ randomPosition
285+ ] ;
286+ if ( aBlockNearTheTop ) {
287+ insertAfter ( aBlockNearTheTop , placeholder ) ;
288+ }
289+ }
290+ setEpicPlaceholder ( placeholder ) ;
291+ return ( ) => {
292+ placeholder . remove ( ) ;
293+ } ;
294+ } , [ ] ) ;
295+
252296 // First construct the payload
253297 const payload = usePayload ( {
254298 shouldHideReaderRevenue,
@@ -258,40 +302,8 @@ export const LiveBlogEpic = ({
258302 pageId,
259303 keywordIds,
260304 } ) ;
261- if ( ! ophanPageViewId || ! payload || ! pageUrl ) return null ;
262-
263- /**
264- * Here we decide where to insert the epic.
265- *
266- * If the url contains a permalink then we
267- * want to insert it immediately after that block to prevent any CLS issues.
268- *
269- * Otherwise, we choose a random position near the top of the blog
270- */
271- const epicPlaceholder = document . createElement ( 'article' ) ;
272- if ( window . location . href . includes ( '#block-' ) ) {
273- // Because we're using a permalink there's a possibility the epic will render in
274- // view. To prevent confusing layout shift we initially hide the message so that
275- // we can reveal (animate in) it once it has been rendered
276- epicPlaceholder . classList . add ( 'pending' ) ;
277- const blockId = window . location . hash . slice ( 1 ) ;
278- const blockLinkedTo = document . getElementById ( blockId ) ;
279- if ( blockLinkedTo ) {
280- insertAfter ( blockLinkedTo , epicPlaceholder ) ;
281- }
282- epicPlaceholder . classList . add ( 'reveal' ) ;
283- epicPlaceholder . classList . remove ( 'pending' ) ;
284- } else {
285- // This is a simple page load so we simply insert the epic somewhere near the top
286- // of the blog
287- const randomPosition = Math . floor ( Math . random ( ) * 3 ) + 1 ; // 1, 2 or 3
288- const aBlockNearTheTop =
289- document . querySelectorAll < HTMLElement > ( 'article.block' ) [
290- randomPosition
291- ] ;
292- if ( aBlockNearTheTop ) {
293- insertAfter ( aBlockNearTheTop , epicPlaceholder ) ;
294- }
305+ if ( ! ophanPageViewId || ! payload || ! pageUrl || ! epicPlaceholder ) {
306+ return null ;
295307 }
296308
297309 return createPortal (
0 commit comments