@uniweb/runtime 0.6.24 → 0.6.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/components/PageRenderer.jsx +35 -30
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/runtime",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.25",
|
|
4
4
|
"description": "Minimal runtime for loading Uniweb foundations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@vitejs/plugin-react": "^4.5.2",
|
|
43
43
|
"vite": "^7.3.1",
|
|
44
|
-
"@uniweb/build": "0.8.
|
|
44
|
+
"@uniweb/build": "0.8.28"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -122,18 +122,10 @@ export default function PageRenderer() {
|
|
|
122
122
|
let page = website?.getPage(location.pathname)
|
|
123
123
|
if (page && website) website.setActivePage(location.pathname)
|
|
124
124
|
|
|
125
|
-
//
|
|
126
|
-
const redirectTarget = page?.redirect
|
|
127
|
-
useEffect(() => {
|
|
128
|
-
if (!redirectTarget) return
|
|
129
|
-
if (redirectTarget.startsWith('http')) {
|
|
130
|
-
window.location.replace(redirectTarget)
|
|
131
|
-
} else {
|
|
132
|
-
navigate(redirectTarget, { replace: true })
|
|
133
|
-
}
|
|
134
|
-
}, [redirectTarget, navigate])
|
|
125
|
+
// ─── Compute navigation targets (before hooks, no early returns) ───
|
|
135
126
|
|
|
136
|
-
|
|
127
|
+
// Explicit redirect: in page.yml
|
|
128
|
+
const redirectTarget = page?.redirect || null
|
|
137
129
|
|
|
138
130
|
// Auto-redirect for content-less pages (structural containers).
|
|
139
131
|
// Folders with page.yml but no markdown keep their route in the hierarchy;
|
|
@@ -141,36 +133,36 @@ export default function PageRenderer() {
|
|
|
141
133
|
const autoRedirectRoute = page && !page.redirect && !page.hasContent()
|
|
142
134
|
? page.getNavigableRoute()
|
|
143
135
|
: null
|
|
144
|
-
const shouldAutoRedirect = autoRedirectRoute && autoRedirectRoute !== page?.route
|
|
145
|
-
|
|
146
|
-
useEffect(() => {
|
|
147
|
-
if (!shouldAutoRedirect) return
|
|
148
|
-
navigate(autoRedirectRoute, { replace: true })
|
|
149
|
-
}, [shouldAutoRedirect, autoRedirectRoute, navigate])
|
|
150
|
-
|
|
151
|
-
if (shouldAutoRedirect) return null
|
|
152
|
-
|
|
153
|
-
// Rewrite pages are served by an external site — the host handles routing.
|
|
154
|
-
// In SPA mode this shouldn't be reached (host proxies before JS loads),
|
|
155
|
-
// but if it is (e.g., dev mode), do a full page reload to let the host handle it.
|
|
156
|
-
if (page?.rewrite) {
|
|
157
|
-
window.location.reload()
|
|
158
|
-
return null
|
|
159
|
-
}
|
|
136
|
+
const shouldAutoRedirect = !!(autoRedirectRoute && autoRedirectRoute !== page?.route)
|
|
160
137
|
|
|
161
138
|
// If no page found, try the 404 page (do NOT fall back to activePage/homepage)
|
|
162
|
-
const isNotFound = !page
|
|
139
|
+
const isNotFound = !page && !redirectTarget
|
|
163
140
|
if (isNotFound) {
|
|
164
141
|
page = website?.getNotFoundPage?.() || null
|
|
165
142
|
}
|
|
166
143
|
|
|
167
|
-
//
|
|
144
|
+
// Head metadata — compute for all cases (redirect pages get a fallback)
|
|
168
145
|
const headMeta = page?.getHeadMeta?.() || {
|
|
169
146
|
title: isNotFound ? 'Page Not Found' : (page?.title || 'Website'),
|
|
170
147
|
description: page?.description || ''
|
|
171
148
|
}
|
|
172
149
|
|
|
173
|
-
//
|
|
150
|
+
// ─── All hooks called unconditionally (React rules of hooks) ───
|
|
151
|
+
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
if (!redirectTarget) return
|
|
154
|
+
if (redirectTarget.startsWith('http')) {
|
|
155
|
+
window.location.replace(redirectTarget)
|
|
156
|
+
} else {
|
|
157
|
+
navigate(redirectTarget, { replace: true })
|
|
158
|
+
}
|
|
159
|
+
}, [redirectTarget, navigate])
|
|
160
|
+
|
|
161
|
+
useEffect(() => {
|
|
162
|
+
if (!shouldAutoRedirect) return
|
|
163
|
+
navigate(autoRedirectRoute, { replace: true })
|
|
164
|
+
}, [shouldAutoRedirect, autoRedirectRoute, navigate])
|
|
165
|
+
|
|
174
166
|
useHeadMeta(headMeta, { siteName })
|
|
175
167
|
|
|
176
168
|
// For dynamic pages created before collection data was available (hard reload),
|
|
@@ -183,6 +175,19 @@ export default function PageRenderer() {
|
|
|
183
175
|
return website.dataStore.onUpdate(forceUpdate)
|
|
184
176
|
}, [isDynamicPending, website])
|
|
185
177
|
|
|
178
|
+
// ─── Early returns (after all hooks) ───
|
|
179
|
+
|
|
180
|
+
if (redirectTarget) return null
|
|
181
|
+
if (shouldAutoRedirect) return null
|
|
182
|
+
|
|
183
|
+
// Rewrite pages are served by an external site — the host handles routing.
|
|
184
|
+
// In SPA mode this shouldn't be reached (host proxies before JS loads),
|
|
185
|
+
// but if it is (e.g., dev mode), do a full page reload to let the host handle it.
|
|
186
|
+
if (page?.rewrite) {
|
|
187
|
+
window.location.reload()
|
|
188
|
+
return null
|
|
189
|
+
}
|
|
190
|
+
|
|
186
191
|
if (!page) {
|
|
187
192
|
// No page and no 404 page defined - show shared fallback + dev debug info
|
|
188
193
|
const requestedPath = location.pathname
|