1
1
import './main.css'
2
2
import '@devrev/marketing-shared-components/dist/cjs/index.css'
3
3
4
- import ReactDOM from 'react-dom'
5
-
4
+ import ReactDOM from 'react-dom/client'
6
5
import React from 'react'
7
6
8
7
import Header from './components/header'
9
8
import Footer from './components/footer'
10
9
11
10
import { Search } from './components/search'
12
11
import { ThemeSwitch } from './components/theme-switch'
13
-
14
12
import { getPageData } from './modules/sanity/utils'
15
13
16
14
const FERN_CONTENT_WRAPPER_ID = 'fern-header-content-wrapper'
17
15
const DEVREV_CONTENT_WRAPPER_ID = 'devrev-header-content-wrapper'
18
-
19
16
const FERN_HEADER_CONTAINER_ID = 'fern-header'
20
17
21
18
const render = async ( ) => {
19
+ console . log ( 'Starting render function' )
22
20
/*
23
21
* This is a where we try to make async data call.
24
22
*/
25
-
26
23
const data = await getPageData ( )
27
-
24
+ console . log ( 'Page data fetched:' , data ? 'success' : 'failed' )
25
+
26
+ // Check if we're in a browser environment
27
+ if ( typeof window === 'undefined' ) {
28
+ console . log ( 'Not in browser environment, exiting render' )
29
+ return
30
+ }
31
+
32
+ console . log ( 'Looking for sidenav element' )
28
33
const sidenav = document . querySelector ( 'button.fern-search-bar' )
29
34
?. parentElement as HTMLElement
35
+ console . log ( 'Sidenav found:' , sidenav ? 'yes' : 'no' )
30
36
31
- const theme = document . getElementsByTagName ( 'html' ) [ 0 ] . getAttribute ( 'class' )
37
+ const theme = document . documentElement . getAttribute ( 'class' )
38
+ console . log ( 'Current theme:' , theme )
32
39
33
40
if ( ! document . getElementById ( 'sidenav-header-wrapper' ) ) {
34
41
const sidenavHeaderWrapper = document . createElement ( 'div' )
@@ -38,77 +45,142 @@ const render = async () => {
38
45
const search = document . createElement ( 'div' )
39
46
search . setAttribute ( 'id' , 'search-component' )
40
47
sidenavHeaderWrapper . appendChild ( search )
41
- ReactDOM . render ( React . createElement ( Search ) , search )
48
+ const searchRoot = ReactDOM . createRoot ( search )
49
+ searchRoot . render ( React . createElement ( Search ) )
42
50
43
51
const wrapper = document . createElement ( 'div' )
44
52
wrapper . setAttribute ( 'id' , 'theme-switch' )
45
53
sidenavHeaderWrapper . appendChild ( wrapper )
46
- ReactDOM . render ( React . createElement ( ThemeSwitch ) , wrapper )
54
+ const themeRoot = ReactDOM . createRoot ( wrapper )
55
+ themeRoot . render ( React . createElement ( ThemeSwitch ) )
47
56
48
57
sidenav . replaceWith ( sidenavHeaderWrapper )
49
58
}
50
59
51
- const fernHeaderId = document . getElementById ( FERN_CONTENT_WRAPPER_ID )
52
- const devrevHeaderId = document . getElementById ( DEVREV_CONTENT_WRAPPER_ID )
53
-
54
- if ( ! fernHeaderId && ! devrevHeaderId ) {
55
- // Main Container
56
- const fernHeaderContainer = document . createElement ( 'div' )
57
- fernHeaderContainer . setAttribute ( 'id' , FERN_HEADER_CONTAINER_ID )
58
-
59
- // Fern Header
60
- const fernContentWrapper = document . createElement ( 'div' )
61
- fernContentWrapper . setAttribute ( 'id' , FERN_CONTENT_WRAPPER_ID )
62
-
63
- const devrevContentWrapper = document . createElement ( 'div' )
64
- devrevContentWrapper . setAttribute ( 'id' , DEVREV_CONTENT_WRAPPER_ID )
65
-
66
- // Get existing fern-header element and its children
67
- const mainHeaderWrapper = document . getElementById ( FERN_HEADER_CONTAINER_ID )
68
-
69
- if ( mainHeaderWrapper ) {
70
- // Move all children to the wrapper
71
- while ( mainHeaderWrapper . firstChild ) {
72
- fernContentWrapper . appendChild ( mainHeaderWrapper . firstChild )
60
+ // Find the existing Fern header
61
+ console . log ( 'Looking for Fern header' )
62
+ const existingFernHeader = document . getElementById ( FERN_HEADER_CONTAINER_ID )
63
+ console . log ( 'Fern header found:' , existingFernHeader ? 'yes' : 'no' )
64
+
65
+ if ( existingFernHeader ) {
66
+ // Check if our custom wrappers already exist
67
+ let fernContentWrapper = document . getElementById ( FERN_CONTENT_WRAPPER_ID )
68
+ let devrevContentWrapper = document . getElementById ( DEVREV_CONTENT_WRAPPER_ID )
69
+ console . log ( 'Existing wrappers found:' , {
70
+ fernWrapper : fernContentWrapper ? 'yes' : 'no' ,
71
+ devrevWrapper : devrevContentWrapper ? 'yes' : 'no'
72
+ } )
73
+
74
+ // If wrappers don't exist, create them
75
+ if ( ! fernContentWrapper ) {
76
+ console . log ( 'Creating Fern content wrapper' )
77
+ fernContentWrapper = document . createElement ( 'div' )
78
+ fernContentWrapper . setAttribute ( 'id' , FERN_CONTENT_WRAPPER_ID )
79
+
80
+ // Move all existing children to the Fern wrapper
81
+ console . log ( 'Moving existing children to Fern wrapper' )
82
+ while ( existingFernHeader . firstChild ) {
83
+ fernContentWrapper . appendChild ( existingFernHeader . firstChild )
73
84
}
85
+
86
+ existingFernHeader . appendChild ( fernContentWrapper )
87
+ console . log ( 'Fern content wrapper created and populated' )
74
88
}
75
-
76
- fernHeaderContainer . appendChild ( fernContentWrapper )
77
- fernHeaderContainer . appendChild ( devrevContentWrapper )
78
-
79
- // Insert the new container where the original fern-header was
80
- if ( mainHeaderWrapper ) {
81
- mainHeaderWrapper . replaceWith ( fernHeaderContainer )
89
+
90
+ if ( ! devrevContentWrapper ) {
91
+ console . log ( 'Creating DevRev content wrapper' )
92
+ devrevContentWrapper = document . createElement ( 'div' )
93
+ devrevContentWrapper . setAttribute ( 'id' , DEVREV_CONTENT_WRAPPER_ID )
94
+ existingFernHeader . appendChild ( devrevContentWrapper )
95
+
96
+ // Render our custom header in the DevRev wrapper
97
+ console . log ( 'Rendering custom header in DevRev wrapper' )
98
+ const headerRoot = ReactDOM . createRoot ( devrevContentWrapper )
99
+
100
+ // Remove display style forcing for production
101
+ // fernContentWrapper.style.display = 'block'
102
+ // devrevContentWrapper.style.display = 'block'
103
+
104
+ // Pass header data to the component
105
+ headerRoot . render (
106
+ React . createElement ( Header , {
107
+ version : theme === 'dark' ? 'light' : 'dark' ,
108
+ ...data . header
109
+ } )
110
+ )
111
+ console . log ( 'Custom header rendered' )
82
112
} else {
83
- document . body . appendChild ( fernHeaderContainer )
113
+ // Update the header with current theme if it already exists
114
+ console . log ( 'Updating existing header with current theme' )
115
+ const headerRoot = ReactDOM . createRoot ( devrevContentWrapper )
116
+ headerRoot . render (
117
+ React . createElement ( Header , {
118
+ version : theme === 'dark' ? 'light' : 'dark' ,
119
+ ...data . header
120
+ } )
121
+ )
84
122
}
85
-
86
- ReactDOM . render (
123
+
124
+ // Make sure the header is visible
125
+ console . log ( 'Making header visible' )
126
+ existingFernHeader . style . display = 'block'
127
+ } else {
128
+ // If Fern header doesn't exist yet, create it
129
+ console . log ( 'Fern header not found, creating it' )
130
+ const newHeader = document . createElement ( 'div' )
131
+ newHeader . setAttribute ( 'id' , FERN_HEADER_CONTAINER_ID )
132
+ document . body . insertBefore ( newHeader , document . body . firstChild )
133
+
134
+ // Create DevRev content wrapper
135
+ const devrevContentWrapper = document . createElement ( 'div' )
136
+ devrevContentWrapper . setAttribute ( 'id' , DEVREV_CONTENT_WRAPPER_ID )
137
+ newHeader . appendChild ( devrevContentWrapper )
138
+
139
+ // Render our custom header
140
+ console . log ( 'Rendering custom header in new element' )
141
+ const headerRoot = ReactDOM . createRoot ( devrevContentWrapper )
142
+ headerRoot . render (
87
143
React . createElement ( Header , {
88
- ...data . header ,
89
- version : theme == 'dark' ? 'light' : 'dark' ,
90
- } ) ,
91
- devrevContentWrapper ,
92
- ( ) => {
93
- // Once the header component is loaded, make it visible
94
- const header = document . getElementById ( FERN_HEADER_CONTAINER_ID )
95
- if ( header ) header . style . display = 'block'
96
- }
144
+ version : theme === 'dark' ? 'light' : 'dark' ,
145
+ ...data . header
146
+ } )
97
147
)
148
+ console . log ( 'Custom header created and rendered' )
98
149
}
99
150
100
- ReactDOM . render (
101
- React . createElement ( Footer , { ...data . footer } ) ,
102
- document . getElementById ( 'fern-footer' ) ,
103
- ( ) => {
151
+ // Handle footer rendering
152
+ console . log ( 'Looking for footer element' )
153
+ const footerElement = document . getElementById ( 'fern-footer' )
154
+ console . log ( 'Footer element found:' , footerElement ? 'yes' : 'no' )
155
+
156
+ if ( footerElement ) {
157
+ // Check if footer is already rendered
158
+ const hasChildren = footerElement . hasChildNodes ( )
159
+ console . log ( 'Footer already has children:' , hasChildren ? 'yes' : 'no' )
160
+
161
+ if ( ! hasChildren ) {
162
+ console . log ( 'Rendering footer component' )
163
+ const footerRoot = ReactDOM . createRoot ( footerElement )
164
+ footerRoot . render ( React . createElement ( Footer , { ...data . footer } ) )
165
+
104
166
// Once the footer component is loaded, make it visible
105
- const footer = document . getElementById ( 'fern-footer' )
106
- if ( footer ) footer . style . display = 'block'
107
- } ,
108
- )
109
-
110
- // Add Plug component directly to body
111
- if ( ! document . getElementById ( 'plug-platform' ) ) {
167
+ console . log ( 'Making footer visible' )
168
+ footerElement . style . display = 'block'
169
+ }
170
+ } else {
171
+ // Create footer if it doesn't exist
172
+ console . log ( 'Creating new footer element' )
173
+ const newFooter = document . createElement ( 'div' )
174
+ newFooter . setAttribute ( 'id' , 'fern-footer' )
175
+ document . body . appendChild ( newFooter )
176
+
177
+ console . log ( 'Rendering footer in new element' )
178
+ const footerRoot = ReactDOM . createRoot ( newFooter )
179
+ footerRoot . render ( React . createElement ( Footer , { ...data . footer } ) )
180
+ newFooter . style . display = 'block'
181
+ console . log ( 'Footer created and rendered' )
182
+ }
183
+ if ( ! document . getElementById ( 'plug-platform' ) ) {
112
184
const plugScript = document . createElement ( 'script' )
113
185
plugScript . setAttribute ( 'type' , 'text/javascript' )
114
186
plugScript . setAttribute ( 'id' , 'plug-platform' )
@@ -142,38 +214,66 @@ const render = async () => {
142
214
}
143
215
}
144
216
}
217
+ console . log ( 'Render function completed' )
145
218
}
146
219
147
- let observations = 0
148
-
149
- if ( document . readyState === 'loading' ) {
150
- document . addEventListener ( 'DOMContentLoaded' , async ( ) => {
151
- await render ( )
152
- setupMutationObserver ( )
153
- } )
154
- } else {
155
- // DOM is already ready, run immediately
156
- render ( ) . then ( ( ) => {
157
- setupMutationObserver ( )
158
- } )
159
- }
160
-
161
- function setupMutationObserver ( ) {
162
- new MutationObserver ( async ( e , o ) => {
163
- await render ( )
164
- for ( const item of e ) {
165
- if ( item . target instanceof HTMLElement ) {
166
- const target = item . target
167
- if ( target . id === 'fern-header' || target . id === 'fern-footer' ) {
168
- if ( observations < 3 ) {
169
- // react hydration will trigger a mutation event
170
- observations ++
171
- } else {
172
- o . disconnect ( )
173
- }
174
- break
220
+ // For Next.js App Router compatibility
221
+ const initApp = ( ) => {
222
+ console . log ( 'Initializing app' )
223
+ if ( typeof window !== 'undefined' ) {
224
+ console . log ( 'Browser environment detected' )
225
+
226
+ // Function to attempt rendering multiple times
227
+ const attemptRender = ( attempts = 0 , maxAttempts = 5 ) => {
228
+ console . log ( `Render attempt ${ attempts + 1 } of ${ maxAttempts } ` )
229
+ render ( ) . then ( ( ) => {
230
+ // Check if header and footer are properly rendered
231
+ const header = document . getElementById ( DEVREV_CONTENT_WRAPPER_ID )
232
+ const footer = document . getElementById ( 'fern-footer' )
233
+ const headerRendered = header && header . children . length > 0
234
+ const footerRendered = footer && footer . children . length > 0
235
+
236
+ console . log ( 'Render check:' , {
237
+ headerRendered : headerRendered ? 'yes' : 'no' ,
238
+ footerRendered : footerRendered ? 'yes' : 'no'
239
+ } )
240
+
241
+ // If not rendered properly and we haven't reached max attempts, try again
242
+ if ( ( ! headerRendered || ! footerRendered ) && attempts < maxAttempts - 1 ) {
243
+ console . log ( 'Components not fully rendered, trying again in 500ms' )
244
+ setTimeout ( ( ) => attemptRender ( attempts + 1 , maxAttempts ) , 500 )
245
+ } else if ( attempts >= maxAttempts - 1 ) {
246
+ console . log ( 'Max render attempts reached' )
247
+ } else {
248
+ console . log ( 'Components successfully rendered' )
175
249
}
176
- }
250
+ } )
177
251
}
178
- } ) . observe ( document . body , { childList : true , subtree : true } )
252
+
253
+ // Check if the DOM is already loaded
254
+ if ( document . readyState === 'loading' ) {
255
+ console . log ( 'DOM still loading, adding DOMContentLoaded listener' )
256
+ document . addEventListener ( 'DOMContentLoaded' , ( ) => {
257
+ console . log ( 'DOMContentLoaded event fired' )
258
+ attemptRender ( )
259
+ } )
260
+ } else {
261
+ // DOM already loaded, render immediately
262
+ console . log ( 'DOM already loaded, rendering immediately' )
263
+ attemptRender ( )
264
+ }
265
+
266
+ // Also add a window load event to ensure everything is rendered
267
+ window . addEventListener ( 'load' , ( ) => {
268
+ console . log ( 'Window load event fired' )
269
+ render ( )
270
+ } )
271
+ } else {
272
+ console . log ( 'Not in browser environment, skipping initialization' )
273
+ }
179
274
}
275
+
276
+ // Initialize the app
277
+ console . log ( 'Starting application initialization' )
278
+ initApp ( )
279
+
0 commit comments