# CAP after browser-side XSLT

Ian Ibbotson, CTO, Alert-Hub. Prepared 4 October 2026.

Contact: ian.ibbotson@alert-hub.org. Telegram CAP community: https://t.me/CAP_community.

Rehearsal target: 25 minutes 10 seconds, including brief diagram pauses and the closing contact page. Reserve about five minutes of the 30-minute slot for questions and transitions. Timings are cues, not automatic slide advances. Read the spoken paragraphs, not the reference lines. All examples on slides are self-contained.

## 1. CAP after browser-side XSLT

**Speaking time: 0:55. Cumulative: 0:55.**

Today I want to look at a change in browser technology through the eyes of people who publish and consume CAP feeds. Chromium is removing its built-in XSLT processor. That matters to anyone whose alert documents become readable web pages through a stylesheet in the browser.

The central point is simple: CAP remains CAP. The change affects a mechanism for presenting it to people. Our job is to make that presentation responsibility explicit.

I am speaking as CTO of Alert-Hub, but the choices we will discuss are available to any CAP publisher. I will use one short example from our own aggregation work to show that the architecture is practical. You do not need our service to implement it.

Let us start by separating the browser feature from the alert standard.

Reference: https://developer.chrome.com/docs/web-platform/deprecating-xslt

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 2. What Chromium is actually removing

**Speaking time: 1:40. Cumulative: 2:35.**

There are three things on this slide, and only one is going away. CAP is an alerting standard. XML is the syntax in which CAP documents are exchanged. XSLT is a transformation language which can turn XML into another document, often HTML.

Chromium is removing the browser's built-in XSLT processing. That includes execution through an XSLT xml-stylesheet instruction and the JavaScript XSLTProcessor API. It is not removing XML support. Even the xml-stylesheet instruction remains relevant when used with CSS. CSS styling and XSLT transformation are different mechanisms.

As checked on 4 October 2026, Chrome's published plan targets Stable version 158, scheduled for 17 November 2026. Temporary origin-trial and enterprise-policy arrangements have a later end date. Treat these dates as a rollout plan to recheck, not a promise that every browser changes on one morning.

For a public warning website, asking everyone to use an extension or a managed-browser exception is a limited bridge. It does not establish a durable publishing contract.

We should therefore describe the impact carefully. A valid CAP document does not become invalid when a browser stops transforming it. A human visitor may lose the familiar formatted view. That is still an operational problem, particularly when people share alert links, but it is a presentation problem with several possible solutions.

Reference: https://developer.chrome.com/docs/web-platform/deprecating-xslt

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 3. The familiar browser transformation

**Speaking time: 1:50. Cumulative: 4:25.**

Here is the model many publishers already use. The server sends XML. Near the top, an xml-stylesheet processing instruction points to a stylesheet. The browser loads that stylesheet, applies its XSLT rules and displays the resulting human-readable document.

The sample is deliberately abbreviated. It is not a complete alert. The namespace tells us that the document uses CAP 1.2. The processing instruction tells a supporting browser how to present it. Those two responsibilities are independent.

Notice what the server actually sent. It did not send an HTML page. It sent CAP XML together with an instruction that told the browser how to construct one. A CAP consumer can parse the alert without ever running that transformation.

This is an elegant arrangement in some environments. One XML document serves a machine consumer, while a stylesheet supplies the human view. The publisher can revise the presentation without redesigning the CAP data model.

But there are additional dependencies: the stylesheet has to be reachable, the browser has to support the transformation, and browser rules must allow the required resources. Stylesheets may depend on relative paths or external assets. The readable page exists only after those steps succeed.

Keep the diagram in mind. We are about to remove a single component from it and ask what survives.

References: https://www.w3.org/TR/xml-stylesheet/ and https://docs.oasis-open.org/emergency/cap/v1.2/CAP-v1.2-os.html

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 4. One presentation mechanism disappears

