Files
cloudflare__vinext/tests/streaming-metadata.test.ts
T
Nathan Nguyen 4b6b438b94 fix(app-router): stream generated metadata for non-html bots (#1585)
* fix(app-router): stream generated metadata for non-html bots

Dynamic App Router metadata was always folded into the route head. That diverged from Next.js for normal browser-like requests, where generated metadata is sent through a body outlet while html-limited bots still receive blocking head metadata.

Track whether the matched route uses generateMetadata, thread next.config htmlLimitedBots into the generated RSC entry, and choose head versus body placement at page element construction.

* test(app-router): cover streaming metadata bot edge cases

Generated metadata must keep the default html-limited bot list when serialized config contains a falsy regex source. Empty config strings previously produced an empty regex, which treated every user agent as blocking and moved generated metadata back into the head.

Add regression coverage for the default Twitterbot path and the streaming body serializer, then match Next.js by falling back to the default bot regex for any falsy htmlLimitedBots value.

* fix(app-router): validate html-limited bot regex config

Invalid serialized htmlLimitedBots values could reach request handling and throw while building the bot matcher. That puts a config error on the request path and recompiles the same matcher for repeated requests.

Validate serialized regex sources while resolving next.config and reuse compiled bot matchers in the streaming metadata helper. The focused tests cover invalid config, falsy fallback, and matcher reuse.

* refactor(config): narrow next config option reads

Config resolution had several local assertions around experimental options, Turbopack aliases, output mode, and Sass options. Those assertions made the boundary wider than necessary in the code adjacent to htmlLimitedBots handling.

Read optional records, strings, arrays, and body-size inputs through typed narrowing helpers so the resolved config path keeps the same semantics without spreading unchecked asserted values.

* fix(config): keep bot regex helper out of server graph

Config resolution imported the streaming metadata server module to validate htmlLimitedBots. In RSC-backed App Router integration tests, that cross-layer import can pull server runtime modules through config resolution and surface rsc reference-validation errors.

Move the shared html-limited bot matcher cache to a neutral utils module and import it from config and the server streaming metadata helper. This keeps config validation independent from the server runtime graph while preserving the cached matcher behavior.
2026-05-26 12:07:07 +01:00

15 lines
694 B
TypeScript

import { describe, expect, it } from "vite-plus/test";
import { shouldServeStreamingMetadata } from "../packages/vinext/src/server/streaming-metadata.js";
import { getHtmlLimitedBotRegex } from "../packages/vinext/src/utils/html-limited-bots.js";
describe("streaming metadata bot matching", () => {
it("reuses compiled html-limited bot regexes by source", () => {
expect(getHtmlLimitedBotRegex("Minibot")).toBe(getHtmlLimitedBotRegex("Minibot"));
});
it("falls back to the default bot list for falsy config sources", () => {
expect(shouldServeStreamingMetadata("Twitterbot", "")).toBe(false);
expect(shouldServeStreamingMetadata("HeadlessChrome", "")).toBe(true);
});
});