fimo 2.6.0-staging.4 → 2.7.0-experimental.1

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.
@@ -1,6 +1,20 @@
1
1
  # Analytics workflow
2
2
 
3
- Pageview aggregates for the **published** site are stored in Fimo's analytics pipeline. Preview traffic is not recorded.
3
+ Pageview aggregates for the **published** site are stored in Fimo's analytics pipeline.
4
+ Ingestion accepts any resolved branch, so do not assume that every possible preview
5
+ sender is excluded; a preview visit is stored under its own branch rather than dropped.
6
+
7
+ For tracking setup, load `fimo-code`. Reading analytics does not install a tracker.
8
+ If counts are zero, check the selected branch, built scripts, enabled setting,
9
+ browser requests and stored results before diagnosing a missing implementation.
10
+ A successful HTTP response alone does not establish that a row was stored.
11
+ Use `fimo-code` analytics setup for the standalone `fimo-analytics` APIs.
12
+ Confirm that the selected package release contains them before generating imports;
13
+ older Fimo releases and existing published sites do not acquire a tracker automatically.
14
+
15
+ For Studio tracking verification, load `fimo-studio` and its analytics reference.
16
+ Its tracking status is independent of the chart range and device filter; a failed
17
+ status check is not evidence of missing tracking.
4
18
 
5
19
  Analytics has a **retained preview for every org** — free included. The free default is a 7-day retention window, so short ranges (`today`, `yesterday`, `this_week`, `last_week`, `last_7_days`) work for everyone. **Extended date ranges and longer retention are paid** — `last_30_days`, `last_90_days`, `this_month`, `last_month`, `last_quarter`, `last_year`, and `custom` require the `canUseExtendedDateRanges` privilege, which only paid orgs have. Asking for an extended range as a free user returns a 403 with an upgrade hint.
6
20
 
@@ -13,7 +27,7 @@ fimo --branch prod analytics pageviews --days 7 --json
13
27
  fimo --branch prod analytics top countries --json
14
28
  ```
15
29
 
16
- Structured read results include `branch` (`data.branch` in the CLI JSON envelope). Check it before interpreting metrics. An intentional `--branch <name>` overrides the default; zero traffic on `main` or a preview branch does **not** mean the published site has no traffic. Preview visits are not collected. If publication or access is unavailable, report that limitation; do not fall back to another branch or present the failure as zero traffic.
30
+ Structured read results include `branch` (`data.branch` in the CLI JSON envelope). Check it before interpreting metrics. An intentional `--branch <name>` overrides the default; zero traffic on `main` or a preview branch does **not** mean the published site has no traffic. Preview visits do not appear in published traffic. If publication or access is unavailable, report that limitation; do not fall back to another branch or present the failure as zero traffic.
17
31
 
18
32
  SDK and hosted MCP reads also default omitted `branch` to `prod` and return the selected `branch`. Annotation **writes** keep the current/explicit Branch and its existing permissions; the read default does not grant permission to write to `prod`.
19
33
 
@@ -90,7 +90,7 @@ Write the locale into a route's path with the reserved `:locale` segment, never
90
90
  | `/:locale/blog/:slug` | `{ "type": "locale", "optional": false }` | `/en/blog/hello` and `/fr/blog/bonjour` |
91
91
  | `/:locale/pricing` | omitted | `/pricing` for `en`, `/fr/pricing` for `fr` |
92
92
 
93
- - `locale` is reserved. It is read from the URL, so it never takes `schema` or `queryField` and never becomes a CMS query. Every other param is content-backed and needs both.
93
+ - `locale` is reserved. It is read from the URL, so it never takes `schema` or `queryField` and never becomes a CMS query. Every other param is an `entry` param that needs both, unless it declares `"type": "external"`: an external param takes no other keys, and the application owns its values.
94
94
  - `optional: true` means omit the configured default locale from the URL. With `i18n.defaultLocale: "en"`, `/pricing` is English and `/fr/pricing` is French.
95
95
  - `optional: false` prefixes every locale, including the default (`/en/pricing` and `/fr/pricing`). Changing `i18n.defaultLocale` chooses the fallback locale; it does not by itself change this prefix policy.
96
96
  - A route with no `:locale` segment stays application-owned. Studio shows it once and neither adds nor interprets a locale segment.
@@ -102,7 +102,7 @@ Register the same shape in the router. React Router spells the omittable segment
102
102
  route(':locale?/blog/:slug', './pages/BlogPost.tsx');
103
103
  ```
104
104
 