**Speaking time: 1:10. Cumulative: 5:35.**

The transformer is now crossed out. The CAP XML still arrives. Its identifier, sender, message type and information blocks still mean what they meant before. A machine consumer that never depended on browser XSLT can continue reading the document.

What disappears is the automatic construction of the human page by the browser's native transformer. Depending on the browser and response handling, a visitor may see XML, a warning or a download. Do not promise that every user sees the same fallback screen.

That distinction matters when we plan the migration. We can preserve the existing machine exchange while changing how we provide the human view. We should test the machine exchange, of course, because an accidental default change can still break consumers.

The useful question is no longer simply how to restore the old browser feature. It is where we want presentation to happen, and who owns its reliability.

Reference: https://developer.chrome.com/docs/web-platform/deprecating-xslt

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 5. Where should presentation happen?

**Speaking time: 1:35. Cumulative: 7:10.**

There are several reasonable choices. A publisher might serve CAP XML only. That can be entirely appropriate for a documented machine endpoint, although it gives a person opening that URL little help.

Another publisher might provide a public HTML page and a separate CAP URL, with clear links between them. This makes the representations explicit and can fit an existing website very well.

A third might serve an HTML application which fetches CAP and renders it with JavaScript. That keeps the transformation work with the client, but the publisher now owns the application, its dependencies and its failure states. Replacing native XSLTProcessor with another call to native XSLTProcessor would not solve the removal.

Server-side rendering offers another location. It can use a normal template or run an existing XSLT stylesheet. The browser then receives HTML which it already knows how to display.

Content negotiation answers a related question: how does a client request the representation it needs? It can accompany server rendering or another rendering strategy. These are not six mutually exclusive technologies. Rendering location and representation selection are separate decisions.

I want to spend most of our time on server rendering with HTTP negotiation because it gives a coherent resource model. First, we need that model.

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 6. Resource and representation

**Speaking time: 2:05. Cumulative: 9:15.**

Consider this URL: https://alerts.example.org/alerts/12345. The examples domain is fictional. What does the URL identify? It can identify alert 12345, rather than inherently identifying an XML file.

HTTP distinguishes a resource from a representation of that resource. The resource is what we are referring to. A representation is information the server sends about it in a particular form. For this alert, CAP XML can be one representation. HTML can be another.

A machine consumer needs interoperable fields and semantics. A person needs readable language, clear instructions and context. Neither need changes the identity of the alert.

This does not mean every CAP identifier becomes a URL. CAP identification rules and the publisher's HTTP addressing policy remain distinct. Nor does it mean one CAP alert and a whole feed are the same resource. A feed may be an RSS or Atom collection whose entries lead to individual alerts.

The HTML and CAP views should derive from the same authoritative alert version. Preserve the sender, time, status, language, instructions and relevant areas. Show updates and cancellations accurately. An attractive page that loses those meanings is a poor representation.

Separate URLs remain a legitimate design. The point here is that a single resource URL can support multiple representations. Once we accept that, HTTP already provides a way for clients to express their needs.

Reference: https://www.rfc-editor.org/rfc/rfc9110.html#section-3

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 7. Three HTTP headers, two representations

**Speaking time: 2:10. Cumulative: 11:25.**

The request header Accept describes representations the client can receive. The response header Content-Type describes the representation the server actually sent. Vary tells caches which request fields influenced selection.

On the left, the consumer asks for application/cap+xml. The server returns CAP XML with that Content-Type. On the right, the browser asks for text/html, and the server returns HTML. Both responses include Vary: Accept because the request header changes the response.

Here are commands you can use after the talk: curl -i -H 'Accept: application/cap+xml' https://alerts.example.org/alerts/12345, and the equivalent with text/html. Replace that fictional host with your test service. The article contains runnable local commands.

Real browser headers contain several media ranges and sometimes quality values. A request is not generally one simple string. Use a framework's negotiation facilities rather than checking whether the header contains the letters html.

