petitviolet blog

    Configure custom 404 in GAE with Gatsby

    2020-05-01

    GoogleAppEngineGatsby

    tl;dr

    Use require_matching_file: true for not 404, and wildcard routing for 404 to handle the other paths.

    app.yaml
    - url: /(.*)
      static_files: public/\1
      upload: public/(.*)
      secure: always
      require_matching_file: true
    
    - url: /(.*)
      static_files: public/404.html
      upload: public/404.html
      secure: always
    

    .

    Routing in GAE

    To set routing rules in GoogleAppEngine(GAE), it needs to write app.yaml with following the format app.yaml Configuration File. This blog is a kind of a static site hosted by GAE, and powered by Gatsby.

    As you may aware of, this blog has a bunch of slugs such as:

    • /post/2020-03-28/imported-blogs-from-qiita
    • /tags/scala
    • /sw.js
    • /favicon.ico
    • etc.

    Thus, I need a way to write abstracted rules and also need a route for 404 if there is no exact matching file. In app.yaml, we can use regular expressions so that it can look like

    - url: /(.*)
      static_files: public/\1
      upload: public/(.*)
      secure: always
    
    - url: /(.*)
      static_files: public/404.html
      upload: public/404.html
      secure: always
    

    However, this doesn't work well, since the first routing handles all slugs and no request gets into the second one, unfortunately.

    How to set routing for 404

    As shown at the top of this post, we can use require_matching_file: true to add non-404 routes and set wildcard routing for 404 to handle the other slugs. The below is possibly a document about require_matching_file, although I couldn't find legit documents for StandardEnvironment for Go.

    https://cloud.google.com/appengine/docs/admin-api/reference/rpc/google.appengine.v1

    I'm pretty not sure we can rely on this, but it says

    Whether this handler should match the request if the file referenced by the handler does not exist.

    If there is no file exactly matching to a requested path, the route with require_matching_file: true will be skipped.