Implementing localized 404 page with Firebase hosting

喜欢而已 提交于 2020-08-09 07:08:47

问题


Say my web app has two locales: English(myapp.com/en/) and French(myapp.com/fr/). I want to localize my 404 pages, so that request to myapp.com/en/non-existent or myapp.com/non-existent would return an English version of the 404 page and request to myapp.comm/fr/non-existent would return a French one.

However, it seems like Firebase Hosting does not provide such functionality by default, as it only allows a single 404 page(source)

So, is there a way of implementing a localized 404 page with Firebase Hosting?


回答1:


One way of achieving this functionality is by using rewrites:

{
  ...
  "hosting": {
    "rewrites": [
      {
        "source": "/fr/**",
        "destination": "/fr/404.html"
      },
      {
        "source": "**",
        "destination": "/en/404.html"
      }
    ]
  }

This will serve the /fr/404.html/ page for unmatched requests inside /fr/ directory and /en/404.html for any other unmatched request.

The downside of this approach is that the returned status code is 200 instead of 404.


A better solution is to rewrite unmatched requests to Cloud Functions that return the needed 404 page and the 404 status code. Note, that the 404 pages have to be located in functions/lib directory, not public.

Also, with the use of proper Cache-Control header, you can allow the Firebase Hosting to cache the output of the Functions so that they don't have to run every time a 404 page is requested.

Firebase config:

{
  ...
  "hosting": {
    "rewrites": [
      {
        "source": "/fr/**",
        "function": "pageNotFoundFr"
      },
      {
        "source": "**",
        "function": "pageNotFound"
      }
    ]
  }

The functions:

exports.pageNotFound = functions.https.onRequest((req, res) => {
    res.set("Cache-Control", "public, max-age=31536000")
    res.status(404).sendFile("en/404.html", {root: __dirname})
})

exports.pageNotFoundFr = functions.https.onRequest((req, res) => {
    res.set("Cache-Control", "public, max-age=31536000")
    res.status(404).sendFile("fr/404.html", {root: __dirname})
})

But this approach duplicates the code and can be messy in case you have more languages.


It would be better to extract the request handler into a function:

exports.pageNotFound = functions.https.onRequest(notFoundHanler("en"))
exports.pageNotFoundFr = functions.https.onRequest(notFoundHanler("fr"))

function notFoundHandler(lang) {
    return function (req, res) {
        res.set("Cache-Control", "public, max-age=31536000")
        res.status(404).sendFile(`${lang}/404.html`, {root: __dirname})
    }
}

Update: I filed a feature request for multiple 404 pages to Firebase and they replied that it will be taken into consideration.



来源:https://stackoverflow.com/questions/62177351/implementing-localized-404-page-with-firebase-hosting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!