@gusnips/vite 0.8.0 → 0.8.2

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
@@ -81,6 +81,14 @@ stream, which lands them inside your body when you are filling one `<div>` rathe
81
81
  a document — so those get stripped, and a render error is rethrown so a broken page fails the
82
82
  build instead of shipping.
83
83
 
84
+ The fallback is not the worst case. `renderToString` can write its own ERROR into the page: one
85
+ repo shipped a live, indexed reference page carrying React's "does not support Suspense" message,
86
+ a stack trace, and five copies of an absolute path from the machine that built it. Nothing in a
87
+ browser shows it, because the bundle replaces the body on load — so the only readers who ever saw
88
+ it were the ones who run no JavaScript, which is every crawler the page was built for. It was in
89
+ one of its two languages, too: the first render bails but resolves the `lazy()` promise, so the
90
+ next locale rendered the real component and looked perfect. `assertRendered` refuses that text now.
91
+
84
92
  End your prerender script with `process.exit(0)`. Under bun, importing this renderer leaves the
85
93
  process alive after the last file is written: `react-dom/server` exits, `react-dom/static.browser`
86
94
  does not, and `process.getActiveResourcesInfo()` shows nothing either way, so the only symptom is a
@@ -95,7 +103,13 @@ their folders — `/guides/errors` → `guides/errors.html`.
95
103
 
96
104
  Every address your app puts in a canonical or a sitemap has to answer 200 rather than redirect. On
97
105
  Cloudflare Pages that means flat files: it serves `pricing/index.html` at `/pricing/` and answers
98
- `/pricing` with a 308. A flat file answers both.
106
+ `/pricing` with a 308. A flat file answers `/pricing` with a 200 and normalizes `/pricing/` to it
107
+ with a 308 — so the form you advertise is the form that is a page, which is the whole point.
108
+
109
+ This page said "a flat file answers both" until somebody ran the `curl -I` the next paragraph asks
110
+ for: `/precos/` came back `308`, `location: /precos`. Nothing about the rule changed, but the
111
+ detail matters when you are deciding whether a slash-tolerant hydration check is fixing anything —
112
+ on a host that normalizes, the browser is redirected before your bundle runs, so it never can.
99
113
 
100
114
  Hosts differ, though. Firebase Hosting redirects `/pricing` to `/pricing/` by default, and serves
101
115
  `pricing/index.html` at `/pricing` itself once `trailingSlash` is `false`. On a host like that,