105
- These canonical entries are also the optional metadata used by Studio Pages. See `references/pages.md` for content-backed `params` and declared `sources`.
105
+ These canonical entries are also the optional metadata used by Studio Pages. See `references/pages.md` for the three `params` types and declared `sources`.
106
106
 
107
107
  For every framework, the application owns its URL scheme, resolves the locale, and passes it into Fimo. Studio stores the locale the app reports for the current location — including when only the locale changed — and reads content in it. Route metadata is optional unless the project wants Fimo Studio route selection/navigation.
108
108
 
@@ -7,15 +7,27 @@ Pages can mirror the application's routes in Fimo Studio. It gives editors a rou
7
7
  A route has three separate parts:
8
8
 
9
9
  - `path` is the URL pattern, such as `/blog/:slug`.
10
- - `params` optionally binds path placeholders to Collection entries so Studio can select a concrete route in the page header.
10
+ - `params` optionally describes each path placeholder: an entry bound to a Collection so Studio can select a concrete route in the page header, the reserved `locale` segment, or a value the application owns.
11
11
  - `sources` optionally names the Labels, Single, and Collection results editors manage after selecting a route.
12
12
 
13
- Each param key matches a `:placeholder` in `path`. `schema` selects the Collection, `queryField` is the entry field stored in the URL, and `displayField` is the field Studio shows to editors. Use `id` or the built-in `slug` for `queryField`; a custom URL field must set both `"required": true` and `"unique": true` in its schema. Params resolve in path order, so a later param query may use an earlier selection:
13
+ Each param key matches a `:placeholder` in `path`. For an entry param, `schema` selects the Collection, `queryField` is the entry field stored in the URL, and `displayField` is the field Studio shows to editors. Use `id` or the built-in `slug` for `queryField`; a custom URL field must set both `"required": true` and `"unique": true` in its schema. Params resolve in path order, so a later param query may use an earlier selection:
14
14
 
15
15
  ```bash
16
16
  fimo pages set <id> --path '/shop/:category/:product' --params '{"category":{"schema":"Category","queryField":"slug","displayField":"name"},"product":{"schema":"Product","queryField":"slug","displayField":"name","query":{"where":{"category":"$params.category.id"},"sort":"name"}}}'
17
17
  ```
18
18
 
19
+ A descriptor's `type` is optional and selects one of three param kinds:
20
+
21
+ - `entry` (the default) binds the placeholder to a Collection with `schema`, `queryField`, `displayField`, and an optional `query`.
22
+ - `locale` is the reserved `:locale` segment with an optional `optional` boolean. See `references/locales.md`.
23
+ - `external` takes no other keys. The application owns the values: Fimo matches the segment from the URL and never looks it up in the CMS.
24
+
25
+ ```bash
26
+ fimo pages set <id> --path '/cartes/:slug' --params '{"slug":{"type":"external"}}'
27
+ ```
28
+
29
+ Declare a placeholder `external` when its values are not Fimo content — a catalogue synced from an upstream source and stored as a media asset, ids that exist only in the visitor's browser, computed archive or pagination segments, third-party ids. Never bind a placeholder to an unrelated Collection to make `fimo validate` pass. `fimo pages list` reports `dynamic:external` and `fimo pages list --expand` skips the route; `fimo/paths` and the generated sitemap emit nothing for it, so the application enumerates those URLs itself. A `$params.<name>.<field>` expression in a param query or a source may reference entry params only. A route may mix kinds: entry params keep their selectors in Studio, and an external param takes a typed value in the preview header.
30
+
19
31
  `sources` is a named object under `routes.<id>.sources`. It is not an array or a route definition. Keep its keys stable and descriptive:
20
32
 