A wildcard, */*, means any media type is acceptable. It does not mean a human browser. An absent header similarly leaves room for a documented server default. A CAP endpoint with existing consumers may sensibly retain XML as that default.

If nothing offered is acceptable, a strict service can return 406 Not Acceptable. HTTP also permits a server to disregard the preference, so document the policy you choose. In our teaching examples, unsupported preferences get 406. Whichever approach you use, label the actual response accurately.

References: https://www.rfc-editor.org/rfc/rfc9110.html#section-12.5.1 and https://www.rfc-editor.org/rfc/rfc9110.html#section-12.5.5

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 8. One request reaches one rendering decision

**Speaking time: 1:40. Cumulative: 13:05.**

Let us follow the diagram slowly. Both clients request the same alert resource. The server selects a representation. For CAP, it sends the alert document. For HTML, it creates or retrieves the human page, then sends that page to the browser.

There is no browser XSLT processor in the HTML path. The page can remain understandable with JavaScript disabled. The live talk needs no network demonstration because the request and response are the demonstration.

There is one cache detail we should not omit. A cache that keys only on the URL could otherwise give HTML to a machine consumer or XML to a person. Vary: Accept describes the distinction. Verify that your CDN actually honours it or uses a correctly configured equivalent cache key. Adding the header without checking the deployed cache is insufficient.

Use validators for the selected representation. If an HTML template changes but CAP does not, its HTML ETag may need to change independently. Preserve useful existing Vary fields rather than replacing them.

Suffix URLs such as .xml and .html can provide convenient explicit links. Decide how those interact with Accept and explain it. There is no universal rule that the header must win. Our offline blog demonstration lets you compare two clearly labelled policies.

Now we can ask what to do with existing stylesheets.

Reference: https://www.rfc-editor.org/rfc/rfc9111.html#section-4.1

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 9. Existing XSLT can move to the server

**Speaking time: 1:55. Cumulative: 15:00.**

On the left, CAP plus XSLT enters the browser. On the right, the same inputs enter a server transformation step. The browser receives the resulting HTML. We have changed the execution location without changing what the CAP document means.

That makes existing stylesheet investment worth reviewing before discarding it. A stylesheet may already encode useful presentation decisions, translations or a warning authority's conventions. Reusing it can reduce migration work.

Reuse is a possibility, not a guarantee. Test the stylesheet version and processor compatibility. Resolve relative links deliberately. A stylesheet written for one browser may make assumptions about assets or document access which do not work in a server environment.

Server rendering can also use a native template or a reusable CAP rendering component. A publisher might retain an approved stylesheet for some sources and use a default renderer elsewhere. The choice is about correctness and maintenance, not loyalty to a transformation language.

There is a trust change. Fetching and executing arbitrary remote stylesheets gives the server work and capabilities that previously belonged to the user's browser. Restrict resource access, approve stylesheets and impose processing limits. A stylesheet can also emit unsafe HTML even when its XML processing is locked down.

The article covers these controls in detail. For now, keep the useful idea: preserving a stylesheet and moving execution are compatible decisions, provided we review the new boundary.

References: https://www.w3.org/TR/xslt-10/ and https://docs.oracle.com/en/java/javase/25/security/java-api-xml-processing-jaxp-security-guide.html

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 10. One implementation: an Alert-Hub reflector

**Speaking time: 2:25. Cumulative: 17:25.**

In our own aggregation work, we needed a readable view of reflected alerts while retaining machine-readable access. This is one implementation of the architecture we have just discussed.

The source is Mexico's Servicio Meteorológico Nacional feed. The upstream URL is https://smn.conagua.gob.mx/tools/PHP/feedsmn/cap.php. Its source page is https://console.alerting-apps.net/cap-aggregator/sources/mx-smn-es. The public reflector is https://ah-node-v2.api.alerting-apps.net/public/reflector/mx-smn-es. These exact links are in the article.

We checked the public endpoints on 4 October 2026. The unsuffixed feed negotiated HTML or RSS/XML. Individual reflected alerts negotiated HTML or application/cap+xml. That distinction matters: the collection is an RSS feed, not a single CAP document. Asking the feed specifically for application/cap+xml returned 406 in that check.

We also tested conflicting headers and suffixes. In the deployed implementation, .xml and .html selected fixed representations even when Accept requested the other type. On an unsuffixed resource, Accept selected the representation. That differs from an Accept-first precedence policy. Both can be designed, but we should describe the one actually running.

The local implementation includes caching and administrative approval of publisher stylesheets, server execution of approved XSLT, and bundled or template rendering when no approved publisher stylesheet is selected. The responses alone do not prove that this Mexican source used publisher XSLT during our check. A selected stylesheet failing at runtime also needs an explicit error or fallback policy. Do not assume every failure falls back automatically.

The console pages returned an access challenge to our command-line checks, so we do not claim their contents were verified. The public HTTP behaviour was directly observable.

Other publishers need not copy this implementation. The example demonstrates the resource and representation approach. Let us return to the general choices.

References: https://ah-node-v2.api.alerting-apps.net/public/reflector/mx-smn-es and sources/LIVE-CHECKS.md in the package

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 11. Choices depend on the publisher

**Speaking time: 1:50. Cumulative: 19:15.**

This comparison is deliberately not a ranking. CAP/XML only offers a simple machine contract. It needs another route to readable public information if people are expected to follow that link.

Separate HTML and CAP URLs are easy to understand and can suit a static publishing pipeline. They require discoverable links and a policy for keeping both views aligned.

Client JavaScript can support rich interaction. It also requires a maintained application, safe handling of alert text and useful loading and error states. A publisher can choose it without changing CAP, although cross-origin fetching may introduce CORS work.

Server rendering produces conventional HTML and can provide an accessible initial page without client code. The renderer still has to make that HTML accessible. Rendering on a server does not automatically guarantee accessibility or indexing.

Server XSLT preserves useful stylesheets but adds processor operations and a trust boundary. It is one way of doing server rendering.

Negotiation provides one resource with multiple representations. It adds selection and cache obligations. A small static host may prefer explicit URLs. A service that already has application routing and a CDN may find negotiation straightforward.

The most coherent choice is the one your organisation can operate reliably, while preserving consumers' CAP contract and meeting readers' needs. You can combine these approaches rather than treating the table as a menu with exactly one selection.

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 12. This is ordinary web development

**Speaking time: 1:30. Cumulative: 20:45.**

You do not need specialist CAP infrastructure to expose different representations. Mainstream frameworks already understand HTTP requests and media types.

In ASP.NET Core, controller output formatters can choose CAP or HTML for the same alert value. Configure browser Accept handling deliberately. Generic XML serialization does not automatically create a valid CAP document, so the example preserves a known CAP payload.

In Spring MVC, a controller can declare the media types it produces, with message converters writing those representations. Set an explicit default and test wildcards rather than relying on accidental converter ordering.

In PHP, Symfony's HttpFoundation component parses Accept fields including quality values and wildcards. A small handler can choose among supported representations and return a properly typed response. That is more reliable than substring matching.

The companion article includes complete small examples for all three, their run commands and a shared HTTP smoke test. They use fictional test content and local templates. They do not fetch or execute remote XSLT.

Production implementations need your real storage, authorisation where applicable, CAP validation and operational controls. The teaching examples focus on the HTTP boundary. Their job is to make the pattern easy to inspect.

References: https://learn.microsoft.com/en-us/aspnet/core/web-api/advanced/custom-formatters?view=aspnetcore-10.0, https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-config/message-converters.html and https://symfony.com/doc/current/components/http_foundation.html

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 13. A practical migration checklist

**Speaking time: 2:10. Cumulative: 22:55.**

Start with an inventory. Search generated XML for xml-stylesheet instructions, code for XSLTProcessor and public links that rely on a browser transformation. Include feed pages, individual alerts and archived documents.

Decide what a person should receive at those URLs. Then choose the representation strategy, including defaults and explicit links. Keep existing machine consumers in view. Many send */* or no meaningful preference. Switching their default to HTML can create a migration problem of your own.

