3

I recently decided to migrate to NextJs, but I'm having a few problems doing so. I have coded an ExpressJs API and now I want to use it as a Custom NextJs Server, as it says in the Docs, but I can't make it work

Here's my server.ts file (I'm using Typescript)

///<reference path="../@types/index.d.ts"/>

import express from "express";
import next from "next";

// Rest of the imports (I removed to make the code shorter here)

import api from "./api";

const dev = process.env.NODE_ENV !== "production";

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

const port = process.env.PORT || 3000;

require("dotenv").config();

app
  .prepare()
  .then(() => {
    const server = express();

    // All these following middlewares are imported previously
    server.use(logger("dev"));
    server.use(cors());
    server.use(compression());
    server.use(express.json());
    server.use(express.urlencoded({ extended: false }));
    server.use(cookieParser());
    server.use(NoCache);

    server.use("/api", auth.userHeader(), API); // My routes

    server.get("*", (req, res, next) => handle(req, res)); // NextJs Handle

    server.use(ErrorHandler);

    server.listen(port, () => {
      console.log(`Server Listening to port ${port}`);
    });
  })
  .catch((ex) => {
    console.error(ex.stack);
    process.exit(1);
  });

export default app;

Here's my folder structure

I made a very simple app to test it (only a link to a login page)

When I run the project with next my application [works as expected and styles are applied][2], but obviously the ExpressJs API doesn't. However, when I run the server.ts file, the API works as expected (all endpoints are functional) and I get next's compiled successfully message, but [the page comes blank][3] given to a style applied by next automatically and also no CSS is loaded into the application (I added a style to the body tag on globals.scss to set the display of it to block !important, so it would overwrite the style that makes the page not show).

Here's my _app.tsx file

import { AuthProvider } from "../context/auth";

import "../styles/globals.scss";

function MyApp({ Component, pageProps }) {
  return (
    <AuthProvider>
      <Component {...pageProps} />
    </AuthProvider>
  );
}

export default MyApp;

and you can see I import the globals.scss right at the top

Here's my _document.tsx file

import Document, { Html, Head, Main, NextScript } from "next/document";

class NextDocument extends Document {
  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default NextDocument;

Here's my next.config.js file

module.exports = {
  publicRuntimeConfig: {
    // Will be available on both server and client
    API_URL: process.env.API_URL,
  },
};

Is there anything I'm missing? I followed the documentation and a few videos I watched, but still no progress

Thanks in advance. Please let me know if you need any other information.

UPDATE

After a few tests, I realized that when I remove typescript, everything works perfectly. I still don't know how to solve it and I don't want to lose all the benefits from typescript

My tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "CommonJS",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve"
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "pages/a.js", "pages/b.js", "pages/index.js", "server.js"],
  "exclude": ["node_modules"]
}

0

1 Answer 1

9

After more tests and realizing that typescript was the problem, I changed the target on my tsconfig.json from ES5 to ES6 and now everything works as expected.

Sign up to request clarification or add additional context in comments.

2 Comments

Nice, this helped solve my issue as well :)
This worked for me. You saved me some hours!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.