@uniweb/runtime 0.6.20 → 0.6.22

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/runtime",
3
- "version": "0.6.20",
3
+ "version": "0.6.22",
4
4
  "description": "Minimal runtime for loading Uniweb foundations",
5
5
  "type": "module",
6
6
  "exports": {
@@ -35,13 +35,13 @@
35
35
  "node": ">=20.19"
36
36
  },
37
37
  "dependencies": {
38
- "@uniweb/core": "0.5.15",
39
- "@uniweb/theming": "0.1.2"
38
+ "@uniweb/core": "0.5.16",
39
+ "@uniweb/theming": "0.1.3"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@vitejs/plugin-react": "^4.5.2",
43
43
  "vite": "^7.3.1",
44
- "@uniweb/build": "0.8.23"
44
+ "@uniweb/build": "0.8.25"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "react": "^18.0.0 || ^19.0.0",
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import React, { useMemo, useEffect, useReducer, useRef } from 'react'
10
- import { useLocation } from 'react-router-dom'
10
+ import { useLocation, useNavigate } from 'react-router-dom'
11
11
  import BlockRenderer from './BlockRenderer.jsx'
12
12
  import Layout from './Layout.jsx'
13
13
  import { useHeadMeta } from '../hooks/useHeadMeta.js'
@@ -117,9 +117,32 @@ export default function PageRenderer() {
117
117
  // Resolve page from current URL and sync website.activePage immediately.
118
118
  // This must happen synchronously (not in an effect) so child components
119
119
  // like Header see the correct activePage during the same render cycle.
120
+ const navigate = useNavigate()
121
+
120
122
  let page = website?.getPage(location.pathname)
121
123
  if (page && website) website.setActivePage(location.pathname)
122
124
 
125
+ // Handle redirect pages — navigate to target immediately
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])
135
+
136
+ if (redirectTarget) return null
137
+
138
+ // Rewrite pages are served by an external site — the host handles routing.
139
+ // In SPA mode this shouldn't be reached (host proxies before JS loads),
140
+ // but if it is (e.g., dev mode), do a full page reload to let the host handle it.
141
+ if (page?.rewrite) {
142
+ window.location.reload()
143
+ return null
144
+ }
145
+
123
146
  // If no page found, try the 404 page (do NOT fall back to activePage/homepage)
124
147
  const isNotFound = !page
125
148
  if (isNotFound) {
@@ -163,7 +163,7 @@ export function useLinkInterceptor(options = {}) {
163
163
  const activeLocale = website.getActiveLocale()
164
164
  const defaultLocale = website.getDefaultLocale()
165
165
  const localeCodes = website.getLocales().map(l => l.code)
166
- const hrefMatch = routeHref.match(/^\/([a-z]{2,3}(?:-[A-Z]{2})?)(?:\/|$)/)
166
+ const hrefMatch = routeHref.match(/^\/([a-z]{2,3}(?:-[A-Za-z]{2,4})?)(?:\/|$)/)
167
167
  const hrefLocale = hrefMatch?.[1]
168
168
 
169
169
  let isLocaleSwitch = false