Review stylesheet reuse. Test representative documents with multiple information blocks, languages, updates, cancellations and missing optional fields. Validate the CAP independently of the HTML. Preserve signed XML bytes where required. Rendering should never imply that HTML is a CAP signature or a replacement for CAP validation.

Test response types, quality values, exclusions with q=0, missing Accept and unsupported formats. Check the result through the actual CDN. Use Vary: Accept for negotiated responses and representation-appropriate validators. Decide canonical links and provide explicit CAP download or alternate links where useful.

Check accessibility with real reading order, language, contrast and keyboard use. Confirm urgency and instructions are understandable, not expressed only through colour.

For server XSLT, restrict stylesheet retrieval against SSRF, disable unneeded file and network access, bound input and output sizes and run transformations within enforceable resource limits. A timeout around a thread may not stop its CPU work. Use a worker boundary when you need a hard stop.

Finally, test in a browser with native XSLT disabled before the rollout reaches your users. You are testing your publishing architecture, including the paths that fail.

References: https://www.rfc-editor.org/rfc/rfc9110.html and https://owasp.org/www-community/attacks/Server_Side_Request_Forgery

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 14. CAP remains. Presentation becomes explicit.

**Speaking time: 1:20. Cumulative: 24:15.**

Let me finish with the three responsibilities we have separated. CAP remains the interoperable alert representation. HTML can provide the human representation. HTTP can connect clients to the representation they need.

