react-cheminfo 0.48.0 → 0.50.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/README.md CHANGED
@@ -35,6 +35,7 @@ only when it drags a heavy dependency behind it.
35
35
  | `react-cheminfo/core` | every framework-free helper — 140 value exports | nothing |
36
36
  | `react-cheminfo/ui` | every React component and hook — 60 value exports | React |
37
37
  | `react-cheminfo/vite` | the prerender plugin and the OG card | nothing; React on the card |
38
+ | `react-cheminfo/pages` | the Cloudflare Pages analytics middleware | nothing |
38
39
  | `react-cheminfo/orbital` | the 3D atomic-orbital viewer | React, molstar |
39
40
  | `react-cheminfo/molecule3d` | the 3D molecule viewer and its toolbar | React, molstar |
40
41
  | `react-cheminfo/structure` | the structure editor and renderer | React, react-ocl, OCL |
@@ -1043,7 +1044,7 @@ keep in step.
1043
1044
  ```ts
1044
1045
  cheminfoPrerender({ site: 'surge', routes: PAGE_ROUTES });
1045
1046
  // origin defaults to https://surge.cheminfo.org — the site owns its host,
1046
- // the mount is '', and /exercises is written at dist/exercises/index.html.
1047
+ // the mount is '', and /exercises is written at dist/exercises.html.
1047
1048
 
1048
1049
  cheminfoPrerender({
1049
1050
  site: 'surge',
@@ -1055,7 +1056,7 @@ cheminfoPrerender({
1055
1056
  ```
1056
1057
 
1057
1058
  The **files on disk are laid out from the build's own root either way** —
1058
- `dist/exercises/index.html`, never `dist/surge/exercises/index.html`. It is the
1059
+ `dist/exercises.html`, never `dist/surge/exercises.html`. It is the
1059
1060
  server that puts them under the mount. An origin must be an absolute `http` or
1060
1061
  `https` address or it is refused: one written `localhost:3000` parses with
1061
1062
  `localhost:` as its scheme, which would read the mount back as `/3000`.
@@ -1096,6 +1097,28 @@ disk. A server writing more into the same place composes it itself, with
1096
1097
  `pageHeadTags` and `fill(page, PAGE_BODY_MARKER, noscriptIndex(…))`. All of that
1097
1098
  is `react-cheminfo/core`, so a backend loads no React and no Vite.
1098
1099
 
1100
+ ### On Cloudflare Pages
1101
+
1102
+ Pages serves the build as it is, so there is no server and no entrypoint to put
1103
+ the analytics snippet in a page. `onRequest` from `react-cheminfo/pages` adds it
1104
+ per request instead, from the project's `TRACKING_SCRIPT` variable, and returns
1105
+ everything that is not a page untouched:
1106
+
1107
+ ```ts
1108
+ // functions/_middleware.ts
1109
+ export { onRequest } from 'react-cheminfo/pages';
1110
+ ```
1111
+
1112
+ It is a door of its own so the Functions bundler reads two small files and
1113
+ never the rest of `core`, whose JSON imports an older esbuild cannot parse.
1114
+
1115
+ Keep the bundles out of the function with a `public/_routes.json`, so a page
1116
+ view costs one invocation rather than one per asset:
1117
+
1118
+ ```json
1119
+ { "version": 1, "include": ["/*"], "exclude": ["/assets/*"] }
1120
+ ```
1121
+
1099
1122
  ## Saying which build is running
1100
1123
 
1101
1124
  A report of something going wrong is worth answering only when we know what was
package/bin/check-seo.mjs CHANGED
@@ -60,10 +60,11 @@ if (stats === undefined || !stats.isDirectory()) {
60
60
  process.exit(usageError(TOOL, `no such build directory: ${root}`));
61
61
  }
62
62
 
63
+ const named = sitemapAddresses();
63
64
  const pages = [];
64
65
  collect(root, pages);
65
66
  if (pages.length === 0) {
66
- process.exit(usageError(TOOL, `no index.html under ${root}`));
67
+ process.exit(usageError(TOOL, `no HTML page under ${root}`));
67
68
  }
68
69
 
69
70
  const problems = [];
