A while ago, Google announced that they would be removing XSLT support from Chrome, and other browser makers followed suit. That’s put us in a tight spot, because the Numbas default theme has always used XSLT to produce the displayed exam content.
On November 17th, 2026, the stable version of Chrome will disable XSLT, so any existing Numbas exam packages will stop working.
As a quick fix, I’ve added an XSLT polyfill script to the default theme, so Numbas exams downloaded from the mathcentre editor from now on will continue to work. The polyfill is a big script and takes a long time to load, so I’m also working on rewriting the theme to remove XSLT entirely. This will be a breaking change, so most custom themes will have to be updated to follow the new way of working. Once that’s done, I’ll write another post explaining what changes you need to make if you’ve written a custom theme.
For now, here’s how the removal of XSLT affects existing Numbas packages.
Exams loaded directly from numbas.mathcentre.ac.uk
If you link directly to the Numbas editor, for example using the “embed” link, you don’t need to do anything: I’ve added the polyfill to the default theme, and exams loaded directly from the editor always use the latest version of the code.
Exam packages uploaded to a Numbas LTI provider
I’ve written a script which will update all exam packages uploaded to a Numbas LTI provider.
Download xslt-polyfill.min.js and put it in /srv/numbas-lti-provider/numbas_lti/static.
Run python manage.py collectstatic --noinput.
Download add_xslt_polyfill.py and put it in /srv/numbas-lti-provider/numbas_lti/management/commands.
Run python manage.py add_xslt_polyfill. The script will edit each uploaded exam package so it loads the polyfill.
Standalone exam packages
Other exam packages not loaded from the editor or an LTI provider will have to be fixed individually, with the polyfill added to each package.
Bulk update script
I’ve written a Python script which will help if you have a large collection of packages on a server that you have terminal access to.
Download add_xslt_polyfill_standalone.py. When you run it, you can either give the URL of a copy of xslt-polyfill.min.js, if you want to have a single copy that all packages load, or the path to a copy of the file on the same machine, which will be copied into each package.
For safety, by default the script just prints the list of packages that it would update. Run the script with the --write option to actually update those packages.
Fixing individual packages
For each exam package, download xslt-polyfill.min.js and put it at the top level of the package (in the same directory as the index.html file)
Edit index.html and insert the following just before the </head> tag:
<script src="xslt-polyfill.min.js"></script>
I’m sorry about this situation – the browser makers have never removed a feature before, so this was hard to foresee. I don’t like making too many breaking changes, so didn’t remove the XSLT code when rewriting the default theme last year. This time, my hand has been forced!