Update the code from a template engine to Next.js

I have a .pug app and I want to convert it to a next app. My current app uses the .pug engine, but I know that Next.js is different. How can I go about converting my app to Next.js? Currently, my files are in the views folder and within the views, the files are structured in pages. Is there a way to convert it easily or do I need to rewrite the entire code?

const express = require('express');
const app = express();
const port =  process.env.PORT || 3000;
const middleware = require('./middleware')
const path = require('path')
const bodyParser = require("body-parser")
const mongoose = require("./database");
const session = require("express-session");
const http = require('http');

const server = app.listen(port, () => console.log("Server listening on port " + port));
const io = require("socket.io")(server, { pingTimeout: 60000 });

app.set("view engine", "pug");
app.set("views", "views");

app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, "public")));

app.use(session({
    secret: "#########",
    resave: true,
    saveUninitialized: false
}))

// Routes
const loginRoute = require('./routes/loginRoutes');
const registerRoute = require('./routes/registerRoutes');
const logoutRoute = require('./routes/logout');
const postRoute = require('./routes/postRoutes');
const profileRoute = require('./routes/profileRoutes');
const uploadRoute = require('./routes/uploadRoutes');
const searchRoute = require('./routes/searchRoutes');
const messagesRoute = require('./routes/messagesRoutes');
const notificationsRoute = require('./routes/notificationRoutes');

// Api routes
const postsApiRoute = require('./routes/api/posts');
const usersApiRoute = require('./routes/api/users');
const chatsApiRoute = require('./routes/api/chats');
const messagesApiRoute = require('./routes/api/messages');
const notificationsApiRoute = require('./routes/api/notifications');

app.use("/login", loginRoute);
app.use("/register", registerRoute);
app.use("/logout", logoutRoute);
app.use("/posts", middleware.requireLogin, postRoute);
app.use("/profile", middleware.requireLogin, profileRoute);
app.use("/uploads", uploadRoute);
app.use("/search", middleware.requireLogin, searchRoute);
app.use("/messages", middleware.requireLogin, messagesRoute);
app.use("/notifications", middleware.requireLogin, notificationsRoute);

app.use("/api/posts", postsApiRoute);
app.use("/api/users", usersApiRoute);
app.use("/api/chats", chatsApiRoute);
app.use("/api/messages", messagesApiRoute);
app.use("/api/notifications", notificationsApiRoute);

app.get("/", middleware.requireLogin, (req, res, next) => {

    var payload = {
        pageTitle: "Home",
        userLoggedIn: req.session.user,
        userLoggedInJs: JSON.stringify(req.session.user),
    }

    res.status(200).render("home", payload);
})

io.on("connection", socket => {

    socket.on("setup", userData => {
        socket.join(userData._id);
        socket.emit("connected");
    })

    socket.on("join room", room => socket.join(room));
    socket.on("typing", room => socket.in(room).emit("typing"));
    socket.on("stop typing", room => socket.in(room).emit("stop typing"));
    socket.on("notification received", room => socket.in(room).emit("notification received"));

    socket.on("new message", newMessage => {
        var chat = newMessage.chat;

        if(!chat.users) return console.log("Chat.users not defined");

        chat.users.forEach(user => {
            
            if(user._id == newMessage.sender._id) return;
            socket.in(user._id).emit("message received", newMessage);
        })
    });

})

Answer №1

If you're hesitant to convert all your pug template engine pages into next.js pages, there's a way for them to coexist. By setting the next.js page as the default route and positioning the next.js code after all the pug page routes, you can maintain both. You'll also need to update

app.get("/", middleware.requireLogin, (req, res, next) => {...}
so that next.js becomes the default route. To implement this method, you'll require a custom next.js server.

sample code

const express = require('express');
const next = require('next');
const port = 3000;
const dev = process.env.NODE_ENV !== 'production'; // using default NodeJS environment variable to determine development mode
const app = next({dev, conf});
const handle = app.getRequestHandler();
const server = express();


// Ensure that all your pug page routes are declared before `server.get('*'`.

server.get('*', authMiddleware(false), (req, res) => {
    // forwarding everything to NextJS
    return handle(req, res);
});

app.prepare().then(() => {
    server.listen(port, (err) => {
        if (err) throw err;
        console.log('NextJS is ready on http://localhost:' + port);
    });

}).catch(e => {
    console.error(e.stack);
    process.exit(1);

});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I retrieve information on a logged in Auth0 user from an API?

I'm currently working on a React application that utilizes auth0 in conjunction with an express API server. One issue I'm facing is how to access user information within the API when a secure endpoint is called. While I can retrieve user data on ...

How can you alter the background color of a Material UI select component when it is selected?

I am attempting to modify the background color of a select element from material ui when it is selected. To help illustrate, I have provided an image that displays how it looks when not selected and selected: Select Currently, there is a large gray backgr ...

What classification should be given to children when they consist solely of React components?

I'm encountering an issue where I need to access children's props in react using typescript. Every time I attempt to do so, I am faced with the following error message: Property 'props' does not exist on type 'string | number | boo ...

Acquire keys from a different residence

Currently, I am working on a React component that accepts data through props and I aim to implement safe property access. I have experimented with the following: type Props = { items?: any[]; // uncertain about using type "any" bindValue?: keyof Prop ...

"Using Sentry in conjunction with Next.JS to enhance application security and optimize

Is there a way to assign the error.digest as a tag to all reported errors? scope.setTag('digest', error.digest) I noticed that in the sentry.server.config.ts and Sentry.init files we can customize the beforeSend hook, but I couldn't locate ...

JavaScript: AWS Amplify: Retrieving the User ID (Sub ID) Following User Registration. Post Registration, Not to Be Confused with Sign In

Currently, I am utilizing the authentication module from AWS Amplify. One question that has been on my mind is how to obtain the userID once a user signs up. While it is possible to retrieve the ID after a user signs in, I am specifically interested in re ...

Issue with hook not updating when invoked inside useEffect

I'm encountering an issue with updating the state after fetching data from my API. The API response seems to be correct, but for some reason, my weatherData-hook is not getting updated and it returns undefined. Can anyone point out what mistake I migh ...

Encountering issues with React Nextjs - unable to utilize useState hook or

Hi everyone, I'm new to React and I think I might have overlooked something. I've been trying to create a simple registration form, but it seems like I'm having trouble changing the state. ` import {useState} from 'react' export ...

Tips for preventing unnecessary updates in a stateless component when it is nested within a parent React class-based component

While diving into React, I encountered an issue with React.memo() not working as expected. Despite using it, my component continues to re-render every time the parent class-based component is updated, even though the props remain unchanged. To investigate ...

What causes certain components in ReactJs to not respond to the `:focus` pseudo-class?

Currently, I am in the process of implementing a straightforward Emoji-Rating system where 5 emojis are displayed on the screen and upon hovering over them, their appearance changes. This functionality is achieved using the :hover pseudo-class. My goal is ...

Steps for Properly Defining Next.js getServerSideProps as a Function Declaration

I've been working on implementing getServerSideProps (additional information available here, and detailed API documentation here), but my challenge lies in utilizing it as a function declaration instead of an expression. Despite searching for relevant ...

Troubleshooting Next.js and Tailwind CSS Breakpoints: What's causing the

Having trouble with my custom breakpoints. For instance, I attempted the following: <div className="flex flex-row gap-5 mb-5 md:ml-15 sm:ml-15"> ... </div> The margin is not being applied on small and medium screens. Here are the th ...

What functionality does this method perform within React.js?

While going through the process of creating login forms, I stumbled upon this interesting method: handleChange(e) { this.setState({ [e.target.name] : e.target.value }); } I am a bit confused about the setState part in this method. The array brackets ...

Steps for automatically closing the parent dialog when the child dialog is opened in Material UI React

When utilizing Material UI React, a scenario arises where a dialog opens on button click. Once "yes" is clicked in the initial dialog, another dialog pops up on top of the first one. Is there a way to close the parent dialog before launching the child di ...

Utilizing React Sound with React Router Dom

Currently developing a website that utilizes a router to display various pages. Chose React for its user-friendly features but encountered an issue with integrating sound. The main issue arises when switching pages, causing the sound to restart instead of ...

The server has access to an environment variable that is not available on the client, despite being properly prefixed

In my project, I have a file named .env.local that contains three variables: NEXT_PUBLIC_MAGIC_PUBLISHABLE_KEY=pk_test_<get-your-own> MAGIC_SECRET_KEY=sk_test_<get-your-own> TOKEN_SECRET=some-secret These variables are printed out in the file ...

Leverage React Final Form to dynamically adjust conditions based on the values within the form

To dynamically generate a specific number of fields based on user input from the initial form step, I am utilizing a multi-step form with a "Wizard" class as the <Condition /> component does not fit my requirements. Essentially, I need to retrieve v ...

Enhancing React Functionality: Increasing React State Following an If Statement

Whenever I click on the start/stop button, it triggers the handlePlay function. This function then proceeds to initiate the playBeat function. In an ideal scenario, the play beat function should continuously display 1222122212221222... until I press the st ...

Input the date manually using the keyboard

I am currently utilizing the rc calendar package available at https://www.npmjs.com/package/rc-calendar When attempting to change the year from 2019 to 2018 by removing the "9," it works as expected. However, when trying to delete the entire date of 1/15/2 ...

Only class components can utilize ReactWrapper::state() in Unit Testing with Jest and Enzyme

Encountering an error while writing unit tests in React using Jest and Enzyme. The error message states: "ReactWrapper::state() can only be called on class components". import React from 'react'; import { mount } from 'enzyme'; import ...