@@ -358,6 +359,11 @@ function exists(path) {
358
359
 
359
360
  /**
360
361
  * Add every built page under a path to the list, with the address it answers.
362
+ *
363
+ * A folder's `index.html` is always a page. Any other `.html` file is one only
364
+ * when the sitemap names its address, as every prerendered `<route>.html` is:
365
+ * a demo the build emits or a document copied from `public` is not a page of
366
+ * the site, and holding it to a page's head would report a correct build.
361
367
  * @param {string} path - A directory of the build.
362
368
  * @param {Array<{ file: string, address: string }>} pages - Collected so far.
363
369
  */
@@ -367,9 +373,29 @@ function collect(path, pages) {
367
373
  const next = join(path, entry.name);
368
374
  if (entry.isDirectory()) {
369
375
  collect(next, pages);
370
- } else if (entry.name === 'index.html') {
371
- const address = `/${relative(root, next).replace(/index\.html$/, '')}`;
372
- pages.push({ file: next, address: trimSlash(address) });
376
+ } else if (entry.name.endsWith('.html')) {
377
+ const page = relative(root, next).replace(/\.html$/, '');
378
+ const address = trimSlash(`/${page.replace(/(?:^|\/)index$/, '')}`);
379
+ if (entry.name === 'index.html' || named.has(address)) {
380
+ pages.push({ file: next, address });
381
+ }
373
382
  }
374
383
  }
375
384
  }
385
+
386
+ /**
387
+ * Read which addresses of this build the sitemap names.
388
+ * @returns {Set<string>} Every address of this build the sitemap names.
389
+ */
390
+ function sitemapAddresses() {
391
+ const sitemap = join(root, 'sitemap.xml');
392
+ const addresses = new Set();
393
+ if (!exists(sitemap)) return addresses;
394
+ for (const match of readFileSync(sitemap, 'utf8').matchAll(
395
+ /<loc>(?<loc>[^<]+)<\/loc>/g,
396
+ )) {
397
+ const own = ownPath(match.groups?.loc ?? '');
398
+ if (own !== undefined) addresses.add(own === '' ? '/' : own);
399
+ }
400
+ return addresses;
401
+ }
package/lib/pages.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export type { TrackingMiddlewareContext } from './seo/core/trackingMiddleware.ts';
2
+ export { trackingScriptMiddleware as onRequest } from './seo/core/trackingMiddleware.ts';
3
+ //# sourceMappingURL=pages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pages.d.ts","sourceRoot":"","sources":["../src/pages.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,EAAE,wBAAwB,IAAI,SAAS,EAAE,MAAM,kCAAkC,CAAC"}
package/lib/pages.js ADDED
@@ -0,0 +1,2 @@
1
+ export { trackingScriptMiddleware as onRequest } from "./seo/core/trackingMiddleware.js";
2
+ //# sourceMappingURL=pages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pages.js","sourceRoot":"","sources":["../src/pages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,IAAI,SAAS,EAAE,MAAM,kCAAkC,CAAC"}
@@ -113,7 +113,7 @@ export declare function homeRoute(routes: readonly RouteMeta[]): RouteMeta;
113
113
  * only the first entry describes, and one carrying a `..` segment writes its
114
114
  * file outside the build output. Two addresses that differ only in an empty
115
115
  * segment or in case are the same defect wearing a disguise: `//x` and `/x`
116
- * both write `dist/x/index.html`, and so do `/About` and `/about` on the
116
+ * both write `dist/x.html`, and so do `/About` and `/about` on the
117
117
  * case-insensitive filesystem macOS and Windows ship by default — one file, two
118
118
  * sitemap entries, and only one of the two descriptions survives. All of it is
119
119
  * author configuration read at build time, so it is refused where it is written