21
33
  ```json
@@ -76,6 +76,14 @@ Each reference defines one package contract. Fetch it when the task reaches that
76
76
  - Framework detection, production routing, and hosting adapters → `references/frameworks/hosting.md`
77
77
  - Major visual work → `references/design.md`
78
78
 
79
+ ## Analytics
80
+
81
+ For pageview installation, read [references/analytics.md](references/analytics.md).
82
+ `FimoProviders` from `fimo-react-router` already tracks when `VITE_API_URL` and
83
+ `VITE_ENABLE_ANALYTICS=true` are configured. Inspect the installed version and
84
+ browser requests before adding a sender. Hosting or the neutral Vite plugin alone
85
+ does not install a tracker. Older releases do not acquire new package exports.
86
+
79
87
  ## Non-negotiable boundaries
80
88
 
81
89
  - Do not hardcode editor-owned collections, page content, labels, or media in JSX.
@@ -0,0 +1,104 @@
1
+ # Pageview tracking
2
+
3
+ First inspect the installed package and the built page. React Router's
4
+ `FimoProviders` already tracks when `VITE_API_URL` and
5
+ `VITE_ENABLE_ANALYTICS=true` are present. Do not mount another sender beside an
6
+ unmodified legacy tracker. The neutral Vite plugin and hosting alone do not
7
+ install tracking.
8
+
9
+ ## Standalone setup
10
+
11
+ Install a released version of `fimo-analytics` that exposes the adapter you need.
12
+ Keep any version/channel selector the user already chose. An older `fimo`
13
+ release does not imply these standalone APIs exist, and existing published
14
+ sites need a code update to gain missing instrumentation.
15
+
16
+ ```sh
17
+ pnpm add fimo-analytics
18
+ ```
19
+
20
+ Obtain the tenant API base URL from the project's configured Fimo connection,
21
+ and append `/e/p`. Pass that complete URL as `endpoint`. Never infer it from the
22
+ site's public URL, guess a project hostname, or invent a discovery command. If
23
+ the connection does not supply a tenant endpoint, obtain it before enabling
24
+ tracking. A configured origin-relative proxy is also accepted.
25
+
26
+ | Framework | Import | Placement |
27
+ | -------------- | --------------------------------------------------- | -------------------------------------------- |
28
+ | React | `{ Analytics }` from `fimo-analytics/react` | Application root |
29
+ | React Router | `{ Analytics }` from `fimo-analytics/react-router` | Inside root router |
30
+ | Next App/Pages | `{ Analytics }` from `fimo-analytics/next` | Root layout or `_app` |
31
+ | Astro | default `Analytics` from `fimo-analytics/astro` | Shared layout, no `client:*` |
32
+ | Svelte | default `Analytics` from `fimo-analytics/svelte` | Root component |
33
+ | SvelteKit | default `Analytics` from `fimo-analytics/sveltekit` | Root `+layout.svelte` |
34
+ | Vue | `{ Analytics }` from `fimo-analytics/vue` | Root component, history routing |
35
+ | Nuxt | `modules: ['fimo-analytics/nuxt']` | `analytics: { endpoint, enabled }` in config |
36
+
37
+ Components accept `endpoint` and `enabled`. React example:
38
+
39
+ ```tsx
40
+ import { Analytics } from 'fimo-analytics/next';
41
+ <Analytics endpoint={endpoint} enabled={isProduction} />;
42
+ ```
43
+
44
+ For Nuxt, also install the optional build peer with `pnpm add -D @nuxt/kit`.
45
+ Next owns its client and Suspense boundaries. SvelteKit uses committed
46
+ navigation; Nuxt covers reused pages and query changes. Generic React, Vue and
47
+ Svelte observe history. For a router that changes the URL before committing,
48
+ use the manual core. For Vue Router, initialize in `onMounted` after initial
49
+ router readiness, send once, subscribe to `router.afterEach`, send only when
50
+ `failure` is falsy, and remove the subscription and destroy on unmount.
51
+
52
+ ```ts
53
+ import { init } from 'fimo-analytics';
54
+ const analytics = init({ endpoint, enabled: isProduction, routing: 'manual' });
55
+ // In the router's successful-navigation callback:
56
+ analytics.pageview();
57
+ // During cleanup:
58
+ analytics.destroy();
59
+ ```
60
+
61
+ Vanilla apps can omit `routing` to track the initial page and browser history.
62
+ Hash routers can pass `{ path: resolvedVirtualPath, pageName }` to `pageview`;
63
+ the React Router adapter already reads its router's virtual location.
64
+
65
+ For plain HTML, copy the installed `dist/browser.js` into static assets:
66
+
67
+ ```html
68
+ <script defer src="/fimo-analytics.js" data-endpoint="https://YOUR-TENANT-API-HOST/e/p" data-enabled="true"></script>
69
+ ```
70
+
71
+ Use a classic script, not `type="module"`. Set `data-enabled="false"` in preview
72
+ builds. No framework peer is required for core or HTML. Framework peers are
73
+ optional and only the chosen adapter's framework is needed.
74
+
75
+ ## Choose the enabled guard
76
+
77
+ Tracking defaults to enabled, so always pass `enabled`. Never use `NODE_ENV`:
78
+ a Fimo hosted preview is a production build, so that guard leaves previews
79
+ reporting. Read the build variable Fimo already sets:
80
+
81
+ | Framework | Guard |
82
+ | ------------------------- | -------------------------------------------------- |
83
+ | React Router and any Vite | `import.meta.env.VITE_ENABLE_ANALYTICS === 'true'` |
84
+ | Next.js | `process.env.NEXT_PUBLIC_FIMO_ENV === 'prod'` |
85
+ | Build-time server env | `process.env.FIMO_ENV === 'prod'` |
86
+
87
+ Astro, SvelteKit, Svelte and Vue have no browser-visible environment name from
88
+ Fimo. Read `FIMO_ENV` at build time and pass the boolean into the bundle through
89
+ the framework's own public-variable mechanism. Do not invent a `PUBLIC_FIMO_ENV`
90
+ and do not expose the whole environment name when a boolean is enough.
91
+
92
+ ## Verify the installed integration
93
+
94
+ Standalone tracking defaults to enabled. Supply an explicit production guard;
95
+ `bl_preview_token` also suppresses sends. SSR and disabled calls are inert.
96
+ Do not add browser secrets, project IDs or branch claims to payloads.
97
+
98
+ Verify one initial POST, navigation, query-only changes, back/forward and a
99
+ route revisit. Check duplicate mounts and cleanup. Existing visitor/session
100
+ storage keys are retained; blocked storage uses per-document IDs. Delivery is
101
+ best effort and has no retries. A 202 response alone does not prove persistence;
102
+ check recorded analytics separately. Framework peer ranges are not proof that
103
+ every older framework release was tested. Use the installed package's version
104
+ qualification and preserve existing supported integrations when upgrading.
@@ -170,6 +170,8 @@ The new-project shell pairs unprefixed default-locale pages with a parallel `[lo
170
170
  }
