Skip to content

Commit 654925a

Browse files
committed
merged prev app router pr
1 parent 0d31b56 commit 654925a

File tree

2 files changed

+196
-92
lines changed

2 files changed

+196
-92
lines changed

custom-implementation/src/main.tsx

Lines changed: 191 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,41 @@
11
import './main.css'
22
import '@devrev/marketing-shared-components/dist/cjs/index.css'
33

4-
import ReactDOM from 'react-dom'
5-
4+
import ReactDOM from 'react-dom/client'
65
import React from 'react'
76

87
import Header from './components/header'
98
import Footer from './components/footer'
109

1110
import { Search } from './components/search'
1211
import { ThemeSwitch } from './components/theme-switch'
13-
1412
import { getPageData } from './modules/sanity/utils'
1513

1614
const FERN_CONTENT_WRAPPER_ID = 'fern-header-content-wrapper'
1715
const DEVREV_CONTENT_WRAPPER_ID = 'devrev-header-content-wrapper'
18-
1916
const FERN_HEADER_CONTAINER_ID = 'fern-header'
2017

2118
const render = async () => {
19+
console.log('Starting render function')
2220
/*
2321
* This is a where we try to make async data call.
2422
*/
25-
2623
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')
2833
const sidenav = document.querySelector('button.fern-search-bar')
2934
?.parentElement as HTMLElement
35+
console.log('Sidenav found:', sidenav ? 'yes' : 'no')
3036

31-
const theme = document.getElementsByTagName('html')[0].getAttribute('class')
37+
const theme = document.documentElement.getAttribute('class')
38+
console.log('Current theme:', theme)
3239

3340
if (!document.getElementById('sidenav-header-wrapper')) {
3441
const sidenavHeaderWrapper = document.createElement('div')
@@ -38,77 +45,142 @@ const render = async () => {
3845
const search = document.createElement('div')
3946
search.setAttribute('id', 'search-component')
4047
sidenavHeaderWrapper.appendChild(search)
41-
ReactDOM.render(React.createElement(Search), search)
48+
const searchRoot = ReactDOM.createRoot(search)
49+
searchRoot.render(React.createElement(Search))
4250

4351
const wrapper = document.createElement('div')
4452
wrapper.setAttribute('id', 'theme-switch')
4553
sidenavHeaderWrapper.appendChild(wrapper)
46-
ReactDOM.render(React.createElement(ThemeSwitch), wrapper)
54+
const themeRoot = ReactDOM.createRoot(wrapper)
55+
themeRoot.render(React.createElement(ThemeSwitch))
4756

4857
sidenav.replaceWith(sidenavHeaderWrapper)
4958
}
5059

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)
7384
}
85+
86+
existingFernHeader.appendChild(fernContentWrapper)
87+
console.log('Fern content wrapper created and populated')
7488
}
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')
82112
} 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+
)
84122
}
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(
87143
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+
})
97147
)
148+
console.log('Custom header created and rendered')
98149
}
99150

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+
104166
// 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')) {
112184
const plugScript = document.createElement('script')
113185
plugScript.setAttribute('type', 'text/javascript')
114186
plugScript.setAttribute('id', 'plug-platform')
@@ -142,38 +214,66 @@ const render = async () => {
142214
}
143215
}
144216
}
217+
console.log('Render function completed')
145218
}
146219

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')
175249
}
176-
}
250+
})
177251
}
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+
}
179274
}
275+
276+
// Initialize the app
277+
console.log('Starting application initialization')
278+
initApp()
279+

fern/docs.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@ js:
2626
- path: ./dist/output.js
2727
strategy: beforeInteractive
2828

29-
29+
layout:
30+
searchbar-placement: sidebar
31+
tabs-placement: sidebar
32+
disable-header: true
33+
3034
typography:
3135
bodyFont:
3236
name: SF Pro

0 commit comments

Comments
 (0)