@@ -1 +1 @@
1
- {"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../src/head.ts"],"names":[],"mappings":"AAiBA,4FAA4F;AAC5F,eAAO,MAAM,UAAU,4BAA0B,CAAC;AAkFlD,uFAAuF;AACvF,MAAM,WAAW,SAAS;IACxB;yBACqB;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;2DACuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;gDAC4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IAClC;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CA+GjE;AAED,MAAM,WAAW,cAAc;IAC7B,2FAA2F;IAC3F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;uDACmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAWD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,cAAmB,GAC1B,IAAI,CA2CN"}
1
+ {"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../src/head.ts"],"names":[],"mappings":"AAiBA,4FAA4F;AAC5F,eAAO,MAAM,UAAU,4BAA0B,CAAC;AAkFlD,uFAAuF;AACvF,MAAM,WAAW,SAAS;IACxB;yBACqB;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;2DACuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;gDAC4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IAClC;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CA+GjE;AAED,MAAM,WAAW,cAAc;IAC7B,2FAA2F;IAC3F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;uDACmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,cAAmB,GAC1B,IAAI,CAyDN"}
package/dist/head.js CHANGED
@@ -208,6 +208,15 @@ export function bakeHead(template, tags) {
208
208
  * splash never is. The donor's was 1,174 bytes.
209
209
  */
210
210
  const SPLASH_MAX_GROWTH = 2000;
211
+ /**
212
+ * React's own words when `renderToString` meets a Suspense boundary it cannot render.
213
+ *
214
+ * Matched in both spellings because the quotes are escaped by the time the markup reaches a file,
215
+ * and matched as the WHOLE sentence rather than a memorable fragment of it: the page that exposed
216
+ * this was a documentation site, and "does not support Suspense" is a phrase a React guide may
217
+ * legitimately print. This one nobody writes on purpose.
218
+ */
219
+ const RENDERER_ERROR = /The server used (?:"|&quot;)renderToString(?:"|&quot;) which does not support Suspense/;
211
220
  /**
212
221
  * What every written file must be true of before the build is allowed to pass.
213
222
  *
@@ -244,6 +253,17 @@ export function assertRendered(file, html, template, checks = {}) {
244
253
  const placeholder = /%[A-Z][A-Z0-9_]{2,}%/.exec(html);
245
254
  if (placeholder)
246
255
  fail(`still carries an unsubstituted placeholder, ${placeholder[0]}`);
256
+ // `renderToString` does not only render the fallback at a boundary it cannot handle — it can
257
+ // write its own ERROR into the markup, stack trace and all, including absolute paths from the
258
+ // machine that ran the build. The eighth migration found exactly that on a live, indexed page,
259
+ // and in only ONE of its two languages: the first render bails but also resolves the `lazy()`
260
+ // promise, so the next locale in the same loop rendered the real component and looked perfect.
261
+ // Checked against the whole document and NOT gated on size, because the error text makes the
262
+ // file bigger — which is why every other check here waves it through.
263
+ if (RENDERER_ERROR.test(html))
264
+ fail("carries React's renderToString error where its page should be. The entry is still on " +
265
+ "`renderToString`, which cannot render a Suspense boundary and writes the failure into " +
266
+ "the file instead — use `renderTree` (invariant 1).");
247
267
  // What the root ACTUALLY opens with. Sliced rather than matched in one pattern, because a
248
268
  // regex that skips React's `<!--$-->` Suspense markers with `(?:<!--.*?-->|\s)*` can backtrack
249
269
  // across the whole document — it will happily skip 40 KB of real page to find a
package/dist/head.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"head.js","sourceRoot":"","sources":["../src/head.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"head.js","sourceRoot":"","sources":["../src/head.ts"],"names":[],"mappings":"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"}
package/dist/sitemap.d.ts CHANGED
@@ -5,7 +5,16 @@ import type { Alternate } from "./head.ts";
5
5
  * FLAT (`pricing.html`), not directory-style (`pricing/index.html`). Cloudflare Pages serves
6
6
  * the directory form at `/pricing/` and answers `/pricing` with a 308 to it — so every address
7
7
  * the app advertises in its canonical and its sitemap would be a redirect rather than a page.
8
- * A flat file is served at `/pricing` AND `/pricing/`, 200 either way.
8
+ * A flat file answers `/pricing` — the address the canonical and the sitemap name — with a 200,
9
+ * and normalizes `/pricing/` to it with a 308.
10
+ *
11
+ * This said "200 either way" until somebody measured it. On a live Pages deployment `/precos/`
12
+ * answers `308` with `location: /precos`, which then answers 200. The rule is untouched by that
13
+ * — the ADVERTISED form is the one that must be a page, and it is — but the parenthetical was
14
+ * inherited from a donor comment and repeated into an adopter's commit message as a live bug
15
+ * before anyone checked. It also has a consequence worth knowing: on a host that normalizes,
16
+ * `hydrateOrMount`'s slash tolerance can never fire, because the browser is redirected before it
17
+ * runs. That tolerance earns its place on hosts that serve both forms, not on this one.
9
18
  *
10
19
  * That is Cloudflare Pages, not every host. Firebase Hosting serves the directory form at
11
20
  * `/pricing` itself with `trailingSlash: false`, and an adopter there names its own files. What
@@ -1 +1 @@
1
- {"version":3,"file":"sitemap.d.ts","sourceRoot":"","sources":["../src/sitemap.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM9C;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;CAC5F;AAED;+CAC+C;AAC/C,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,0FAA0F;IAC1F,QAAQ,EAAE,MAAM,CAAC;IACjB;iEAC6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;iFAC6E;IAC7E,UAAU,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;CACnC;AAED,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAyBnE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAYjG;AAED,MAAM,WAAW,aAAa;IAC5B;;uFAEmF;IACnF,MAAM,EAAE,MAAM,CAAC;IACf;;;;iDAI6C;IAC7C,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B;0FACsF;IACtF,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAED,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAa,EAAE,EAAE,aAAa,GAAG,MAAM,CAQpF"}
1
+ {"version":3,"file":"sitemap.d.ts","sourceRoot":"","sources":["../src/sitemap.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM9C;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;CAC5F;AAED;+CAC+C;AAC/C,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,0FAA0F;IAC1F,QAAQ,EAAE,MAAM,CAAC;IACjB;iEAC6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;iFAC6E;IAC7E,UAAU,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;CACnC;AAED,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAyBnE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAYjG;AAED,MAAM,WAAW,aAAa;IAC5B;;uFAEmF;IACnF,MAAM,EAAE,MAAM,CAAC;IACf;;;;iDAI6C;IAC7C,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B;0FACsF;IACtF,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAED,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAa,EAAE,EAAE,aAAa,GAAG,MAAM,CAQpF"}
package/dist/sitemap.js CHANGED
@@ -11,7 +11,16 @@ import { escapeAttr } from "./escape.js";
11
11
  * FLAT (`pricing.html`), not directory-style (`pricing/index.html`). Cloudflare Pages serves
12
12
  * the directory form at `/pricing/` and answers `/pricing` with a 308 to it — so every address
13
13
  * the app advertises in its canonical and its sitemap would be a redirect rather than a page.
14
- * A flat file is served at `/pricing` AND `/pricing/`, 200 either way.
14
+ * A flat file answers `/pricing` — the address the canonical and the sitemap name — with a 200,
15
+ * and normalizes `/pricing/` to it with a 308.
16
+ *
17
+ * This said "200 either way" until somebody measured it. On a live Pages deployment `/precos/`
18
+ * answers `308` with `location: /precos`, which then answers 200. The rule is untouched by that
19
+ * — the ADVERTISED form is the one that must be a page, and it is — but the parenthetical was
20
+ * inherited from a donor comment and repeated into an adopter's commit message as a live bug
21
+ * before anyone checked. It also has a consequence worth knowing: on a host that normalizes,
22
+ * `hydrateOrMount`'s slash tolerance can never fire, because the browser is redirected before it
23
+ * runs. That tolerance earns its place on hosts that serve both forms, not on this one.
15
24
  *
16
25
  * That is Cloudflare Pages, not every host. Firebase Hosting serves the directory form at
17
26
  * `/pricing` itself with `trailingSlash: false`, and an adopter there names its own files. What
@@ -1 +1 @@
1
- {"version":3,"file":"sitemap.js","sourceRoot":"","sources":["../src/sitemap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sitemap.js","sourceRoot":"","sources":["../src/sitemap.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gusnips/vite",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "The build-time half of a prerendered Vite SPA: head baking, sitemap, robots, the prerender driver, and a shared vite preset.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/head.test.ts CHANGED
@@ -363,6 +363,30 @@ describe("assertRendered", () => {
363
363
  expect(() => assertRendered("pricing.html", page(link), shell)).not.toThrow();
364
364
  });
365
365
 
366
+ // The eighth migration's finding, in the exact shape it shipped: `renderToString` writing its
367
+ // own failure into a live, indexed page — quotes already escaped, the build machine's absolute
368
+ // paths in the trace. Every other check here passes it, because the error text makes the file
369
+ // BIGGER rather than smaller.
370
+ it("catches React's renderToString error baked into the body", () => {
371
+ const leaked =
372
+ `<div id="root"><main>The server used &quot;renderToString&quot; which does not support ` +
373
+ `Suspense. If you intended for this Suspense boundary to render the fallback content on the ` +
374
+ `server consider throwing an Error somewhere within the Suspense boundary. at Lazy ` +
375
+ `(&lt;anonymous&gt;) at RenderedRoute (/Users/someone/repo/node_modules/react-router/x.js:1:1)` +
376
+ `${"x".repeat(400)}</main></div>`;
377
+ expect(() => assertRendered("api.html", page(leaked), shell)).toThrow(/renderToString error/);
378
+ });
379
+
380
+ // The page that exposed this was a DOCUMENTATION site, which is why the pattern is React's whole
381
+ // sentence and not a memorable fragment of it: a guide is allowed to write about Suspense, and
382
+ // failing its build for saying the words would be a worse bug than the one being caught.
383
+ it("does not flag a guide that writes about Suspense", () => {
384
+ const guide =
385
+ `<div id="root"><main><p>renderToString does not support Suspense, which is why this build ` +
386
+ `uses renderTree instead.</p>${"x".repeat(800)}</main></div>`;
387
+ expect(() => assertRendered("guides/ssr.html", page(guide), shell)).not.toThrow();
388
+ });
389
+
366
390
  it("catches a file that is not marked as the language it was baked for", () => {
367
391
  const html = page(`<div id="root">${long}</div>`);
368
392
  expect(() => assertRendered("pt/pricing.html", html, shell, { lang: "pt-BR" })).toThrow(
package/src/head.ts CHANGED
@@ -314,6 +314,17 @@ export interface RenderedChecks {
314
314
  */
315
315
  const SPLASH_MAX_GROWTH = 2000;
316
316
 
317
+ /**
318
+ * React's own words when `renderToString` meets a Suspense boundary it cannot render.
319
+ *
320
+ * Matched in both spellings because the quotes are escaped by the time the markup reaches a file,
321
+ * and matched as the WHOLE sentence rather than a memorable fragment of it: the page that exposed
322
+ * this was a documentation site, and "does not support Suspense" is a phrase a React guide may
323
+ * legitimately print. This one nobody writes on purpose.
324
+ */
325
+ const RENDERER_ERROR =
326
+ /The server used (?:"|&quot;)renderToString(?:"|&quot;) which does not support Suspense/;
327
+
317
328
  /**
318
329
  * What every written file must be true of before the build is allowed to pass.
319
330
  *
@@ -355,6 +366,20 @@ export function assertRendered(
355
366
  const placeholder = /%[A-Z][A-Z0-9_]{2,}%/.exec(html);
356
367
  if (placeholder) fail(`still carries an unsubstituted placeholder, ${placeholder[0]}`);
357
368
 
369
+ // `renderToString` does not only render the fallback at a boundary it cannot handle — it can
370
+ // write its own ERROR into the markup, stack trace and all, including absolute paths from the
371
+ // machine that ran the build. The eighth migration found exactly that on a live, indexed page,
372
+ // and in only ONE of its two languages: the first render bails but also resolves the `lazy()`
373
+ // promise, so the next locale in the same loop rendered the real component and looked perfect.
374
+ // Checked against the whole document and NOT gated on size, because the error text makes the
375
+ // file bigger — which is why every other check here waves it through.
376
+ if (RENDERER_ERROR.test(html))
377
+ fail(
378
+ "carries React's renderToString error where its page should be. The entry is still on " +
379
+ "`renderToString`, which cannot render a Suspense boundary and writes the failure into " +
380
+ "the file instead — use `renderTree` (invariant 1).",
381
+ );
382
+
358
383
  // What the root ACTUALLY opens with. Sliced rather than matched in one pattern, because a
359
384
  // regex that skips React's `<!--$-->` Suspense markers with `(?:<!--.*?-->|\s)*` can backtrack
360
385
  // across the whole document — it will happily skip 40 KB of real page to find a
package/src/sitemap.ts CHANGED
@@ -15,7 +15,16 @@ import type { Alternate } from "./head.ts";
15
15
  * FLAT (`pricing.html`), not directory-style (`pricing/index.html`). Cloudflare Pages serves
16
16
  * the directory form at `/pricing/` and answers `/pricing` with a 308 to it — so every address
17
17
  * the app advertises in its canonical and its sitemap would be a redirect rather than a page.
18
- * A flat file is served at `/pricing` AND `/pricing/`, 200 either way.
18
+ * A flat file answers `/pricing` — the address the canonical and the sitemap name — with a 200,
19
+ * and normalizes `/pricing/` to it with a 308.
20
+ *
21
+ * This said "200 either way" until somebody measured it. On a live Pages deployment `/precos/`
22
+ * answers `308` with `location: /precos`, which then answers 200. The rule is untouched by that
23
+ * — the ADVERTISED form is the one that must be a page, and it is — but the parenthetical was
24
+ * inherited from a donor comment and repeated into an adopter's commit message as a live bug
25
+ * before anyone checked. It also has a consequence worth knowing: on a host that normalizes,
26
+ * `hydrateOrMount`'s slash tolerance can never fire, because the browser is redirected before it
27
+ * runs. That tolerance earns its place on hosts that serve both forms, not on this one.
19
28
  *
20
29
  * That is Cloudflare Pages, not every host. Firebase Hosting serves the directory form at
21
30
  * `/pricing` itself with `trailingSlash: false`, and an adopter there names its own files. What