XSLT Polyfill: the Extension, the One-Line Fix and Edge's Later Date
Table of Contents
The red “This site uses XSLT” banner ends with a suggestion: “You might be able to install a browser extension”. The extension is XSLT Polyfill: libxslt compiled to WebAssembly, running in your browser after Chrome removes its own copy. If you run the site, the same polyfill is one <script> line in your XML. I tested that line on a styled sitemap and an RSS feed in Chrome with XSLT turned off, and both rendered exactly as before, with no banner. One more thing the searches are asking about: Microsoft Edge does not remove XSLT with Chrome. It does it one release later, in Edge 159, in the week of 10 December 2026.
This is the follow-up to Chrome removes XSLT: what breaks, which covers the full timeline, what the banner means and the CFDI invoice code that actually breaks. This post is only about the fixes the banner points to.
Which fix is yours
| You are | What you see | Fix |
|---|---|---|
| A visitor in Chrome | The red banner on someone else’s page | Nothing until 17 November. After that, the XSLT Polyfill extension, or ask the site owner |
| A visitor in Edge | The same banner | The same extension, installed from the Chrome Web Store. Your deadline is December |
| IT for a company app you cannot change | The banner on an intranet, a device panel or a vendor app | The XSLTEnabled policy, in Chrome and in Edge, until August 2027 |
| The owner of a styled sitemap or feed | The banner on your own .xml | The one-line polyfill, or drop the stylesheet |
The owner of JavaScript that calls XSLTProcessor | Console warnings, and ReferenceError from Chrome 158 | Load the polyfill before your code, or move the transform to the server |
The dates, Chrome and Edge
Chrome dates come from Chromium Dash and Chrome’s announcement. Edge dates come from the Edge release schedule and Microsoft 365 message MC1509789, published 15 October 2026. All checked on 23 October.
| Milestone | Chrome | Edge |
|---|---|---|
| Red banner on XSLT pages | Chrome 154, 22 Sep 2026 | Already showing (Edge 154 shipped 24 Sep) |
| Beta of the removing version | Chrome 158, 28 Oct | Edge 159, week of 17 Nov |
| XSLT off in Stable | Chrome 158, 17 Nov 2026 | Edge 159, week of 10 Dec 2026 |
| Enterprise policy and Origin Trial end | Chrome 176, 17 Aug 2027 | Edge 176, “Summer 2027” |
Microsoft’s wording is that in Edge 159 browser-native XSLT “will be off by default in Stable”, and it lists the reason as reducing attack surface. Edge 158 ships in the week of 19 November with XSLT still on. That is about three extra weeks for Edge users, nothing more: every Edge user who sees the banner today will lose XSLT before the year ends.
If you are a visitor: the XSLT Polyfill extension
The banner’s “install a browser extension” link opens a Chrome Web Store search for “XSLT Polyfill”. The result Chrome’s own announcement links to is this one. On 23 October the listing showed:
- Version 1.0.25, updated 20 October 2026, 514 KiB.
- 100,000 users, 4.2 stars from 10 ratings.
- A contact address that matches the polyfill’s author (
mfreed7on GitHub and npm). - A statement that it collects no user data and that all processing happens locally.
What it does, per its description: when a page is raw XML with an XSLT processing instruction, it runs the stylesheet with the polyfill so the page renders as before. It also provides a polyfilled XSLTProcessor, so JavaScript that used XSLT keeps working. On pages without XSLT, or in a browser that still has native XSLT, it does nothing. That last point means installing it today changes nothing you can see. It starts working the day your browser drops XSLT.
Before you install it, the usual rule for extensions applies: an extension that rewrites pages needs broad access to them. Check the permissions Chrome shows you, and prefer the listing Chrome’s announcement links to over lookalikes in the same search.
Firefox still has XSLT and has no removal date, so you do not need anything there today. There is a separate add-on with the same name on addons.mozilla.org, by a different author (zcorpan).
Edge: the same banner, one release later
Edge is built on Chromium, so it inherited the banner. In September an Edge user asked on Microsoft Q&A why their Remote Desktop web portal showed “This site uses XSLT…”. The answer was the same as for Chrome: the site owner has to fix it, and the policy only buys time.
There is no XSLT Polyfill listing on Edge Add-ons (I searched on 23 October). Edge can install Chrome Web Store extensions, though: open the listing in Edge, accept the “Allow extensions from other stores” prompt, then add it from the listing’s button.
For IT. Edge has its own XSLTEnabled policy, documented on Microsoft Learn for Edge 147 and later on Windows and macOS (not Android or iOS). Enabled, it keeps XSLT available whatever the browser’s default is. Microsoft plans to remove it in Edge 176:
Group Policy: Administrative Templates > Microsoft Edge > Control the availability of the XSLT feature
Registry: HKLM\SOFTWARE\Policies\Microsoft\Edge XSLTEnabled REG_DWORD 0x00000001
macOS: XSLTEnabled = <true/>
Microsoft’s checklist for admins is worth copying even if you only use Chrome: run Lighthouse in Navigation mode with the Best Practices category on each internal app (turn off “Clear storage” for apps behind a login), then look for XSLT deprecation warnings in the report, the Issues panel and the console.
If you own the site: the one-line polyfill
The same polyfill the extension uses can live in your XML, so visitors do not need any extension. It is on npm as xslt-polyfill (1.0.33 on 21 October 2026, BSD-3-Clause). The README’s instructions: add a <script> element in the XHTML namespace as a child of the root element, before the content.
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/sitemap.xsl"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<script src="/xslt-polyfill.min.js" xmlns="http://www.w3.org/1999/xhtml"></script>
<url><loc>https://example.com/a/</loc></url>
<url><loc>https://example.com/b/</loc></url>
</urlset>
What I tested
I served a sitemap with a small XSL stylesheet (an <h1> and a table of links) from a local server. Then I loaded it in Chrome 155 with --enable-features=XSLT and with --disable-features=XSLT, which is how Chrome 158 behaves, and dumped the DOM of each result:
| Sitemap | XSLT on (today) | XSLT off (Chrome 158) |
|---|---|---|
| Stylesheet only | Table rendered, with the red banner | Chrome’s raw XML viewer |
| Stylesheet + polyfill line | Table rendered, no banner | Table rendered, no banner: same <h1>, same 2 rows |
Three details came out of it:
- The line also removes the banner today. While native XSLT exists, the polyfill does not install itself. Chromium also takes a script in that position as a sign that the polyfill is deployed, and skips the banner (Chrome 155 and later). So the same line fixes November and makes the warning go away now.
- It does not have to be the root’s direct child. In an RSS feed I put it inside
<channel>, one level down, and the result was the same in both modes. - It works from a CDN. Pointing
srcathttps://cdn.jsdelivr.net/npm/xslt-polyfill@1.0.33/xslt-polyfill.min.jsalso rendered. Self-host it if you prefer not to depend on a third party. Either way, pin the version.
The cost is weight: xslt-polyfill.min.js is 1.46 MB, with the WebAssembly inside. Only people who open your sitemap or feed in a browser download it, and it is cached after that.
In Astro
@astrojs/rss takes raw XML in customData and puts it inside <channel>. I checked that with version 4.0.19. It writes the element self-closed (<script ... />), which is fine in XML, and I confirmed that form loads the polyfill too:
// src/pages/rss.xml.js
import rss from '@astrojs/rss';
export async function GET(context) {
return rss({
title: 'My blog',
description: '…',
site: context.site,
stylesheet: '/rss.xsl',
customData:
'<script src="/xslt-polyfill.min.js" xmlns="http://www.w3.org/1999/xhtml"></script>',
items: [],
});
}
Copy node_modules/xslt-polyfill/xslt-polyfill.min.js to public/, or use the CDN URL. @astrojs/sitemap has no option to inject an element. If you set xslURL there, the simple paths are dropping it or post-processing the generated file.
In WordPress
Core, Yoast and Rank Math give you filters to change or remove the stylesheet URL, but no clean hook to add an element inside <urlset>. Until WordPress ships its own fix (ticket #65593, milestone 7.2), the practical choice is the one in the previous post: drop the stylesheet, or serve an HTML version separately.
For JavaScript that calls XSLTProcessor
Load the polyfill as an ordinary script before your code. new XSLTProcessor(), importStylesheet() and transformToFragment() keep working once the browser has no native version. To exercise it in today’s Chrome, set window.xsltUsePolyfillAlways = true before the script loads.
The limits
- XSLT 1.0 only. The README describes it as a polyfill for XSLT 1.0, “roughly as shipped in the Chrome browser”, and points to SaxonJS for anything more.
xsl:include,xsl:importanddocument()are loaded withfetch(). That means CORS applies, where the native processor ignored it. A stylesheet that includes files from another domain will fail. Sincefetch()is asynchronous andXSLTProcessor’s methods are synchronous, those methods fail when the stylesheet has includes. For a simple sitemap stylesheet on your own domain, this does not come up. For complex ones (such as the SAT’s CFDI stylesheet, with 33 includes), flatten them into one file first. The previous post shows that case checked against a real seal.- Crawlers. I found no statement from Google about a
<script>inside a sitemap. What I can check is the protocol’s own schema:sitemap.xsdallows elements from other namespaces at the start of<urlset>, before the first<url>. The line goes exactly there, so it fits the protocol’s structure. A strict validator may still complain, because the schema asks it to validate those elements. If nobody reads your sitemap in a browser, removing the stylesheet is simpler than adding the polyfill.
How to check it worked
# 1. The line is in what you actually serve
curl -s https://yoursite.com/sitemap.xml | head -c 600 | grep -o '<script[^>]*xslt-polyfill[^>]*>'
# 2. It renders with XSLT off, the way Chrome 158 will
chrome --headless=new --disable-features=XSLT --virtual-time-budget=8000 \
--dump-dom https://yoursite.com/sitemap.xml | grep -c '<tr'
# > 0 → the table is there. 0 → you are looking at the raw XML viewer
--virtual-time-budget matters: the polyfill loads asynchronously, and without it --dump-dom can capture the page before the transform. In a normal window, chrome://flags/#xslt set to Disabled gives the same result.
Frequently asked questions
What is the XSLT Polyfill extension that Chrome's banner suggests?
It is a browser extension that runs XSLT with libxslt compiled to WebAssembly, so XML pages styled with XSLT keep rendering after the browser removes its native XSLT. It also provides a polyfilled XSLTProcessor for JavaScript. It does nothing on pages without XSLT, or while the browser still supports XSLT natively. The Chrome Web Store listing Chrome's announcement links to showed version 1.0.25, 100,000 users, and a statement that processing is local and no user data is collected, as of 23 October 2026.
When does Microsoft Edge remove XSLT?
In Edge 159, whose Stable release is planned for the week of 10 December 2026, according to Microsoft's release schedule and message MC1509789. Edge 158, in the week of 19 November, still has XSLT. Chrome removes it earlier, in Chrome 158 on 17 November 2026. Edge's temporary XSLTEnabled policy is planned to be removed in Edge 176, in summer 2027.
Can I install the XSLT Polyfill extension in Edge?
There is no XSLT Polyfill listing on the Edge Add-ons store as of 23 October 2026, but Edge can install extensions from the Chrome Web Store. Open the Chrome Web Store listing in Edge, accept Allow extensions from other stores, and add it.
How do I add the XSLT polyfill to a sitemap or RSS feed?
Add a script element in the XHTML namespace near the top of the XML, as a child of the root element: <script src="/xslt-polyfill.min.js" xmlns="http://www.w3.org/1999/xhtml"></script>. I tested it in Chrome with XSLT disabled on a sitemap and on an RSS feed, with the line inside channel, and both rendered as before. The file is about 1.46 MB and is published on npm as xslt-polyfill.
Does the polyfill remove the This site uses XSLT banner?
Yes. Chromium skips the banner when the XML has an XHTML script within two levels of the root element, which it reads as the polyfill being deployed. In my test on Chrome 155 the sitemap with the polyfill line showed no banner with native XSLT on, and rendered the same table with XSLT off.
Is a script element inside a sitemap valid?
The sitemaps.org schema allows elements from other namespaces at the start of urlset, before the first url, which is where the polyfill line goes. Google has not published anything specific about it. A strict validator may complain because the schema asks for those elements to be validated. If no person reads your sitemap in a browser, removing the XSL stylesheet is simpler.
Does the XSLT polyfill support xsl:include?
It loads xsl:include, xsl:import and document() with fetch, so those requests are subject to CORS, unlike the native processor. Because fetch is asynchronous, the synchronous XSLTProcessor methods fail when the stylesheet has includes. Flatten the stylesheet into one file to avoid both problems.
Found it useful? Get the next one by email
Once a week: what breaks when you upgrade, AI for developers and what I'm building, with sources. No spam.
By subscribing you accept our privacy policy.