@bygghammar/cms-platform 0.90.0-m7.11 → 0.90.0-m7.12

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/CHANGELOG.md CHANGED
@@ -8,6 +8,28 @@ matches `package.json` exactly. See
8
8
  Versions 0.1.0 through 0.78.0 predate this repository and were reconstructed
9
9
  from the published npm tarballs.
10
10
 
11
+ ## 0.90.0-m7.12
12
+
13
+ - The page SEO panel no longer prints a bare page path under the Canonical
14
+ heading. For a locale with no configured public domain there is no canonical
15
+ URL, and a path shown there reads as an address on whatever hostname the
16
+ backoffice happens to be open at.
17
+ - That case now says so in words — *No public URL — no domain configured for
18
+ this language* — instead of a relative path, the current or backoffice
19
+ hostname, another locale's domain, or a fabricated absolute URL.
20
+ - The Route row is unchanged and still shows the page path alongside the
21
+ current registry route, so nothing that was accurate is lost.
22
+ - A mapped locale is unaffected: its canonical preview stays absolute on that
23
+ locale's own domain. So is single-origin mode, where the one hostname serving
24
+ every language answers for each of them.
25
+ - `pageSeoPreviewCanonical` keeps its signature and its return value, path
26
+ fallback included, so existing callers are unaffected; what an empty origin
27
+ means is decided by `PageSeoPanelView`, which owns the display. The helper's
28
+ documentation now records that the fallback is not a URL.
29
+ - Regression coverage renders the panel and asserts the Canonical row itself
30
+ for the mapped, single-origin and unmapped cases.
31
+ - No migration and no database change.
32
+
11
33
  ## 0.90.0-m7.11
12
34
 
13
35
  - The page builder no longer invents a public URL for a locale with no
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bygghammar/cms-platform",
3
- "version": "0.90.0-m7.11",
3
+ "version": "0.90.0-m7.12",
4
4
  "description": "Shared CMS platform: blocks, block types, i18n core, UI primitives and design-token contract used by every Bygghammar/Voyara site.",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -38,7 +38,21 @@ export type PageSeoPanelViewProps = {
38
38
  pageKey?: string | null;
39
39
  /** Current registry route for a locale, shown in the preview panel. */
40
40
  registryRoute: (locale: string) => string;
41
- /** Public origin used to build the canonical preview URL. */
41
+ /**
42
+ * The public hostname this locale is published on, or `""` when there is
43
+ * none.
44
+ *
45
+ * Since m7.10 a deployment's locale-to-domain table is explicit: a locale
46
+ * absent from it has no public site. `""` is that answer — NO PUBLIC URL
47
+ * EXISTS — and it must never be read as "use a relative URL", "use whatever
48
+ * hostname the backoffice is open at", or "borrow another locale's domain".
49
+ * Each of those states an address the page is not served at, under the one
50
+ * heading a search engine is asked to believe.
51
+ *
52
+ * A host in single-origin mode — no mappings at all, every language under a
53
+ * locale prefix on one hostname — answers with that hostname, so the
54
+ * canonical stays absolute there.
55
+ */
42
56
  originForLocale: (locale: string) => string;
43
57
  /** Images found on this page, for the "use hero / pick from page" buttons. */
44
58
  pageImages: readonly PageSeoImageCandidate[];
@@ -171,10 +185,13 @@ export function PageSeoPanelView({
171
185
  locale: activeLocale,
172
186
  defaultLocale,
173
187
  });
174
- const previewCanonical = pageSeoPreviewCanonical({
175
- path: previewPath,
176
- origin: originForLocale(activeLocale),
177
- });
188
+ const previewOrigin = originForLocale(activeLocale);
189
+ // No hostname, no canonical. The path alone is not a fallback: printed here
190
+ // it reads as a URL on the hostname this screen is being served from, and an
191
+ // unmapped locale has no public hostname at all.
192
+ const previewCanonical = previewOrigin
193
+ ? pageSeoPreviewCanonical({ path: previewPath, origin: previewOrigin })
194
+ : null;
178
195
 
179
196
  return (
180
197
  <div>
@@ -344,7 +361,15 @@ export function PageSeoPanelView({
344
361
  <div className="text-[0.65rem] uppercase tracking-[0.22em] text-ink/55">Preview</div>
345
362
  <dl className="mt-4 grid grid-cols-1 md:grid-cols-[140px_1fr] gap-x-6 gap-y-2 text-sm">
346
363
  <dt className="text-ink/50">Canonical</dt>
347
- <dd className="font-mono text-ink/80 break-all">{previewCanonical}</dd>
364
+ <dd className="text-ink/80 break-all">
365
+ {previewCanonical ? (
366
+ <span className="font-mono">{previewCanonical}</span>
367
+ ) : (
368
+ <span className="text-ink/55">
369
+ No public URL — no domain configured for this language
370
+ </span>
371
+ )}
372
+ </dd>
348
373
  <dt className="text-ink/50">Route</dt>
349
374
  <dd className="font-mono text-ink/80">
350
375
  {previewPath} (current registry: {registryRoute(activeLocale)})
@@ -210,7 +210,17 @@ export function pageSeoPreviewPath(args: {
210
210
  return slug === "" ? `/${args.locale}` : `/${args.locale}/${slug}`;
211
211
  }
212
212
 
213
- /** Absolute canonical preview URL; falls back to the path when no domain is known. */
213
+ /**
214
+ * Absolute canonical preview URL for a page path on a known public origin.
215
+ *
216
+ * With no origin there is no URL to build, and the bare path returned instead
217
+ * is not one either: shown under a heading like "Canonical" it reads as an
218
+ * address on whatever hostname is being browsed — which, for a locale with no
219
+ * configured domain, is the backoffice rather than a public site. Deciding what
220
+ * an empty origin means belongs to the caller; `PageSeoPanelView` asks first
221
+ * and says so in words rather than printing this. The fallback is kept for
222
+ * callers that already depend on it.
223
+ */
214
224
  export function pageSeoPreviewCanonical(args: { path: string; origin?: string | null }): string {
215
225
  return args.origin ? `https://${args.origin}${args.path}` : args.path;
216
226
  }