uniweb 0.22.0 → 0.23.0

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",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "description": "Create structured Vite + React sites with content/code separation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -41,13 +41,13 @@
41
41
  "js-yaml": "^4.1.0",
42
42
  "prompts": "^2.4.2",
43
43
  "tar": "^7.0.0",
44
- "@uniweb/core": "^0.8.5",
45
- "@uniweb/kit": "^0.12.0",
46
- "@uniweb/runtime": "^0.11.7"
44
+ "@uniweb/core": "^0.9.0",
45
+ "@uniweb/kit": "^0.12.1",
46
+ "@uniweb/runtime": "^0.11.8"
47
47
  },
48
48
  "peerDependencies": {
49
+ "@uniweb/build": "^0.23.0",
49
50
  "@uniweb/content-reader": "^1.2.2",
50
- "@uniweb/build": "^0.22.0",
51
51
  "@uniweb/semantic-parser": "^1.2.2"
52
52
  },
53
53
  "peerDependenciesMeta": {
@@ -1954,6 +1954,93 @@ from. `values` keeps the `File` so your input can show its selection.
1954
1954
 
1955
1955
  Full reference: `development/receiving-form-submissions.md`.
1956
1956
 
1957
+ ### Tracking (`tracking:`)
1958
+
1959
+ A site may declare one **tracking destination**, and everything worth counting
1960
+ goes there as an event on a single stream. A page visit is just the event the
1961
+ runtime emits by itself.
1962
+
1963
+ ```yaml
1964
+ # site.yml — your own collector, on any host
1965
+ tracking: https://plausible.io/api/event
1966
+
1967
+ # or, when it needs more than an address
1968
+ tracking:
1969
+ endpoint: https://plausible.io/api/event
1970
+ consent: required
1971
+ ```
1972
+
1973
+ A host may also supply one under `services.tracking`, and the usual precedence
1974
+ applies: yours wins, then the host's, then neither.
1975
+
1976
+ **The runtime reports `page_view` on every route change, including the first.**
1977
+ That is the only thing it emits on its own — everything else is yours to report:
1978
+
1979
+ ```jsx
1980
+ // In a section type, the block is already in your props.
1981
+ block.track('video_milestone', { milestone: 50 })
1982
+ ```
1983
+
1984
+ `block.track` attaches the page path and the section type for you. For an event
1985
+ with no block in hand, use the hook:
1986
+
1987
+ ```jsx
1988
+ import { useTracker } from '@uniweb/kit'
1989
+
1990
+ const { track } = useTracker()
1991
+ <button onClick={() => track('brochure_download', { file: 'specs.pdf' })}>…</button>
1992
+ ```
1993
+
1994
+ The event name is yours — there is no list of permitted names.
1995
+
1996
+ ⛔ **Never guard a `track()` call.** A site with **no** tracking destination is
1997
+ the default and the majority: the call returns having done nothing, opened no
1998
+ connection, and thrown nothing. Absent is the normal state, not an error — so
1999
+ don't check whether tracking is on, and never render differently because of it.
2000
+ There is no "is tracking enabled" question a component should be asking.
2001
+
2002
+ ⚠️ **If a site asks for consent**, tracking holds everything until a visitor
2003
+ answers; granting sends what was buffered, denying discards it. A consent banner
2004
+ is an ordinary component:
2005
+
2006
+ ```jsx
2007
+ import { useTrackingConsent } from '@uniweb/kit'
2008
+
2009
+ const { status, grant, deny } = useTrackingConsent()
2010
+ if (status !== 'pending') return null
2011
+ return <CookieBanner onAccept={grant} onReject={deny} />
2012
+ ```
2013
+
2014
+ Without `consent: required`, tracking starts immediately — declaring a
2015
+ destination is the site owner's decision to make, not the framework's.
2016
+
2017
+ Every event carries a **`visit`** key on the envelope — opaque, generated at page
2018
+ load, the same for every event of that page load — so a collector can order what
2019
+ happened into a journey.
2020
+
2021
+ > **What is never sent:** no visitor id, no fingerprint, no session spanning days
2022
+ > or tabs, and **nothing is written to the visitor's device** — no cookie, no
2023
+ > local storage. The `visit` key lives in memory and dies with the document, so
2024
+ > it identifies one page load rather than a person. A `page_view` carries the
2025
+ > path, and — captured once when the page first loads, then replayed on each view
2026
+ > — the external referrer and any `utm_*` the visitor arrived with. Nothing else.
2027
+
2028
+ ### ⛔ Use kit. Never touch the `uniweb` global
2029
+
2030
+ Everything above reaches the runtime through `@uniweb/kit` or through something
2031
+ handed to your component as a prop. That is the rule, not a stylistic preference:
2032
+
2033
+ - ✅ `useWebsite()`, `useTracker()`, `resolveService(website, …)` — kit hooks and
2034
+ utilities.
2035
+ - ✅ `block.track(…)`, `block.page`, `block.website` — the block **arrives in your
2036
+ props**, so calling methods on it is not reaching for a global.
2037
+ - ⛔ `globalThis.uniweb`, `window.uniweb` — never, in a foundation.
2038
+
2039
+ The singleton is framework internals: its shape is not part of the contract with
2040
+ foundations, and code that reads it directly breaks on changes that were never
2041
+ breaking changes. If you need something kit does not expose yet, that is worth
2042
+ reporting — not worth reaching around.
2043
+
1957
2044
  <!-- template:loom -->
1958
2045
  ### Content handlers
1959
2046
 
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-08-13T20:52:45.396Z",
3
+ "generatedAt": "2026-08-14T23:58:32.904Z",
4
4
  "packages": {
5
5
  "@uniweb/build": {
6
- "version": "0.22.0",
6
+ "version": "0.23.0",
7
7
  "path": "framework/build",
8
8
  "deps": [
9
9
  "@uniweb/content-reader",
@@ -28,7 +28,7 @@
28
28
  "deps": []
29
29
  },
30
30
  "@uniweb/core": {
31
- "version": "0.8.5",
31
+ "version": "0.9.0",
32
32
  "path": "framework/core",
33
33
  "deps": [
34
34
  "@uniweb/semantic-parser",
@@ -46,7 +46,7 @@
46
46
  "deps": []
47
47
  },
48
48
  "@uniweb/kit": {
49
- "version": "0.12.0",
49
+ "version": "0.12.1",
50
50
  "path": "framework/kit",
51
51
  "deps": [
52
52
  "@uniweb/core",
@@ -65,7 +65,7 @@
65
65
  "deps": []
66
66
  },
67
67
  "@uniweb/projections": {
68
- "version": "0.3.1",
68
+ "version": "0.3.2",
69
69
  "path": "framework/projections",
70
70
  "deps": [
71
71
  "@uniweb/content-writer",
@@ -73,7 +73,7 @@
73
73
  ]
74
74
  },
75
75
  "@uniweb/runtime": {
76
- "version": "0.11.7",
76
+ "version": "0.11.8",
77
77
  "path": "framework/runtime",
78
78
  "deps": [
79
79
  "@uniweb/core",
@@ -111,7 +111,7 @@
111
111
  "deps": []
112
112
  },
113
113
  "@uniweb/unipress": {
114
- "version": "0.8.7",
114
+ "version": "0.8.8",
115
115
  "path": "framework/unipress",
116
116
  "deps": [
117
117
  "@uniweb/build",