@bagelink/blox 1.15.178 → 1.15.180

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.
Files changed (67) hide show
  1. package/dist/{PreviewApp-B8EmNfyH.cjs → PreviewApp-APyemzqx.cjs} +1 -1
  2. package/dist/{PreviewApp-DdkAQqw2.js → PreviewApp-BKTydm92.js} +1 -1
  3. package/dist/{PreviewApp.vue_vue_type_style_index_0_lang-CPBuld3j.cjs → PreviewApp.vue_vue_type_style_index_0_lang-C0ZVst7R.cjs} +6 -6
  4. package/dist/{PreviewApp.vue_vue_type_style_index_0_lang-1JKQVLm2.js → PreviewApp.vue_vue_type_style_index_0_lang-DHb-NJ4C.js} +1 -1
  5. package/dist/api/index.d.ts +22 -0
  6. package/dist/api/index.d.ts.map +1 -1
  7. package/dist/components/BloxRouterView.vue.d.ts +26 -15
  8. package/dist/components/BloxRouterView.vue.d.ts.map +1 -1
  9. package/dist/composables/useLocale.d.ts +7 -0
  10. package/dist/composables/useLocale.d.ts.map +1 -1
  11. package/dist/composables/useLocaleNav.d.ts +2 -2
  12. package/dist/composables/useLocaleNav.d.ts.map +1 -1
  13. package/dist/content/{ContentDetailHost.vue.d.ts → ContentDetailView.vue.d.ts} +1 -1
  14. package/dist/content/ContentDetailView.vue.d.ts.map +1 -0
  15. package/dist/content/ContentHost.vue.d.ts +3 -0
  16. package/dist/content/ContentHost.vue.d.ts.map +1 -0
  17. package/dist/content/index.d.ts +9 -0
  18. package/dist/content/index.d.ts.map +1 -0
  19. package/dist/content/registry.d.ts +73 -0
  20. package/dist/content/registry.d.ts.map +1 -0
  21. package/dist/content/routes.d.ts +48 -0
  22. package/dist/content/routes.d.ts.map +1 -0
  23. package/dist/content/useContentItem.d.ts +37 -5
  24. package/dist/content/useContentItem.d.ts.map +1 -1
  25. package/dist/content/useContentSeo.d.ts +20 -7
  26. package/dist/content/useContentSeo.d.ts.map +1 -1
  27. package/dist/core.d.ts +3 -1
  28. package/dist/core.d.ts.map +1 -1
  29. package/dist/createBloxApp.d.ts.map +1 -1
  30. package/dist/data/useData.d.ts +91 -0
  31. package/dist/data/useData.d.ts.map +1 -0
  32. package/dist/index.cjs +185 -138
  33. package/dist/index.d.ts +7 -13
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.mjs +177 -131
  36. package/dist/localeRoutes.d.ts +15 -0
  37. package/dist/localeRoutes.d.ts.map +1 -0
  38. package/dist/localeStrategy.d.ts +13 -0
  39. package/dist/localeStrategy.d.ts.map +1 -1
  40. package/dist/{prerender-NHAqrTm3.js → prerender-DB1R4jiQ.js} +10 -9
  41. package/dist/{prerender-H72-UrK4.cjs → prerender-DXGy7pee.cjs} +10 -9
  42. package/dist/{core-KRHc4Bob.cjs → routes-C97aL4cQ.cjs} +415 -220
  43. package/dist/{core-Bp2bf8e4.js → routes-bhjTTXfU.js} +444 -249
  44. package/dist/ssg/cli.cjs +1 -1
  45. package/dist/ssg/cli.mjs +1 -1
  46. package/dist/ssg/createSSREntry.d.ts.map +1 -1
  47. package/dist/ssg/index.cjs +28 -19
  48. package/dist/ssg/index.mjs +31 -22
  49. package/dist/ssg/render-resolved-page.d.ts +6 -0
  50. package/dist/ssg/render-resolved-page.d.ts.map +1 -1
  51. package/dist/ssg/seo.d.ts +9 -3
  52. package/dist/ssg/seo.d.ts.map +1 -1
  53. package/dist/vite-plugin.cjs +2 -2
  54. package/dist/vite-plugin.d.ts.map +1 -1
  55. package/dist/vite-plugin.mjs +2 -2
  56. package/package.json +1 -1
  57. package/dist/components/LocaleRouterLink.vue.d.ts +0 -28
  58. package/dist/components/LocaleRouterLink.vue.d.ts.map +0 -1
  59. package/dist/composables/useData.d.ts +0 -22
  60. package/dist/composables/useData.d.ts.map +0 -1
  61. package/dist/composables/useSeo.d.ts +0 -20
  62. package/dist/composables/useSeo.d.ts.map +0 -1
  63. package/dist/content/ContentDetailHost.vue.d.ts.map +0 -1
  64. package/dist/content/defineContent.d.ts +0 -22
  65. package/dist/content/defineContent.d.ts.map +0 -1
  66. package/dist/routing/withLocaleRoutes.d.ts +0 -8
  67. package/dist/routing/withLocaleRoutes.d.ts.map +0 -1
