@uniweb/build 0.74.3 → 0.74.4

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/build",
3
- "version": "0.74.3",
3
+ "version": "0.74.4",
4
4
  "description": "Build tooling for the Uniweb Component Web Platform",
5
5
  "type": "module",
6
6
  "exports": {
@@ -58,14 +58,14 @@
58
58
  "sharp": "^0.35.3",
59
59
  "yaml": "^2.5.0",
60
60
  "@uniweb/content-reader": "^1.2.8",
61
- "@uniweb/content-writer": "^0.3.4",
62
- "@uniweb/schemas": "^0.10.1",
63
61
  "@uniweb/projections": "^0.7.11",
64
62
  "@uniweb/theming": "^0.2.0",
63
+ "@uniweb/content-writer": "^0.3.4",
64
+ "@uniweb/schemas": "^0.10.1",
65
65
  "@uniweb/semantic-parser": "^1.5.1"
66
66
  },
67
67
  "optionalDependencies": {
68
- "@uniweb/runtime": "^0.28.6"
68
+ "@uniweb/runtime": "^0.28.7"
69
69
  },
70
70
  "peerDependencies": {
71
71
  "vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
@@ -74,8 +74,8 @@
74
74
  "@tailwindcss/vite": "^4.0.0",
75
75
  "@vitejs/plugin-react": "^4.0.0 || ^5.0.0",
76
76
  "vite-plugin-svgr": "^4.0.0",
77
- "@uniweb/core": "^0.35.1",
78
- "@uniweb/runtime": "^0.28.6"
77
+ "@uniweb/core": "^0.35.2",
78
+ "@uniweb/runtime": "^0.28.7"
79
79
  },
80
80
  "peerDependenciesMeta": {
81
81
  "vite": {
@@ -30,6 +30,7 @@
30
30
  import { readFile, writeFile } from 'node:fs/promises'
31
31
  import { existsSync } from 'node:fs'
32
32
  import { join } from 'node:path'
33
+ import { resolveRoute } from '@uniweb/core/resolve-route'
33
34
 
34
35
  import { DeployError, spawnTool, readCredential, credentialHint } from './deploy-utils.js'
35
36
  import {
@@ -61,7 +62,13 @@ async function collectRoutingEntries(localeConfigs) {
61
62
  const prefix = localeConfig.routePrefix || ''
62
63
  for (const page of siteContent.pages || []) {
63
64
  if (page.redirect) {
64
- entries.push(`${prefix}${page.route} ${page.redirect} 302`)
65
+ // Where the app sends a visitor of this locale (`resolveRoute`): a page of the site in their
66
+ // language, anything else as written. ⛔ Until 2026-09-30 the target was written raw, so
67
+ // `/fr/old` redirected a French reader to the English page.
68
+ const route = `${prefix}${page.route}`
69
+ const resolved = resolveRoute(siteContent, route, { activeLocale: prefix ? prefix.slice(1) : undefined })
70
+ const location = resolved.kind === 'redirect' ? resolved.location : page.redirect
71
+ entries.push(`${route} ${location} 302`)
65
72
  }
66
73
  if (page.rewrite) {
67
74
  entries.push(`${prefix}${page.route}/* ${page.rewrite}/:splat 200`)
package/src/prerender.js CHANGED
@@ -1003,10 +1003,18 @@ export async function prerenderSite(siteDir, options = {}) {
1003
1003
  const translatedPageRoute = isDefault ? page.route : website.translateRoute(page.route, locale)
1004
1004
  const outputRoute = routePrefix + translatedPageRoute
1005
1005
 
1006
- // Redirect pages: emit a redirect HTML instead of rendering content
1006
+ // Redirect pages: emit a redirect HTML instead of rendering content — to where the app sends
1007
+ // a visitor of this locale (`resolveRoute`): a page of the site in their language, anything
1008
+ // else as written. ⛔ Until 2026-09-30 the stub wrote the target raw, so a French reader was
1009
+ // sent to the English page and a relative target resolved against the stub's own URL.
1007
1010
  if (page.redirect) {
1008
- onProgress(` Redirect ${outputRoute} → ${page.redirect}`)
1009
- const redirectHtml = `<!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equiv="refresh" content="0;url=${page.redirect}"><link rel="canonical" href="${page.redirect}"><title>Redirecting...</title></head><body><p>Redirecting to <a href="${page.redirect}">${page.redirect}</a></p></body></html>`
1011
+ const resolved = website.resolveRoute(page.route)
1012
+ const location = resolved.kind === 'redirect' ? resolved.location : page.redirect
1013
+ const target = location.startsWith('/') && !location.startsWith('//')
1014
+ ? (website.basePath || '') + location
1015
+ : location
1016
+ onProgress(` Redirect ${outputRoute} → ${target}`)
1017
+ const redirectHtml = `<!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equiv="refresh" content="0;url=${target}"><link rel="canonical" href="${target}"><title>Redirecting...</title></head><body><p>Redirecting to <a href="${target}">${target}</a></p></body></html>`
1010
1018
  const outputPath = getOutputPath(distDir, outputRoute)
1011
1019
  await mkdir(dirname(outputPath), { recursive: true })
1012
1020
  await writeFile(outputPath, redirectHtml)
@@ -38,6 +38,7 @@ import { parseFetchConfig, toFetchList } from './data-fetcher.js'
38
38
  import { resolveExtensionUrls } from './extension-urls.js'
39
39
  import { buildTheme, extractFoundationVars } from '../theme/index.js'
40
40
  import { resolveDefaultLocale, resolvePublishableLocales, validateLanguageConfig, pageRouteQuery, currentFor } from '@uniweb/core'
41
+ import { authoredRedirectTarget } from '@uniweb/core/resolve-route'
41
42
  import { parseFrontmatter } from '../utils/frontmatter.js'
42
43
  import { parseGrid } from '@uniweb/schemas/grid'
43
44
 
@@ -1333,11 +1334,9 @@ async function processPage(pagePath, pageName, siteRoot, { isIndex = false, pare
1333
1334
  if (pageConfig.redirect) {
1334
1335
  const route = isIndex ? parentRoute
1335
1336
  : parentRoute === '/' ? `/${pageName}` : `${parentRoute}/${pageName}`
1336
- const redirect = pageConfig.redirect
1337
- // Resolve relative redirects against the page's own route
1338
- const target = redirect.startsWith('/') || redirect.startsWith('http')
1339
- ? redirect
1340
- : (route === '/' ? `/${redirect}` : `${route}/${redirect}`)
1337
+ // A relative redirect resolves against the page's own route — core's rule, which a host
1338
+ // resolving a pushed payload applies too (`@uniweb/core/resolve-route`).
1339
+ const target = authoredRedirectTarget(route, pageConfig.redirect)
1341
1340
 
1342
1341
  return {
1343
1342
  page: {