Chromium's change removes a familiar transformation mechanism. It does not redefine the CAP standard or remove XML. Publishers now need an explicit answer to where the human presentation comes from.

For some organisations, the answer will be an HTML page at another URL. For others it will be a client application, a server template or an existing stylesheet executed on the server. Server rendering with HTTP negotiation is a particularly coherent option when you want one alert resource with both human and machine representations. It comes with ordinary responsibilities around defaults, caches and security.

If you take one action from this talk, identify a public alert URL and write down what each client should receive, including a client that sends */*. That small contract gives you something concrete to implement and test.

I will leave you with contact details and the resources for taking this further.

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.

## 15. Contact and resources

**Speaking time: 0:55. Cumulative: 25:10.**

The blog is now at blog.alert-hub.org. The companion article link on this page opens the full technical reference for this talk. You can also download the PowerPoint, PDF, rehearsal notes and framework examples directly from here. The article includes the references and both interactive demonstrations.

You can email me at ian.ibbotson@alert-hub.org. I also hang out in the Telegram CAP_community group, linked on this slide. Please join the conversation there.

Thank you. I would be interested to hear where your current presentation happens, and which constraints affect the migration you would choose.

Pause before questions. Leave this contact page visible, or return to the conclusion if the discussion needs it. The talk remains understandable offline. Contact and download links are follow-up resources.

References: https://blog.alert-hub.org/posts/cap-ecosystem/2026-10-04-cap-xslt-transition/, https://blog.alert-hub.org/presentations/cap-xslt-transition/cap-xslt-transition.pptx, https://blog.alert-hub.org/presentations/cap-xslt-transition/cap-xslt-transition.pdf, https://blog.alert-hub.org/presentations/cap-xslt-transition/script/SPEAKER-NOTES.md and https://blog.alert-hub.org/presentations/cap-xslt-transition/examples.zip.

Reference (branding): https://blog.alert-hub.org/ and https://blog.alert-hub.org/assets/alert-hub-icon-96.png. Contact/community link: https://t.me/CAP_community.