171
171
  ```
172
172
 
173
+ A dynamic segment whose values are not Fimo content takes `{ "type": "external" }` instead of a Collection binding; Fimo matches it from the URL, and the page's own `getStaticPaths` (or on-demand rendering) supplies those values.
174
+
173
175
  ## Client islands
174
176
 
175
177
  Generated content reads remain server-only. Preserve existing islands and do not add React or a client SDK to work around this boundary.
@@ -33,6 +33,7 @@ Read the relevant reference file when the user's question matches a topic.
33
33
  | ------------------------ | --------------------------------------- | ----------------------------------------------------- |
34
34
  | Command Palette | references/command-palette.md | "What can I open with Cmd+K?", "Quick actions" |
35
35
  | Publish & Deploy | references/publish-and-deploy.md | "How do I publish?", "How do I make my site live?" |
36
+ | Analytics | references/analytics.md | "Is tracking working?", "Why are analytics empty?" |
36
37
  | Custom Domains | references/custom-domains.md | "How do I use my own domain?", "DNS setup" |
37
38
  | Content Management (CMS) | references/cms.md | "How does the CMS work?", "How do I add blog posts?" |
38
39
  | Media Library | references/media-library.md | "How do I upload images?", "Where are my files?" |
@@ -0,0 +1,28 @@
1
+ # Analytics
2
+
3
+ Open **Analytics** in the project's workspace navigation. It may be inside
4
+ **More** at narrower desktop widths. This workspace reports the published site,
5
+ regardless of the editing branch currently selected.
6
+
7
+ Publishing alone does not confirm pageview tracking. Before publication, the
8
+ page offers setup guidance without an **Open site** link.
9
+
10
+ For a published site:
11
+
12
+ - **Waiting for the first pageview** means no pageviews are stored for it.
13
+ **Open site** lets the user visit the published address. **Set up tracking**
14
+ opens the installation guide. A visit must run a configured tracker to count.
15
+ - **Pageviews received** shows the last pageview timestamp across available
16
+ history. Changing the chart's date range or device filter does not reset it.
17
+ Earlier traffic proves tracking worked then, not that a later deployment
18
+ still sends events.
19
+ - **Tracking status unavailable** means the status could not be checked.
20
+ **Check again** retries it. Do not interpret this as an uninstalled tracker.
21
+ Charts that loaded successfully remain visible.
22
+
23
+ Studio checks every 15 seconds while waiting in a visible tab. The first
24
+ pageview refreshes the charts automatically. Processing may take longer than
25
+ one check. Do not diagnose a missing tracker from zero chart counts alone.
26
+
27
+ Users need analytics viewing permission. Date ranges and grouping apply to the
28
+ charts; available history depends on the organization's analytics access.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "bundled": true,
3
3
  "bundler": "esbuild",
4
- "bundledAt": "2026-09-14T08:59:44.223Z",
5
- "cliVersion": "2.5.1",
4
+ "bundledAt": "2026-09-29T12:38:55.114Z",
5
+ "cliVersion": "2.6.0",
6
6
  "external": [
7
7
  "oxc-parser",
8
8
  "fsevents",