Skip to main content

On this page

Plugins

Root.js supports custom plugins that can be used to modify various serving behaviors and hook into various parts of the app.

configureServer

If a plugin defines a configureServer() callback function, it can be used to modify the underlying Express.js app.

Example:

ts
// @/root.config.ts

import {defineConfig} from '@blinkk/root';
import {blogRedirectPlugin} from './plugins/blog-redirect';

export default defineConfig({
  plugins: [blogRedirectPlugin()],
});
ts
// @/plugins/blog-redirect.ts

import {NextFunction, Plugin, Request, Response} from '@blinkk/root';

/**
 * Plugin to redirect `/blog` to `https://blog.example.com`. The redirect is
 * handled via a middleware to preserve query params in the redirect.
 */
export function blogRedirectPlugin(): Plugin {
  return {
    name: 'blog-redirect',
    configureServer: (server) => {
      server.use((req: Request, res: Response, next: NextFunction) => {
        if (req.path.startsWith('/blog')) {
          redirectPreserveQueryParams(
            req,
            res,
            301,
            'https://blog.example.com/'
          );
          return;
        }
        next();
      });
    },
  };
}

function redirectPreserveQueryParams(
  req: Request,
  res: Response,
  code: number,
  redirectUrl: string
) {
  const currentQueryStr = getQueryStr(req);
  if (currentQueryStr) {
    const redirectUrlWithQuery = `${redirectUrl}?${currentQueryStr}`;
    res.redirect(code, redirectUrlWithQuery);
  } else {
    res.redirect(code, redirectUrl);
  }
}

function getQueryStr(req: Request): string {
  const qIndex = req.originalUrl.indexOf('?');
  if (qIndex === -1) {
    return '';
  }
  return req.originalUrl.slice(qIndex + 1);
}
1
2
3
4
5
6
7
8
9
10
11
12
Breakpoint: