The MFE 404 handling should be considered nascent/rudimentary as it stands today. I think there are a few things at play:
Client-side routing is assumed to exist in most MFEs, usually via a mechanism like react-router. This means that the same MFE index.html should be served at a variety of URLs. With a traditional web server, you’d use a wildcard or a partial path in your routes/URLs to serve the same HTML from all those paths, effectively delegating further routing to the client for all the paths that are potentially ‘owned’ by the frontend application. On the client side, it manages the URL without page reloads via standard browser APIs under the covers, and only hits the server’s routing again on a hard page refresh.
In the edX implementation of MFEs, we have no server to provide that wildcard route today, as we’re deploying the MFE as static files to something like S3. In edx.org’s case, we use CloudFlare’s routing to serve index.html at any path under the sub-domain for that MFE. Again - I want to just reiterate that this is fairly rudimentary and gets the job done. In my view, no one feels strongly that it
needs to be this way.
One place it does get interesting, though, are 404s and other error codes. In the case of something like the profile MFE, we don’t know whether a “/u/whoever” path is valid until after the MFE loads and has hit up an LMS API URL to try to get user data for that username. With the current setup, it’s impossible to properly return a 404 on the initial page request because we haven’t actually talked to a server yet, and the S3/CDN routing is certainly not smart enough to know whether a user exists in our system. In this case, once we’ve hit our LMS API and find out it’s a bad user name, the MFE renders a soft 404 page - with a 200 status code, unfortunately! - to indicate to the user that that user doesn’t exist. Given this “serverless” (API-only) approach, that’s the best we can do in this case.
That said, we can certainly show proper 404 pages (with proper status codes) for URLs we know are totally invalid for a given MFE… “/not/a/valid/url” in profile, for instance. Today that’d have to be configured via the storage service (i.e., S3, Cloudfront, CloudFlare, etc.) because they can intercept the request and return a status code with a custom error page - that’s the best we can do without a server in between… we’re using these storage service platforms as our ‘server’ w/r/t routes/status codes, so to speak.
Another option that we don’t do today would be to have routes in Open edX IDAs/micro-services that are responsible for serving MFEs’ index.html files. This would give us the most flexibility - server-side processing for bad routes (and possibly running some DB queries up front!), delegation to the client for everything else.
Personally, I think it’d be reasonable for us to get to the above; it’d involve a slightly stronger coupling of the MFEs to their respective backend micro-services, but I think it’d make up for that in flexibility and ease of configuration. The routing would all just be right there in the backend, rather than needing to be configured manually as part of your deployment/ops setup. Note that this also implies that MFEs would be served from paths on a given micro-service’s subdomain, instead of a separate MFe subdomain. In general, after talking with folks internally at edX and in the community, this may actually be more desirable than the current sub-domain situation. (Sub-domains could still be used by mapping a sub-domain at certain paths to an existing micro-service.) I’m curious whether there would be any use cases for folks needing to change/customize the paths for an MFE, assuming the default was something reasonable.
That’s the lay of the land, anyway. I think we should be open to making improvements here.