Server Extensibility

Description

We should allow users, or any package, to extend the server (which is a Koa server) and do things like catch a URL, like for example ads.txt and then return a string, a 301, or whatever they want. Some examples of things users will be able to do once this is released:

  • Create 301 redirects from Frontity.
  • Send different headers. This could be useful for send custom Cache-Control headers for example.
  • It would enable the possibility of creating a package for ads.txt (@frontity/ads.txt) or robots.txt (@frontity/robots.txt).

Server extensibility will also allow other changes, like for example hooking into ReactDOM’s render or changing the HTML template.

Examples

It will work with a different export, probably server . Something like this:

// The normal package export.
export default {
  roots...
  state...
  actions...
}

// The server middleware export.
export const server = ({ app }) => {
  app.use(ctx => {
    // Add some headers...
    ctx.set({
       SomeHeader: "Value of the header",
       OtherHeader: "Value of the header"
    });
  })
  
  // Create custom routes....
  app.use(route('/custom-route', ctx => {
    ctx.body = 'Some body content';
  }));
}

@luisherranz Could you take a look at this Feature Discussion whenever you have time please? Feel free to add any information missing or correct anything that isn’t correct :slightly_smiling_face:

Sure, I’ll do :slight_smile:

@orballo suggested it’d be great to be able to capture SSR errors to display a more beautiful error, including the logo and a custom message.

I guess we can make sure that you can wrap the function that does the SSR with a middleware like:

app.use(({ ctx, next }) => {
  const oldRender = ctx.libraries.frontity.render;
  ctx.libraries.frontity.render = (...args) => {
    try {
      return oldRender(...args);
    } catch (error) {
      // Return my pretty HTML.
    }
  };
  next();
});