DEV Community

Marco
Marco

Posted on

Nextjs custom server with fastify

Image description

React server-side rendering support for Fastify with Next.js framework

In this post we will create a custom server to start an app in nextjs with fastify underneath.

Let's create a new app in nextjs with npx

npx create-next-app@latest
Enter fullscreen mode Exit fullscreen mode

Let's proceed with the installation of the dependencies

npm install fastify @fastify/static fastify-env dotenv
Enter fullscreen mode Exit fullscreen mode

First let's create an .env file at the root

PORT=6100
Enter fullscreen mode Exit fullscreen mode

On the root of the project, so to speak, next to the src folder we are going to create a new folder called server

Inside we create an index.js file
The content will look like this

require("dotenv").config();
const fastify = require("fastify")();
const fastifyStatic = require("@fastify/static");
const path = require("path");
const next = require("next");

const dev = process.env.NODE_ENV !== "production";
const host = process.env.HOST || "localhost";
const port = parseInt(process.env.PORT || "6100");

const app = next({ dev });
const handle = app.getRequestHandler();

(async () => {
  try {
    await app.prepare();

    fastify.register(fastifyStatic, {
      root: path.join(__dirname, "..", "public", "static"),
      prefix: "/static/",
    });

    fastify.all("/*", (req, reply) => {
      reply.hijack();
      handle(req.raw, reply.raw)
        .then(() => {
          reply.raw.end();
        })
        .catch((err) => {
          fastify.log.error(err);
          reply.raw.writeHead(500);
          reply.raw.end("Internal Server Error");
        });
    });

    await fastify.listen({ port, host });

    console.log(`Fastify server ready on port: ${port}`);
  } catch (err) {
    console.log(err);
    process.exit(1);
  }
})();
Enter fullscreen mode Exit fullscreen mode

This is the package.json file with the related run and build scripts

{
  "name": "nextjs_fastify",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev-next": "next dev",
    "dev": "node server/index.js",
    "prod": "cross-env NODE_ENV=production node ./server/index.js",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@fastify/static": "^7.0.4",
    "dotenv": "^16.4.5",
    "fastify": "^4.28.1",
    "fastify-env": "^2.2.0",
    "next": "^14.2.4",
    "react": "^18",
    "react-dom": "^18"
  },
  "devDependencies": {
    "@types/next": "^9.0.0",
    "@types/node": "^20.14.9",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "cross-env": "^7.0.3",
    "typescript": "^5"
  }
}
Enter fullscreen mode Exit fullscreen mode

Now all we have to do is run the desired scripts and that's it

To run the server in dev mode
npm run dev

To run the server in production mode you will first need to create the build version
npm run build

Only after the build has been completed can we launch the server in production mode with
npm run prod

And tadaan we will now have a client in nextjs with fastify under the hood 🚀

Thanks for reading

Top comments (0)