@@ -93,7 +93,7 @@ export function homeRoute(routes) {
93
93
  * only the first entry describes, and one carrying a `..` segment writes its
94
94
  * file outside the build output. Two addresses that differ only in an empty
95
95
  * segment or in case are the same defect wearing a disguise: `//x` and `/x`
96
- * both write `dist/x/index.html`, and so do `/About` and `/about` on the
96
+ * both write `dist/x.html`, and so do `/About` and `/about` on the
97
97
  * case-insensitive filesystem macOS and Windows ship by default — one file, two
98
98
  * sitemap entries, and only one of the two descriptions survives. All of it is
99
99
  * author configuration read at build time, so it is refused where it is written
@@ -0,0 +1,27 @@
1
+ /** What a Cloudflare Pages Function hands its middleware, as far as it is read. */
2
+ export interface TrackingMiddlewareContext {
3
+ /** The visitor's request. */
4
+ request: Request;
5
+ /** The project's variables; `TRACKING_SCRIPT` holds the analytics snippet. */
6
+ env: {
7
+ TRACKING_SCRIPT?: string;
8
+ };
9
+ /** Serve the request from the build, as Pages would without a function. */
10
+ next: () => Promise<Response>;
11
+ }
12
+ /**
13
+ * Put the analytics snippet in every page a Cloudflare Pages site serves.
14
+ *
15
+ * Pages has no server and no entrypoint to write the deployment's snippet into
16
+ * the build, so it is added per request instead, from the project's
17
+ * `TRACKING_SCRIPT` variable — the deployment owns it, never the build. With
18
+ * the variable unset, and for anything that is not a page, the response the
19
+ * build gives is returned untouched. A site wires it in
20
+ * `functions/_middleware.ts`:
21
+ *
22
+ * export { onRequest } from 'react-cheminfo/pages';
23
+ * @param context - The Pages Function context.
24
+ * @returns The response, carrying the snippet when it is an HTML page.
25
+ */
26
+ export declare function trackingScriptMiddleware(context: TrackingMiddlewareContext): Promise<Response>;
27
+ //# sourceMappingURL=trackingMiddleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trackingMiddleware.d.ts","sourceRoot":"","sources":["../../../src/seo/core/trackingMiddleware.ts"],"names":[],"mappings":"AAEA,mFAAmF;AACnF,MAAM,WAAW,yBAAyB;IACxC,6BAA6B;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,8EAA8E;IAC9E,GAAG,EAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,2EAA2E;IAC3E,IAAI,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,QAAQ,CAAC,CAmBnB"}
@@ -0,0 +1,33 @@
1
+ import { injectTrackingScript } from "./trackingScript.js";
2
+ /**
3
+ * Put the analytics snippet in every page a Cloudflare Pages site serves.
4
+ *
5
+ * Pages has no server and no entrypoint to write the deployment's snippet into
6
+ * the build, so it is added per request instead, from the project's
7
+ * `TRACKING_SCRIPT` variable — the deployment owns it, never the build. With
8
+ * the variable unset, and for anything that is not a page, the response the
9
+ * build gives is returned untouched. A site wires it in
10
+ * `functions/_middleware.ts`:
11
+ *
12
+ * export { onRequest } from 'react-cheminfo/pages';
13
+ * @param context - The Pages Function context.
14
+ * @returns The response, carrying the snippet when it is an HTML page.
15
+ */
16
+ export async function trackingScriptMiddleware(context) {
17
+ const response = await context.next();
18
+ const snippet = context.env.TRACKING_SCRIPT?.trim() ?? '';
19
+ if (snippet === '' ||
20
+ context.request.method !== 'GET' ||
21
+ response.status === 304 ||
22
+ !response.headers.get('content-type')?.includes('text/html')) {
23
+ return response;
24
+ }
25
+ const headers = new Headers(response.headers);
26
+ headers.delete('content-length');
27
+ return new Response(injectTrackingScript(await response.text(), snippet), {
28
+ status: response.status,
29
+ statusText: response.statusText,
30
+ headers,
31
+ });
32
+ }
33
+ //# sourceMappingURL=trackingMiddleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trackingMiddleware.js","sourceRoot":"","sources":["../../../src/seo/core/trackingMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAY3D;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAAkC;IAElC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IACtC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC1D,IACE,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK;QAChC,QAAQ,CAAC,MAAM,KAAK,GAAG;QACvB,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC5D,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9C,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACjC,OAAO,IAAI,QAAQ,CAAC,oBAAoB,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,EAAE;QACxE,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,OAAO;KACR,CAAC,CAAC;AACL,CAAC"}
@@ -15,6 +15,12 @@
15
15
  * Every address the tool answers is on disk, so an address that is *not* on
16
16
  * disk is genuinely not a page and must 404 rather than serving the tool under
17
17
  * a name it does not have.
18
+ *
19
+ * `/about` is written to `about.html`, never `about/index.html`: a static host
20
+ * serves a folder's index at `/about/` and redirects the address every link and
21
+ * canonical uses to it (Cloudflare Pages does, with no way to turn it off),
22
+ * while `about.html` is served at `/about` itself by Pages, static-web-server
23
+ * and `vite preview` alike.
18
24
  */
19
25
  import type { Plugin } from 'vite';
20
26
  import type { SiteId, SiteRecord } from '../../ecosystem/core/sites.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"prerender.d.ts","sourceRoot":"","sources":["../../../src/seo/vite/prerender.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,KAAK,EAAU,MAAM,EAAE,MAAM,MAAM,CAAC;AAE3C,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAExE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAI7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAMnD,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC/B,iCAAiC;IACjC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC;IAC1B;;;;;;;;;OASG;IACH,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,KAAK,SAAS,SAAS,EAAE,CAAC,CAAC;IAC9E;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,aAAa,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC;IACxD;;;;OAIG;IACH,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC1B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,QAAQ,CAAC,EACP,OAAO,GAAG,YAAY,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,GAAG,YAAY,CAAC,CAAC;IAC5E;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK,WAAW,GAAG,SAAS,CAAC;IAC5E;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CA2HnE"}
1
+ {"version":3,"file":"prerender.d.ts","sourceRoot":"","sources":["../../../src/seo/vite/prerender.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,KAAK,EAAU,MAAM,EAAE,MAAM,MAAM,CAAC;AAE3C,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAExE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAI7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAMnD,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC/B,iCAAiC;IACjC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC;IAC1B;;;;;;;;;OASG;IACH,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,KAAK,SAAS,SAAS,EAAE,CAAC,CAAC;IAC9E;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,aAAa,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC;IACxD;;;;OAIG;IACH,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC1B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,QAAQ,CAAC,EACP,OAAO,GAAG,YAAY,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,GAAG,YAAY,CAAC,CAAC;IAC5E;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK,WAAW,GAAG,SAAS,CAAC;IAC5E;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CA2HnE"}
@@ -15,6 +15,12 @@
15
15
  * Every address the tool answers is on disk, so an address that is *not* on
16
16
  * disk is genuinely not a page and must 404 rather than serving the tool under
17
17
  * a name it does not have.
18
+ *
19
+ * `/about` is written to `about.html`, never `about/index.html`: a static host
20
+ * serves a folder's index at `/about/` and redirects the address every link and
21
+ * canonical uses to it (Cloudflare Pages does, with no way to turn it off),
22
+ * while `about.html` is served at `/about` itself by Pages, static-web-server
23
+ * and `vite preview` alike.
18
24
  */
19
25
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
20
26
  import { dirname, join, resolve } from 'node:path';
@@ -105,7 +111,7 @@ export function cheminfoPrerender(options) {
105
111
  root = true;
106
112
  write(route, language, address === '/'
107
113
  ? join(out, 'index.html')
108
- : join(out, address.slice(1), 'index.html'));
114
+ : join(out, `${address.slice(1)}.html`));
109
115
  written++;
110
116
  }
111
117
  // The file a static server hands out for the mount itself. A table
@@ -1 +1 @@
1
- {"version":3,"file":"prerender.js","sourceRoot":"","sources":["../../../src/seo/vite/prerender.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prerender.js","sourceRoot":"","sources":["../../../src/seo/vite/prerender.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-cheminfo",
3
- "version": "0.48.0",
3
+ "version": "0.50.0",
4
4
  "license": "MIT",
5
5
  "description": "React components, hooks and framework-free helpers shared by the cheminfo sites: site chrome, citations, sharing, routing, pedagogy, charts, and the structure, orbital and 3D molecule viewers",
6
6
  "author": "Luc Patiny",
@@ -22,6 +22,7 @@
22
22
  "./molecule3d": "./lib/molecule3d.js",
23
23
  "./molstar/*": "./lib/molstar/*/index.js",
24
24
  "./orbital": "./lib/orbital.js",
25
+ "./pages": "./lib/pages.js",
25
26
  "./slides": "./lib/slides.js",
26
27
  "./spectra": "./lib/spectra.js",
27
28
  "./structure": "./lib/structure.js",
package/src/pages.ts ADDED
@@ -0,0 +1,2 @@
1
+ export type { TrackingMiddlewareContext } from './seo/core/trackingMiddleware.ts';
2
+ export { trackingScriptMiddleware as onRequest } from './seo/core/trackingMiddleware.ts';
@@ -156,7 +156,7 @@ export function homeRoute(routes: readonly RouteMeta[]): RouteMeta {
156
156
  * only the first entry describes, and one carrying a `..` segment writes its
157
157
  * file outside the build output. Two addresses that differ only in an empty
158
158
  * segment or in case are the same defect wearing a disguise: `//x` and `/x`
159
- * both write `dist/x/index.html`, and so do `/About` and `/about` on the
159
+ * both write `dist/x.html`, and so do `/About` and `/about` on the
160
160
  * case-insensitive filesystem macOS and Windows ship by default — one file, two
161
161
  * sitemap entries, and only one of the two descriptions survives. All of it is
162
162
  * author configuration read at build time, so it is refused where it is written
@@ -0,0 +1,48 @@
1
+ import { injectTrackingScript } from './trackingScript.ts';
2
+
3
+ /** What a Cloudflare Pages Function hands its middleware, as far as it is read. */
4
+ export interface TrackingMiddlewareContext {
5
+ /** The visitor's request. */
6
+ request: Request;
7
+ /** The project's variables; `TRACKING_SCRIPT` holds the analytics snippet. */
8
+ env: { TRACKING_SCRIPT?: string };
9
+ /** Serve the request from the build, as Pages would without a function. */
10
+ next: () => Promise<Response>;
11
+ }
12
+
13
+ /**
14
+ * Put the analytics snippet in every page a Cloudflare Pages site serves.
15
+ *
16
+ * Pages has no server and no entrypoint to write the deployment's snippet into
17
+ * the build, so it is added per request instead, from the project's
18
+ * `TRACKING_SCRIPT` variable — the deployment owns it, never the build. With
19
+ * the variable unset, and for anything that is not a page, the response the
20
+ * build gives is returned untouched. A site wires it in
21
+ * `functions/_middleware.ts`:
22
+ *
23
+ * export { onRequest } from 'react-cheminfo/pages';
24
+ * @param context - The Pages Function context.
25
+ * @returns The response, carrying the snippet when it is an HTML page.
26
+ */
27
+ export async function trackingScriptMiddleware(
28
+ context: TrackingMiddlewareContext,
29
+ ): Promise<Response> {
30
+ const response = await context.next();
31
+ const snippet = context.env.TRACKING_SCRIPT?.trim() ?? '';
32
+ if (
33
+ snippet === '' ||
34
+ context.request.method !== 'GET' ||
35
+ response.status === 304 ||
36
+ !response.headers.get('content-type')?.includes('text/html')
37
+ ) {
38
+ return response;
39
+ }
40
+
41
+ const headers = new Headers(response.headers);
42
+ headers.delete('content-length');
43
+ return new Response(injectTrackingScript(await response.text(), snippet), {
44
+ status: response.status,
45
+ statusText: response.statusText,
46
+ headers,
47
+ });
48
+ }
@@ -15,6 +15,12 @@
15
15
  * Every address the tool answers is on disk, so an address that is *not* on
16
16
  * disk is genuinely not a page and must 404 rather than serving the tool under
17
17
  * a name it does not have.
18
+ *
19
+ * `/about` is written to `about.html`, never `about/index.html`: a static host
20
+ * serves a folder's index at `/about/` and redirects the address every link and
21
+ * canonical uses to it (Cloudflare Pages does, with no way to turn it off),
22
+ * while `about.html` is served at `/about` itself by Pages, static-web-server
23
+ * and `vite preview` alike.
18
24
  */
19
25
 
20
26
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
@@ -229,7 +235,7 @@ export function cheminfoPrerender(options: PrerenderOptions): Plugin {
229
235
  language,
230
236
  address === '/'
231
237
  ? join(out, 'index.html')
232
- : join(out, address.slice(1), 'index.html'),
238
+ : join(out, `${address.slice(1)}.html`),
233
239
  );
234
240
  written++;
235
241
  }