package/dist/ssg/cli.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
  "use strict";
3
3
  const process = require("node:process");
4
- const prerender = require("../prerender-H72-UrK4.cjs");
4
+ const prerender = require("../prerender-DXGy7pee.cjs");
5
5
  async function resolveApiBase(mode) {
6
6
  if (process.env.BAGELINK_API_URL != null && process.env.BAGELINK_API_URL !== "") {
7
7
  return { apiBase: process.env.BAGELINK_API_URL };
package/dist/ssg/cli.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
  import process from "node:process";
3
- import { p as polyfillBloxSsgGlobals, f as fetchCmsSiteData, a as prerender } from "../prerender-NHAqrTm3.js";
3
+ import { p as polyfillBloxSsgGlobals, f as fetchCmsSiteData, a as prerender } from "../prerender-DB1R4jiQ.js";
4
4
  async function resolveApiBase(mode) {
5
5
  if (process.env.BAGELINK_API_URL != null && process.env.BAGELINK_API_URL !== "") {
6
6
  return { apiBase: process.env.BAGELINK_API_URL };
@@ -1 +1 @@
1
- {"version":3,"file":"createSSREntry.d.ts","sourceRoot":"","sources":["../../src/ssg/createSSREntry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAO,SAAS,EAAE,MAAM,KAAK,CAAA;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAO9D,MAAM,WAAW,yBAAyB;IACzC,oCAAoC;IACpC,aAAa,EAAE,SAAS,CAAA;IACxB;;;;OAIG;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,QAAQ,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IAC9D;;;OAGG;IACH,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACpD,wBAAwB;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,oGAAoG;IACpG,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAA;IAC5E;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CAC5C;AAED,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;CAClE;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,YAAY,CA6HnF"}
1
+ {"version":3,"file":"createSSREntry.d.ts","sourceRoot":"","sources":["../../src/ssg/createSSREntry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAO,SAAS,EAAE,MAAM,KAAK,CAAA;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAY9D,MAAM,WAAW,yBAAyB;IACzC,oCAAoC;IACpC,aAAa,EAAE,SAAS,CAAA;IACxB;;;;OAIG;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,QAAQ,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IAC9D;;;OAGG;IACH,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACpD,wBAAwB;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,oGAAoG;IACpG,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAA;IAC5E;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CAC5C;AAED,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;CAClE;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,YAAY,CA4JnF"}
@@ -22,17 +22,19 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
25
- const prerender = require("../prerender-H72-UrK4.cjs");
25
+ const prerender = require("../prerender-DXGy7pee.cjs");
26
26
  const ssg_client = require("./client.cjs");
27
27
  const pinia = require("pinia");
28
28
  const vue = require("vue");
29
- const core = require("../core-KRHc4Bob.cjs");
29
+ const routes = require("../routes-C97aL4cQ.cjs");
30
30
  async function renderBloxSsgPage(options) {
31
31
  const {
32
32
  url,
33
33
  resolvedData,
34
34
  renderToString,
35
35
  createAppForUrl,
36
+ collectData,
37
+ collectSeo,
36
38
  stateWindowKey = ssg_client.BLOX_STATE_WINDOW_KEY,
37
39
  stateKey = url,
38
40
  locale,
@@ -42,29 +44,27 @@ async function renderBloxSsgPage(options) {
42
44
  } = options;
43
45
  const g = globalThis;
44
46
  const prevState = g[stateWindowKey];
45
- const prevData = g[ssg_client.BLOX_DATA_WINDOW_KEY];
46
47
  if (resolvedData != null) {
47
48
  g[stateWindowKey] = { [stateKey]: resolvedData };
48
49
  }
49
- g[ssg_client.BLOX_DATA_WINDOW_KEY] = {};
50
- delete g[ssg_client.BLOX_PAGE_SEO_WINDOW_KEY];
51
50
  try {
52
- const { app, router } = createAppForUrl(url);
51
+ const { app, router, dataRegistry } = createAppForUrl(url);
53
52
  await router.push(url);
54
53
  await router.isReady();
55
54
  const html = await renderToString(app);
56
55
  const stateScript = resolvedData != null ? `<script>window[${JSON.stringify(stateWindowKey)}]=${JSON.stringify({ [stateKey]: resolvedData })};${"<"}/script>` : "";
57
56
  const collectionsScript = collections && Object.keys(collections).length > 0 ? `<script>window[${JSON.stringify(ssg_client.BLOX_COLLECTIONS_WINDOW_KEY)}]=${JSON.stringify(collections)};${"<"}/script>` : "";
58
57
  const websiteIdScript = websiteId ? `<script>window[${JSON.stringify(ssg_client.BLOX_WEBSITE_ID_WINDOW_KEY)}]=${JSON.stringify(websiteId)};${"<"}/script>` : "";
59
- const bloxData = g[ssg_client.BLOX_DATA_WINDOW_KEY];
60
- const dataScript = bloxData && Object.keys(bloxData).length > 0 ? `<script>window[${JSON.stringify(ssg_client.BLOX_DATA_WINDOW_KEY)}]=${JSON.stringify(bloxData)};${"<"}/script>` : "";
61
- const pageSeo = g[ssg_client.BLOX_PAGE_SEO_WINDOW_KEY] ?? null;
58
+ const seoHead = dataRegistry && collectSeo ? collectSeo(dataRegistry) : void 0;
59
+ const seoOverride = seoHead && Object.keys(seoHead).length > 0 ? seoHead : void 0;
60
+ const bloxData = dataRegistry && collectData ? collectData(dataRegistry) : {};
61
+ const dataScript = Object.keys(bloxData).length > 0 ? `<script>window[${JSON.stringify(routes.BLOX_DATA_WINDOW_KEY)}]=${safeJson(bloxData)};${"<"}/script>` : "";
62
62
  const head = prerender.buildPageHead({
63
63
  url,
64
64
  resolvedData,
65
65
  website,
66
66
  locale,
67
- pageSeo,
67
+ override: seoOverride,
68
68
  stateScript: [stateScript, collectionsScript, websiteIdScript, dataScript].filter(Boolean).join("\n")
69
69
  });
70
70
  const lang = locale || (website == null ? void 0 : website.default_locale) || "en";
@@ -76,14 +76,11 @@ async function renderBloxSsgPage(options) {
76
76
  } else {
77
77
  delete g[stateWindowKey];
78
78
  }
79
- if (prevData !== void 0) {
80
- g[ssg_client.BLOX_DATA_WINDOW_KEY] = prevData;
81
- } else {
82
- delete g[ssg_client.BLOX_DATA_WINDOW_KEY];
83
- }
84
- delete g[ssg_client.BLOX_PAGE_SEO_WINDOW_KEY];
85
79
  }
86
80
  }
81
+ function safeJson(value) {
82
+ return JSON.stringify(value).replace(/</g, "\\u003c");
83
+ }
87
84
  let _websiteId = null;
88
85
  function createBloxSSREntry(options) {
89
86
  var _a;
@@ -99,6 +96,7 @@ function createBloxSSREntry(options) {
99
96
  globalComponents = {}
100
97
  } = options;
101
98
  const apiBase = options.apiBase ?? (typeof process !== "undefined" ? (_a = process.env) == null ? void 0 : _a.BAGELINK_API_URL : void 0) ?? "https://api.bagel.to";
99
+ routes.setApiOrigin(apiBase);
102
100
  async function getWebsiteId() {
103
101
  if (_websiteId) return _websiteId;
104
102
  const res = await fetch(`${apiBase}/blox/websites`);
@@ -127,12 +125,16 @@ function createBloxSSREntry(options) {
127
125
  }
128
126
  function buildApp(url) {
129
127
  const router = createRouter("memory", url);
130
- const app = vue.createSSRApp(rootComponent);
128
+ const app = vue.createSSRApp({
129
+ name: "BloxSsgRoot",
130
+ render: () => vue.h(vue.Suspense, null, { default: () => vue.h(rootComponent) })
131
+ });
132
+ const dataRegistry = routes.provideBloxData(app, { server: true });
131
133
  const pinia$1 = pinia.createPinia();
132
134
  pinia$1.use(({ store: s }) => {
133
135
  s.router = vue.markRaw(router);
134
136
  });
135
- const blox = core.createBlox({
137
+ const blox = routes.createBlox({
136
138
  modules,
137
139
  websiteName,
138
140
  store,
@@ -151,13 +153,18 @@ function createBloxSSREntry(options) {
151
153
  blox.install(app, {});
152
154
  app.use(pinia$1);
153
155
  app.use(router);
156
+ for (const record of routes.generateContentRoutes(supportedLocales, locale)) {
157
+ if (!router.hasRoute(record.name)) router.addRoute(record);
158
+ }
159
+ routes.installLocaleAwareResolve(router, blox.strategy);
154
160
  for (const [name, comp] of Object.entries(globalComponents)) {
155
161
  app.component(name, comp);
156
162
  }
157
- return { app, router };
163
+ return { app, router, dataRegistry };
158
164
  }
159
165
  async function render(url, ctx) {
160
166
  const { locale: pageLocale, slug } = detectLocale(url);
167
+ routes.setActiveLocale(pageLocale);
161
168
  let resolvedData = null;
162
169
  try {
163
170
  resolvedData = await fetchResolvedPage(slug, pageLocale);
@@ -174,6 +181,8 @@ function createBloxSSREntry(options) {
174
181
  resolvedData,
175
182
  renderToString,
176
183
  createAppForUrl: buildApp,
184
+ collectData: routes.collectBloxData,
185
+ collectSeo: routes.collectBloxSeo,
177
186
  website: ctx.website,
178
187
  websiteId: ctx.websiteId,
179
188
  collections: ctx.collections
@@ -1,16 +1,18 @@
1
- import { b as buildPageHead } from "../prerender-NHAqrTm3.js";
2
- import { c, d, f, g, e, h, i, p, a } from "../prerender-NHAqrTm3.js";
3
- import { BLOX_STATE_WINDOW_KEY, BLOX_DATA_WINDOW_KEY, BLOX_PAGE_SEO_WINDOW_KEY, BLOX_COLLECTIONS_WINDOW_KEY, BLOX_WEBSITE_ID_WINDOW_KEY } from "./client.mjs";
4
- import { getCollectionCache, getEmbeddedWebsiteId, installBloxStateCache, installCollectionCache } from "./client.mjs";
1
+ import { b as buildPageHead } from "../prerender-DB1R4jiQ.js";
2
+ import { c, d, f, g, e, h, i, p, a } from "../prerender-DB1R4jiQ.js";
3
+ import { BLOX_STATE_WINDOW_KEY, BLOX_COLLECTIONS_WINDOW_KEY, BLOX_WEBSITE_ID_WINDOW_KEY } from "./client.mjs";
4
+ import { BLOX_DATA_WINDOW_KEY, BLOX_PAGE_SEO_WINDOW_KEY, getCollectionCache, getEmbeddedWebsiteId, installBloxStateCache, installCollectionCache } from "./client.mjs";
5
5
  import { createPinia } from "pinia";
6
- import { createSSRApp, markRaw } from "vue";
7
- import { c as createBlox } from "../core-Bp2bf8e4.js";
6
+ import { createSSRApp, h as h2, Suspense, markRaw } from "vue";
7
+ import { B as BLOX_DATA_WINDOW_KEY2, s as setApiOrigin, a as setActiveLocale, c as collectBloxData, b as collectBloxSeo, p as provideBloxData, d as createBlox, g as generateContentRoutes, i as installLocaleAwareResolve } from "../routes-bhjTTXfU.js";
8
8
  async function renderBloxSsgPage(options) {
9
9
  const {
10
10
  url,
11
11
  resolvedData,
12
12
  renderToString,
13
13
  createAppForUrl,
14
+ collectData,
15
+ collectSeo,
14
16
  stateWindowKey = BLOX_STATE_WINDOW_KEY,
15
17
  stateKey = url,
16
18
  locale,
@@ -20,29 +22,27 @@ async function renderBloxSsgPage(options) {
20
22
  } = options;
21
23
  const g2 = globalThis;
22
24
  const prevState = g2[stateWindowKey];
23
- const prevData = g2[BLOX_DATA_WINDOW_KEY];
24
25
  if (resolvedData != null) {
25
26
  g2[stateWindowKey] = { [stateKey]: resolvedData };
26
27
  }
27
- g2[BLOX_DATA_WINDOW_KEY] = {};
28
- delete g2[BLOX_PAGE_SEO_WINDOW_KEY];
29
28
  try {
30
- const { app, router } = createAppForUrl(url);
29
+ const { app, router, dataRegistry } = createAppForUrl(url);
31
30
  await router.push(url);
32
31
  await router.isReady();
33
32
  const html = await renderToString(app);
34
33
  const stateScript = resolvedData != null ? `<script>window[${JSON.stringify(stateWindowKey)}]=${JSON.stringify({ [stateKey]: resolvedData })};${"<"}/script>` : "";
35
34
  const collectionsScript = collections && Object.keys(collections).length > 0 ? `<script>window[${JSON.stringify(BLOX_COLLECTIONS_WINDOW_KEY)}]=${JSON.stringify(collections)};${"<"}/script>` : "";
36
35
  const websiteIdScript = websiteId ? `<script>window[${JSON.stringify(BLOX_WEBSITE_ID_WINDOW_KEY)}]=${JSON.stringify(websiteId)};${"<"}/script>` : "";
37
- const bloxData = g2[BLOX_DATA_WINDOW_KEY];
38
- const dataScript = bloxData && Object.keys(bloxData).length > 0 ? `<script>window[${JSON.stringify(BLOX_DATA_WINDOW_KEY)}]=${JSON.stringify(bloxData)};${"<"}/script>` : "";
39
- const pageSeo = g2[BLOX_PAGE_SEO_WINDOW_KEY] ?? null;
36
+ const seoHead = dataRegistry && collectSeo ? collectSeo(dataRegistry) : void 0;
37
+ const seoOverride = seoHead && Object.keys(seoHead).length > 0 ? seoHead : void 0;
38
+ const bloxData = dataRegistry && collectData ? collectData(dataRegistry) : {};
39
+ const dataScript = Object.keys(bloxData).length > 0 ? `<script>window[${JSON.stringify(BLOX_DATA_WINDOW_KEY2)}]=${safeJson(bloxData)};${"<"}/script>` : "";
40
40
  const head = buildPageHead({
41
41
  url,
42
42
  resolvedData,
43
43
  website,
44
44
  locale,
45
- pageSeo,
45
+ override: seoOverride,
46
46
  stateScript: [stateScript, collectionsScript, websiteIdScript, dataScript].filter(Boolean).join("\n")
47
47
  });
48
48
  const lang = locale || (website == null ? void 0 : website.default_locale) || "en";
@@ -54,14 +54,11 @@ async function renderBloxSsgPage(options) {
54
54
  } else {
55
55
  delete g2[stateWindowKey];
56
56
  }
57
- if (prevData !== void 0) {
58
- g2[BLOX_DATA_WINDOW_KEY] = prevData;
59
- } else {
60
- delete g2[BLOX_DATA_WINDOW_KEY];
61
- }
62
- delete g2[BLOX_PAGE_SEO_WINDOW_KEY];
63
57
  }
64
58
  }
59
+ function safeJson(value) {
60
+ return JSON.stringify(value).replace(/</g, "\\u003c");
61
+ }
65
62
  let _websiteId = null;
66
63
  function createBloxSSREntry(options) {
67
64
  var _a;
@@ -77,6 +74,7 @@ function createBloxSSREntry(options) {
77
74
  globalComponents = {}
78
75
  } = options;
79
76
  const apiBase = options.apiBase ?? (typeof process !== "undefined" ? (_a = process.env) == null ? void 0 : _a.BAGELINK_API_URL : void 0) ?? "https://api.bagel.to";
77
+ setApiOrigin(apiBase);
80
78
  async function getWebsiteId() {
81
79
  if (_websiteId) return _websiteId;
82
80
  const res = await fetch(`${apiBase}/blox/websites`);
@@ -105,7 +103,11 @@ function createBloxSSREntry(options) {
105
103
  }
106
104
  function buildApp(url) {
107
105
  const router = createRouter("memory", url);
108
- const app = createSSRApp(rootComponent);
106
+ const app = createSSRApp({
107
+ name: "BloxSsgRoot",
108
+ render: () => h2(Suspense, null, { default: () => h2(rootComponent) })
109
+ });
110
+ const dataRegistry = provideBloxData(app, { server: true });
109
111
  const pinia = createPinia();
110
112
  pinia.use(({ store: s }) => {
111
113
  s.router = markRaw(router);
@@ -129,13 +131,18 @@ function createBloxSSREntry(options) {
129
131
  blox.install(app, {});
130
132
  app.use(pinia);
131
133
  app.use(router);
134
+ for (const record of generateContentRoutes(supportedLocales, locale)) {
135
+ if (!router.hasRoute(record.name)) router.addRoute(record);
136
+ }
137
+ installLocaleAwareResolve(router, blox.strategy);
132
138
  for (const [name, comp] of Object.entries(globalComponents)) {
133
139
  app.component(name, comp);
134
140
  }
135
- return { app, router };
141
+ return { app, router, dataRegistry };
136
142
  }
137
143
  async function render(url, ctx) {
138
144
  const { locale: pageLocale, slug } = detectLocale(url);
145
+ setActiveLocale(pageLocale);
139
146
  let resolvedData = null;
140
147
  try {
141
148
  resolvedData = await fetchResolvedPage(slug, pageLocale);
@@ -152,6 +159,8 @@ function createBloxSSREntry(options) {
152
159
  resolvedData,
153
160
  renderToString,
154
161
  createAppForUrl: buildApp,
162
+ collectData: collectBloxData,
163
+ collectSeo: collectBloxSeo,
155
164
  website: ctx.website,
156
165
  websiteId: ctx.websiteId,
157
166
  collections: ctx.collections
@@ -1,4 +1,5 @@
1
1
  import { WebsiteRead } from '../api/types';
2
+ import { BloxDataRegistry, BloxSeoHead } from '../data/useData';
2
3
  export interface BloxSsgRouterLike {
3
4
  push: (url: string) => Promise<void>;
4
5
  isReady: () => Promise<void>;
@@ -22,7 +23,12 @@ export declare function renderBloxSsgPage<TApp>(options: {
22
23
  createAppForUrl: (url: string) => {
23
24
  app: TApp;
24
25
  router: BloxSsgRouterLike;
26
+ dataRegistry?: BloxDataRegistry;
25
27
  };
28
+ /** Serialize data collected during SSR (via `useData` + onServerPrefetch). */
29
+ collectData?: (registry: BloxDataRegistry) => Record<string, unknown>;
30
+ /** Evaluate `useSeo` sources after render → per-page SEO override. */
31
+ collectSeo?: (registry: BloxDataRegistry) => BloxSeoHead;
26
32
  stateWindowKey?: string;
27
33
  /**
28
34
  * Key under which the resolved data is embedded in `__BLOX_STATE__`.
@@ -1 +1 @@
1
- {"version":3,"file":"render-resolved-page.d.ts","sourceRoot":"","sources":["../../src/ssg/render-resolved-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAM/C,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACpC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE;IACtD,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,OAAO,GAAG,IAAI,CAAA;IAC5B,cAAc,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAC9C,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK;QAAE,GAAG,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,iBAAiB,CAAA;KAAE,CAAA;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,+EAA+E;IAC/E,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IAC5B,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;CACvC,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAgF/D"}
1
+ {"version":3,"file":"render-resolved-page.d.ts","sourceRoot":"","sources":["../../src/ssg/render-resolved-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAKpE,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACpC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE;IACtD,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,OAAO,GAAG,IAAI,CAAA;IAC5B,cAAc,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAC9C,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK;QAAE,GAAG,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,iBAAiB,CAAC;QAAC,YAAY,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAA;IAC3G,8EAA8E;IAC9E,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrE,sEAAsE;IACtE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,WAAW,CAAA;IACxD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,+EAA+E;IAC/E,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IAC5B,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;CACvC,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6E/D"}
package/dist/ssg/seo.d.ts CHANGED
@@ -52,13 +52,19 @@ export declare function buildPageHead(options: {
52
52
  stateScript?: string;
53
53
  /** Active render locale — selects per-locale structured data. */
54
54
  locale?: string;
55
- /** Runtime SEO from `useSeo()` during SSR (detail pages / blocks). */
56
- pageSeo?: {
55
+ /**
56
+ * Per-page SEO override contributed by a block via `useSeo()` during SSR.
57
+ * Takes precedence over CMS/site defaults — this is how router-driven detail
58
+ * pages (blog article, event, product) get real titles/descriptions/OG image.
59
+ * `alternates` (locale → path) drives hreflang for detail pages that don't
60
+ * have backend resolve-path alternates.
61
+ */
62
+ override?: {
57
63
  title?: string;
58
64
  description?: string;
59
65
  image?: string;
60
66
  alternates?: Record<string, string>;
61
- } | null;
67
+ };
62
68
  }): string;
63
69
  /**
64
70
  * Build site-wide `<head>` tags: verification, structured data, analytics, favicon.
@@ -1 +1 @@
1
- {"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../../src/ssg/seo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../../src/ssg/seo.ts"],"names":[],"mappings":"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"}
@@ -263,10 +263,10 @@ function bloxPlugin(options = {}) {
263
263
  const blockName = nameMatch[1];
264
264
  const exportName = blockName.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
265
265
  remaining = remaining.slice(0, callStart) + remaining.slice(i);
266
+ const scannable = callExpr.replace(/'(?:\\.|[^'\\])*'/g, "''").replace(/"(?:\\.|[^"\\])*"/g, '""').replace(/`(?:\\.|[^`\\])*`/g, "``").replace(/([a-z_$][\w$]*)\s*:/gi, ":");
266
267
  const identifiers = /* @__PURE__ */ new Set();
267
268
  const identRe = /\b([a-z_$][\w$]*)\b/gi;
268
269
  let identMatch;
269
- const strippedCall = callExpr.replace(/(['"`])(?:\\.|(?!\1).)*\1/g, '""').replace(/\b([a-z_$][\w$]*)\s*:/gi, ":");
270
270
  const SKIP_IDENTS = /* @__PURE__ */ new Set([
271
271
  "true",
272
272
  "false",
@@ -275,7 +275,7 @@ function bloxPlugin(options = {}) {
275
275
  "NaN",
276
276
  "Infinity"
277
277
  ]);
278
- while ((identMatch = identRe.exec(strippedCall)) !== null) {
278
+ while ((identMatch = identRe.exec(scannable)) !== null) {
279
279
  if (!SKIP_IDENTS.has(identMatch[1])) identifiers.add(identMatch[1]);
280
280
  }
281
281
  for (const ident of identifiers) {
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,MAAM,CAAA;AAM9C,MAAM,WAAW,iBAAiB;IACjC;;;;;OAKG;IACH,GAAG,CAAC,EAAE,OAAO,CAAA;IACb;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,EAAE,CAqapE"}
1
+ {"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,MAAM,CAAA;AAM9C,MAAM,WAAW,iBAAiB;IACjC;;;;;OAKG;IACH,GAAG,CAAC,EAAE,OAAO,CAAA;IACb;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,EAAE,CA4apE"}
@@ -239,10 +239,10 @@ function bloxPlugin(options = {}) {
239
239
  const blockName = nameMatch[1];
240
240
  const exportName = blockName.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
241
241
  remaining = remaining.slice(0, callStart) + remaining.slice(i);
242
+ const scannable = callExpr.replace(/'(?:\\.|[^'\\])*'/g, "''").replace(/"(?:\\.|[^"\\])*"/g, '""').replace(/`(?:\\.|[^`\\])*`/g, "``").replace(/([a-z_$][\w$]*)\s*:/gi, ":");
242
243
  const identifiers = /* @__PURE__ */ new Set();
243
244
  const identRe = /\b([a-z_$][\w$]*)\b/gi;
244
245
  let identMatch;
245
- const strippedCall = callExpr.replace(/(['"`])(?:\\.|(?!\1).)*\1/g, '""').replace(/\b([a-z_$][\w$]*)\s*:/gi, ":");
246
246
  const SKIP_IDENTS = /* @__PURE__ */ new Set([
247
247
  "true",
248
248
  "false",
@@ -251,7 +251,7 @@ function bloxPlugin(options = {}) {
251
251
  "NaN",
252
252
  "Infinity"
253
253
  ]);
254
- while ((identMatch = identRe.exec(strippedCall)) !== null) {
254
+ while ((identMatch = identRe.exec(scannable)) !== null) {
255
255
  if (!SKIP_IDENTS.has(identMatch[1])) identifiers.add(identMatch[1]);
256
256
  }
257
257
  for (const ident of identifiers) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/blox",
3
3
  "type": "module",
4
- "version": "1.15.178",
4
+ "version": "1.15.180",
5
5
  "description": "Blox page builder library for drag-and-drop page building and static data management",
6
6
  "author": {
7
7
  "name": "Bagel Studio",
@@ -1,28 +0,0 @@
1
- import { RouteLocationRaw } from 'vue-router';
2
- type __VLS_Props = {
3
- to: RouteLocationRaw;
4
- replace?: boolean;
5
- activeClass?: string;
6
- exactActiveClass?: string;
7
- ariaCurrentValue?: 'time' | 'step' | 'true' | 'false' | 'location' | 'page' | 'date';
8
- };
9
- declare function __VLS_template(): {
10
- attrs: Partial<{}>;
11
- slots: {
12
- default?(_: {}): any;
13
- default?(_: {}): any;
14
- default?(_: {}): any;
15
- };
16
- refs: {};
17
- rootEl: any;
18
- };
19
- type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
20
- declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
21
- declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
22
- export default _default;
23
- type __VLS_WithTemplateSlots<T, S> = T & {
24
- new (): {
25
- $slots: S;
26
- };
27
- };
28
- //# sourceMappingURL=LocaleRouterLink.vue.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"LocaleRouterLink.vue.d.ts","sourceRoot":"","sources":["../../src/components/LocaleRouterLink.vue"],"names":[],"mappings":"AAuEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AASlD,KAAK,WAAW,GAAG;IAClB,EAAE,EAAE,gBAAgB,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAA;CACpF,CAAC;AA+BF,iBAAS,cAAc;WAqDT,OAAO,IAA6B;;yBAZrB,GAAG;yBACH,GAAG;yBACH,GAAG;;;;EAe/B;AAWD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe,kSAMnB,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAAnG,wBAAoG;AAQpG,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
@@ -1,22 +0,0 @@
1
- import { MaybeRefOrGetter, Ref } from 'vue';
2
- import { BLOX_DATA_WINDOW_KEY } from '../ssg/constants';
3
- export { BLOX_DATA_WINDOW_KEY };
4
- export interface UseDataOptions<T> {
5
- default?: T | (() => T);
6
- }
7
- export interface UseDataResult<T> {
8
- data: Ref<T>;
9
- pending: Ref<boolean>;
10
- error: Ref<Error | null>;
11
- refresh: () => Promise<void>;
12
- }
13
- /**
14
- * Unified async data loader for Blox marketing apps (Nuxt-like `useAsyncData`).
15
- *
16
- * - **SSR/SSG**: `onServerPrefetch` awaits the fetcher; results land in `globalThis.__BLOX_DATA__`
17
- * and are embedded into the HTML by the SSG renderer.
18
- * - **Client hydrate**: reads `window.__BLOX_DATA__[key]` synchronously (no refetch).
19
- * - **SPA**: fetches on cache miss; re-runs when `key` changes.
20
- */
21
- export declare function useData<T>(key: MaybeRefOrGetter<string>, handler: () => Promise<T>, opts?: UseDataOptions<T>): UseDataResult<T>;
22
- //# sourceMappingURL=useData.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useData.d.ts","sourceRoot":"","sources":["../../src/composables/useData.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,GAAG,EAKR,MAAM,KAAK,CAAA;AACZ,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAEvD,OAAO,EAAE,oBAAoB,EAAE,CAAA;AAE/B,MAAM,WAAW,cAAc,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;CACvB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC/B,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;IACZ,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACrB,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAA;IACxB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5B;AA0BD;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACxB,GAAG,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAC7B,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,IAAI,GAAE,cAAc,CAAC,CAAC,CAAM,GAC1B,aAAa,CAAC,CAAC,CAAC,CAuClB"}
@@ -1,20 +0,0 @@
1
- import { MaybeRefOrGetter } from 'vue';
2
- export interface SeoInput {
3
- title?: string;
4
- description?: string;
5
- image?: string;
6
- /** Bare default-locale paths per locale code (e.g. `{ en: '/legal/x', es: '/legal/y' }`). */
7
- alternates?: Record<string, string>;
8
- }
9
- export type SeoGetter = MaybeRefOrGetter<SeoInput | null | undefined>;
10
- /**
11
- * Declare page SEO from a block / detail view.
12
- *
13
- * - **Client**: updates `document.title` + basic meta tags.
14
- * - **SSR/SSG**: writes `globalThis.__BLOX_PAGE_SEO__` so the prerenderer can
15
- * embed title/description/og/hreflang into `<head>`.
16
- */
17
- export declare function useSeo(getter: SeoGetter): void;
18
- /** Read the SEO payload written by `useSeo` during the current SSR render. */
19
- export declare function consumePageSeo(): SeoInput | null;
20
- //# sourceMappingURL=useSeo.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useSeo.d.ts","sourceRoot":"","sources":["../../src/composables/useSeo.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,gBAAgB,EAMrB,MAAM,KAAK,CAAA;AAGZ,MAAM,WAAW,QAAQ;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6FAA6F;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACnC;AAED,MAAM,MAAM,SAAS,GAAG,gBAAgB,CAAC,QAAQ,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;AA4CrE;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuB9C;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,IAAI,QAAQ,GAAG,IAAI,CAKhD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ContentDetailHost.vue.d.ts","sourceRoot":"","sources":["../../src/content/ContentDetailHost.vue"],"names":[],"mappings":";AAoIA,wBAKG"}
@@ -1,22 +0,0 @@
1
- import { Component } from 'vue';
2
- import { Router } from 'vue-router';
3
- export interface ContentRouteDef {
4
- /** Stable vue-router name for default-locale links `{ name, params:{ slug } }`. */
5
- name: string;
6
- /** Datastore collection. */
7
- collection: string;
8
- /** Bare (default-locale) route pattern with a `:slug` param. */
9
- route: string;
10
- /** Optional detail component; falls back to a minimal placeholder. */
11
- component?: Component;
12
- }
13
- /** Register data-powered detail collections (call once at app init, before createBloxApp). */
14
- export declare function defineContent(defs: ContentRouteDef[]): void;
15
- /** Snapshot of the content registry (used by prerender helpers / tests). */
16
- export declare function contentRoutes(): readonly ContentRouteDef[];
17
- /**
18
- * Add locale-aware named routes for every `defineContent` entry.
19
- * Must run **before** the CMS catch-all.
20
- */
21
- export declare function registerContentRoutesOnRouter(router: Router, locales: readonly string[], defaultLocale: string): void;
22
- //# sourceMappingURL=defineContent.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"defineContent.d.ts","sourceRoot":"","sources":["../../src/content/defineContent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AACpC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAIxC,MAAM,WAAW,eAAe;IAC/B,mFAAmF;IACnF,IAAI,EAAE,MAAM,CAAA;IACZ,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,SAAS,CAAC,EAAE,SAAS,CAAA;CACrB;AAID,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,IAAI,CAG3D;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,IAAI,SAAS,eAAe,EAAE,CAE1D;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC5C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,aAAa,EAAE,MAAM,GACnB,IAAI,CAeN"}
@@ -1,8 +0,0 @@
1
- import { Component } from 'vue';
2
- import { RouteRecordRaw } from 'vue-router';
3
- /**
4
- * Duplicate a route for the default locale (bare path) and every non-default
5
- * locale as `/:locale(xx|yy)/…`.
6
- */
7
- export declare function withLocaleRoutes(path: string, component: RouteRecordRaw['component'] | Component, locales: readonly string[], defaultLocale: string): RouteRecordRaw[];
8
- //# sourceMappingURL=withLocaleRoutes.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"withLocaleRoutes.d.ts","sourceRoot":"","sources":["../../src/routing/withLocaleRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC,GAAG,SAAS,EAClD,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,aAAa,EAAE,MAAM,GACnB,cAAc,EAAE,CAiBlB"}