Skip to content

fix: ignore .woff2 and modern static-asset extensions#3

Merged
marcin-prerender merged 1 commit into
prerender:mainfrom
marcin-prerender:fix/ignore-woff2-and-modern-static-assets
Jun 12, 2026
Merged

fix: ignore .woff2 and modern static-asset extensions#3
marcin-prerender merged 1 commit into
prerender:mainfrom
marcin-prerender:fix/ignore-woff2-and-modern-static-assets

Conversation

@marcin-prerender

Copy link
Copy Markdown
Contributor

The bugs

1. Missing modern static-asset extensions. The IGNORE_EXTENSIONS blocklists predate woff2. Matching is exact on the final extension, so .woff does not cover .woff2. Bot requests for .woff2/.otf/.eot/.webp/.avif assets were routed to service.prerender.io instead of being served directly.

2. proxy.ts: the extension filter was dead code — it matched NOTHING. The extraction

const extension = pathname.slice(((pathname.lastIndexOf(".") - 1) >>> 0) + 1);

already yields the extension with its leading dot (e.g. ".woff"; "" for dotless paths). The code then prefixed another dot:

const dottedExt = hasExtension ? `.${extension}` : ""; // "..woff" — double dot

"..woff" never matches any IGNORE_EXTENSIONS entry, so every bot static-asset request (.css, .js, images, fonts — all of them) was forwarded to Prerender in the proxy.ts integration.

3. middleware.js: case-sensitive comparison. The extracted extension was compared without lowercasing, so e.g. /LOGO.PNG slipped past the filter. The contract mandates case-insensitive suffix matching.

Live evidence

Verified against prerender.io itself: a Googlebot-UA request for inter-*.woff2 returns a 504 (normal UA: 200), while .css/.js correctly bypass Prerender and return 200 for both UAs.

Contract

Canonical change to the static-asset ignore list: prerender/integration-contract#1 — the contract list (case-insensitive suffix matching) now includes .woff2 .otf .eot .webp .avif .webmanifest.

Changes

  • middleware.js: added .woff2, .otf, .eot, .webp, .avif to IGNORE_EXTENSIONS; removed the duplicate .doc; extension is now lowercased before the includes check.
  • proxy.ts: added the same five extensions; removed the broken double-dot dottedExt construction — the comparison now uses the extracted extension directly (it already includes the leading dot), lowercased. Dotless paths still yield "", which never matches.

Validated middleware.js with node --check; sanity-tested the extraction (/fonts/inter-bold.WOFF2.woff2 → ignored; /about"" → proxied).

🤖 Generated with Claude Code

The IGNORE_EXTENSIONS blocklists predate woff2. Suffix matching is
exact on the final extension, so ".woff" does not cover ".woff2" —
verified live: Googlebot requesting prerender.io's own inter-*.woff2
got a 504 (normal UA: 200) while .css/.js correctly bypassed.

Adds .woff2, .otf, .eot, .webp, .avif to middleware.js and proxy.ts
per the integration contract (prerender/integration-contract#1), and
removes the duplicate ".doc" entry in middleware.js.

Also fixes two filter bugs:
- proxy.ts: the extension filter was dead code. The extracted
  extension already includes the leading dot (".woff"), but the code
  prefixed another dot ("..woff"), which never matched
  IGNORE_EXTENSIONS — so ALL bot static-asset requests were forwarded
  to Prerender. Now compares the extracted extension directly,
  lowercased.
- middleware.js: the extension was compared case-sensitively; the
  contract mandates case-insensitive suffix matching. Now lowercased
  before the includes check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@marcin-prerender marcin-prerender merged commit 690cd2d into prerender:main Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants